Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Producing an inset map with the tmap package in R

Tags:

r

viewport

gis

tmap

I am trying to produce an inset map of London alongside a larger map of the UK. I'm using the package "tmap" which I have found to be an excellent package and particularly easy to move to having used ggplot2 for a while. However, the documentation on how to produce an inset map using tmap is a bit unclear. The reference manual describes how it should be possible to produce an inset map using:

    save_tm(...insets_tm = NULL, insets_vp = NULL) 

but it is not clear how the second command, insets_vp, should be used. I have only found one example which actually provides suggested syntax for producing an insetmap using tmap:

    alaska <- tm_shape(shp_alaska) + … print(alaska, vp=viewport(x=.1, 
    y=.15, width=.2, height=.3)) 

See here for the source of the above code. This doesn't actually show how the map of the USA and Alaska/Hawaii are combined. As for my own attempts at coding, I have tried the following (dplyr, magrittr, rgdal, GISTools, RColorBrewer, tmap are all loaded, R vn 3.3.2, RStudio 1.0.136):

  1. I first create two tmap objects polygon and points for all of the UK (UK_Im_Sec) and London (London_Im_Sec):

    UK_Im_Sec<-tm_shape(UKNI_LA_ll, is.master = TRUE)+
    tm_borders(lwd=0.25)+
    tm_shape(Immobile_residuals)+
    tm_dots(col="Sec_Name", style="cat", palette="Set1", title="Socio-economic background (NS-SEC)")+
    tm_layout(title="Mapping outlier residuals - non-predicted 'immobility' (Social class)", title.size = 3.0,
        title.position=c("center","TOP"),legend.outside = TRUE,
        legend.outside.position = "right",frame = FALSE)
    
    LDN_Im_Sec<-tm_shape(Immobile_resids_LDN)+
    tm_dots(col="Sec_Name", style="cat", palette="Set1", size = 0.25,title="Socio-economic background (NS-SEC)")+
    tm_shape(LDN_Poly, is.master = TRUE)+
    tm_borders(lwd=0.25)+
    tm_text(text="NAME", size = 0.6, auto.placement=TRUE)+
    tm_layout("London",title.position = c("center", "BOTTOM"),legend.outside = TRUE, legend.outside.position = "right", frame =  FALSE)
    
  2. I then try to save out a pdf which combines both objects:

    save_tmap(UK_Im_Sec,insets_tm = LDN_Im_Sec,filename="ZRMdlNoRg_SEC_-3to-5SDs_ImmobResids_FINAL.pdf", dpi=600)
    

This prints the pdf but only with the map of the UK. So,

  1. I try and add insets_vp into the code:

    save_tmap(UK_Im_Sec,insets_tm = LDN_Im_Sec,insets_vp=UK_Im_Sec, filename="ZRMdlNoRg_SEC_-3to-5SDs_ImmobResids_FINAL.pdf", dpi=600)
    

But this gives the following error code:

    Error in save_tmap(UK_Im_Sec, insets_tm = LDN_Im_Sec, insets_vp = UK_Im_Sec,  : 
    Insets and/or its viewports not in the correct format
  1. I then try to combine the suggested syntax for print(x, viewport=(x=,y=,h=,w=) with insets_vp, as follows:

    save_tmap(UK_Im_Sec,insets_tm = LDN_Im_Sec,insets_vp=viewport(x=2, y=.15, width=.2, height=.3), filename="ZRMdlNoRg_SEC_-3to-5SDs_ImmobResids_FINAL.pdf", dpi=600)
    Error in inherits(insets_vp, "viewport") : 
    could not find function "viewport"
    

I know that other people have had difficulty producing inset maps in other packages and that there are questions that have already been asked and resolved for other packages, notably in ggplot (I can't link to the questions because of limits on links), but as far as I know there is nothing on this particular tmap issue.

This is my first question here so apologies for any errors in laying out the question.

like image 203
SJPG Avatar asked Feb 07 '17 09:02

SJPG


People also ask

What is an inset map?

An inset map is a smaller map inset within a larger map. Inset maps serve multiple purposes, including to: Provide an overview of the main map. Inset maps can show the location of the main map in the context of a larger area. Show more detail of a portion of the main map.

What is TMAP R?

tmap is an actively maintained open-source R-library for drawing thematic maps. The API is based on A Layered Grammar of Graphics and resembles the syntax of ggplot2 , a popular R-library for drawing charts.

What is a inset map in ArcGIS?

Utilizing an Inset Map can be an effective way of adding valuable location information to any map layout. In ArcGIS, an Inset Map is added simply by adding a new Data Frame to the map through the Insert menu. In our example, a study is being performed in the counties affected by 2005's Hurricane Rita.

What is the best way to make a map in R?

The tmap R package greatly simplifies creating good looking maps. Like in ggplot, but also similar to most GIS tools, it allows you to build up a map layer by layer. If tmap is new to you, good starting points are the Geocomputation with R online book and the tmap get started page. And you can of course google for examples.

Can we use the TMap package for theming in R?

The tmap package is an excellent choice for powerful sf-based mapping in R, but, given that our non-map charts are all produced with ggplot2, I was eager to see whether we could develop a single set of common theming (e.g. colours and fonts) and apply it to all our visuals.

Is it possible to make an inset map using TMap?

The reference manual describes how it should be possible to produce an inset map using: but it is not clear how the second command, insets_vp, should be used. I have only found one example which actually provides suggested syntax for producing an insetmap using tmap: See here for the source of the above code.

What do you like most about TMap?

Like in ggplot, but also similar to most GIS tools, it allows you to build up a map layer by layer. If tmap is new to you, good starting points are the Geocomputation with R online book and the tmap get started page. And you can of course google for examples. One of the features I like, is the ability to include inset maps, like in Figure 1.


2 Answers

You'll need to load the grid package. So, this should work

library(grid)
save_tmap(UK_Im_Sec,insets_tm = LDN_Im_Sec,insets_vp=viewport(x=2, y=.15, width=.2, height=.3), filename="ZRMdlNoRg_SEC_-3to-5SDs_ImmobResids_FINAL.pdf", dpi=600)

I'll update the US choropleth demo soon, with a save_tmap example.

like image 93
Martijn Tennekes Avatar answered Nov 06 '22 09:11

Martijn Tennekes


The last chart in the tmap demo documentation has insets of Alaska and Hawaii. Below is the code, I've just removed the fill variable:

library("readxl")
library("maptools")
library("grid")
library("tmap")
library("tmaptools")

# function to obtain US county shape
get_US_county_2010_shape <- function() {
  dir <- tempdir()
  download.file("http://www2.census.gov/geo/tiger/GENZ2010/gz_2010_us_050_00_20m.zip", destfile = file.path(dir, "gz_2010_us_050_00_20m.zip"))
  unzip(file.path(dir, "gz_2010_us_050_00_20m.zip"), exdir = dir)
  read_shape(file.path(dir, "gz_2010_us_050_00_20m.shp"))
}

# obtain US county shape
US <- get_US_county_2010_shape()

# split shape 
US_cont <- US[!(US$STATE %in% c("02","15","72")),]  
US_AK <- US[US$STATE == "02", ]
US_HI <- US[US$STATE == "15",]

# create state boundaries
US_states <- unionSpatialPolygons(US_cont, IDs=US_cont$STATE)

After setting up the shapefiles, here is where the viewport windows are added to the plot:

# change back to the plotting mode
tmap_mode("plot")

# plot contiguous US
tm_shape(US_cont, projection=2163) +
  tm_polygons(border.col = "grey50", border.alpha = .5, title = "", showNA = TRUE) +
  tm_shape(US_states) +
  tm_borders(lwd=1, col = "black", alpha = .5) +
  tm_credits("Data @ Unites States Department of Agriculture\nShape @ Unites States Census Bureau", position = c("right", "bottom")) +
  tm_layout(title.position = c("center", "top"), 
            legend.position = c("right", "bottom"), 
            frame = FALSE, 
            inner.margins = c(0.1, 0.1, 0.05, 0.05))

# Alaska inset
m_AK <- tm_shape(US_AK, projection = 3338) +
  tm_polygons(border.col = "grey50", border.alpha = .5, breaks = seq(10, 50, by = 5)) +
  tm_layout("Alaska", legend.show = FALSE, bg.color = NA, title.size = 0.8, frame = FALSE)

# Hawaii inset
m_HI <- tm_shape(US_HI, projection = 3759) +
  tm_polygons(border.col = "grey50", border.alpha = .5, breaks=seq(10, 50, by = 5)) +
  tm_layout(legend.show = FALSE, bg.color=NA, title.position = c("LEFT", "BOTTOM"), title.size = 0.8, frame=FALSE)

# print insets
print(m_AK, vp=viewport(x= 0.15, y= 0.15, width= 0.3, height= 0.3))
print(m_HI, vp=viewport(x= 0.4, y= 0.1, width= 0.2, height= 0.1))

Source: I've adapted this from https://github.com/mtennekes/tmap/tree/master/demo/USChoropleth

like image 43
Phil Avatar answered Nov 06 '22 09:11

Phil