Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Plot 2 tmap objects side-by-side

Example:

I want to plot two tmap plots side by side, which are generated by this code.

library(tmap)
library(gridExtra)

data(World)

plot1=
  tm_shape(World, projection = "merc") + 
  tm_layout("", inner.margins=c(-1.72, -2.05, -0.75, -1.56)) +
  tm_borders(alpha = 0.3, lwd=2)

plot2=
  tm_shape(World, projection = "merc") + 
  tm_layout("", inner.margins=c(-1.72, -2.05, -0.75, -1.56)) +
  tm_borders(alpha = 0.3, lwd=2)

plot1 and plot2 work fine as single stand-alone plots: enter image description here

Problem:

I have problems to put both plots side-by-side. I tried:

grid.arrange(plot1, plot2) throughs an error Error in arrangeGrob(..., as.table = as.table, clip = clip, main = main, : input must be grob!. I thought that this should work (using gridExtra) as tmap seems to be based on the grid graphics system.

Also par(mfrow=c(1,2)) does not work as it shows only one plot (guess this is related as tmap plot does not follow the base graphics system).

Question:

How can I plot both objects plot1 and plot2 side-by-side (ncol=2)?

Update:

Regarding the proposed grid-based solution, I get overlapping plots instead of two column arranged plots.

enter image description here

> sessionInfo()
R version 3.1.2 (2014-10-31)
Platform: x86_64-apple-darwin13.4.0 (64-bit)

locale:
[1] de_DE.UTF-8/de_DE.UTF-8/de_DE.UTF-8/C/de_DE.UTF-8/de_DE.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] tmap_1.0    dplyr_0.4.3 sp_1.1-1   

loaded via a namespace (and not attached):
 [1] assertthat_0.1     class_7.3-11       classInt_0.1-23    colorspace_1.2-6   DBI_0.3.1          digest_0.6.8       e1071_1.6-4        ggplot2_1.0.1     
 [9] grid_3.1.2         gridBase_0.4-7     gtable_0.1.2       lattice_0.20-29    magrittr_1.5       MASS_7.3-35        munsell_0.4.2      parallel_3.1.2    
[17] plyr_1.8.3         proto_0.3-10       R6_2.1.1           raster_2.3-40      RColorBrewer_1.1-2 Rcpp_0.12.2        reshape2_1.4.1     rgdal_0.8-16      
[25] rgeos_0.3-11       scales_0.3.0       stringi_1.0-1      stringr_1.0.0      tools_3.1.2 
like image 448
user2030503 Avatar asked Dec 17 '15 21:12

user2030503


2 Answers

tmap_arrange()

https://cran.r-project.org/web/packages/tmap/tmap.pdf

data(World)
w1 <- qtm(World, projection = "eck4", title="Eckert IV")
w2 <- qtm(World, projection = "merc", title="Mercator")
w3 <- qtm(World, projection = "wintri", title="Winkel-Tripel")
w4 <- qtm(World, projection = "robin", title="Robinsin")

current.mode <- tmap_mode("plot")
tmap_arrange(w1, w2, w3, w4)
tmap_mode(current.mode)
like image 57
scottr Avatar answered Oct 20 '22 07:10

scottr


Nice question!

grid.arrange doesn't support tmap plots (yet?) in the same way it supports ggplot2 plots.

There are two options:

1) Use small multiples by assigning two values to an aesthetic (see examples from tm_facets). Your plots don't use aesthetics, but you can trick this as follows:

tm_shape(World, projection = "merc") + 
  tm_fill(col=c("white", "white")) +
  tm_layout("", inner.margins=c(-1.72, -2.05, -0.75, -1.56)) +
  tm_borders(alpha = 0.3, lwd=2)

2) Use the grid package to define viewports:

library(grid)
grid.newpage()
pushViewport(viewport(layout=grid.layout(1,2)))
print(plot1, vp=viewport(layout.pos.col = 1))
print(plot2, vp=viewport(layout.pos.col = 2))

Another thing, rather than clipping the shape with negative inner margins, you could also use the bounding box arguments inside tm_shape:

tm_shape(World, projection = "merc", xlim=c(-2e6, 6.5e6), ylim=c(-4e6, 8.5e6)) + 
  tm_borders(alpha = 0.3, lwd=2)

It produces the same map, but it the code a little cleaner.

like image 34
Martijn Tennekes Avatar answered Oct 20 '22 06:10

Martijn Tennekes