With the tmap package, thematic maps can be generated with great flexibility. The syntax for creating plots is similar to that of ggplot2
, but tailored to maps. This vignette is for those who want to get started with tmap within a couple of minutes. A more detailed description of tmap can be found in an article published in the Journal of Statistical Software (JSS). However, that article describes tmap version 1.11-2, which is out-of-date. Some major changes have been made since then, which are described in vignette("tmap-changes")
.
For more context on R’s geographic capabilities we recommend the online version of the book Geocomputation with R. The Making maps with R chapter of the book provides many more context and abundant code examples of map making with tmap
and other packages. Other good resources are the vignettes of the sf
package.
A good place to start is to create a map of the world. After installing tmap, the following lines of code should create the map shown below:
library(tmap)
data("World")
tm_shape(World) +
tm_polygons("HPI")
The object World
is a spatial object of class sf
from the sf package; it is a data.frame
with a special column that contains a geometry for each row, in this case polygons. In order to plot it in tmap, you first need to specify it with tm_shape
. Layers can be added with the +
operator, in this case tm_polygons
. There are many layer functions in tmap, which can easily be found in the documentation by their tm_
prefix. See also ?'tmap-element'
.
Each map can be plotted as a static image or viewed interactively using "plot"
and "view"
modes, respectively. The mode can be set with the function tmap_mode
, and toggling between the modes can be done with the ‘switch’ ttm()
(which stands for toggle thematic map.
tmap_mode("view")
tm_shape(World) +
tm_polygons("HPI")
A shape is a spatial object (with a class from sf
, sp
, stars
, or raster
). Multiple shapes and also multiple layers per shape can be plotted:
data(World, metro, rivers, land)
tmap_mode("plot")
## tmap mode set to plotting
tm_shape(land) +
tm_raster("elevation", palette = terrain.colors(10)) +
tm_shape(World) +
tm_borders("white", lwd = .5) +
tm_text("iso_a3", size = "AREA") +
tm_shape(metro) +
tm_symbols(col = "red", size = "pop2020", scale = .5) +
tm_legend(show = FALSE)
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
Facets can be created in three ways:
tm_polygons
:tmap_mode("view")
tm_shape(World) +
tm_polygons(c("HPI", "economy")) +
tm_facets(sync = TRUE, ncol = 2)
by
argument of tm_facets
:tmap_mode("plot")
## tmap mode set to plotting
data(NLD_muni)
$perc_men <- NLD_muni$pop_men / NLD_muni$population * 100
NLD_muni
tm_shape(NLD_muni) +
tm_polygons("perc_men", palette = "RdYlBu") +
tm_facets(by = "province")
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
tmap_arrange
function:tmap_mode("plot")
## tmap mode set to plotting
data(NLD_muni)
<- tm_shape(NLD_muni) + tm_polygons("population", convert2density = TRUE)
tm1 <- tm_shape(NLD_muni) + tm_bubbles(size = "population")
tm2
tmap_arrange(tm1, tm2)
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## Legend labels were too wide. Therefore, legend.text.size has been set to 0.27. Increase legend.width (argument of tm_layout) to make the legend wider and therefore the labels larger.
## The legend is too narrow to place all symbol sizes.
Tiled basemaps can be added with the layer function tm_basemap
. Semi-transparent overlay maps (for example annotation labels) can be added with tm_tiles
.
tmap_mode("view")
tm_basemap("Stamen.Watercolor") +
tm_shape(metro) + tm_bubbles(size = "pop2020", col = "red") +
tm_tiles("Stamen.TonerLabels")
See a preview of the available tilemaps. This list is also accessible in R: leaflet::providers
.
The functions tm_layout
and tm_view
are used to specify the map layout and the interactive aspects respectively. These functions can be used in the same way as the layer functions, e.g.
tmap_mode("plot")
## tmap mode set to plotting
tm_shape(World) +
tm_polygons("HPI") +
tm_layout(bg.color = "skyblue", inner.margins = c(0, .02, .02, .02))
These options, as well as a couple of others, can also be set within with tmap_options
, which works in the same way as the base R function options
. The main advantage is that these options are set globally, so they do not have to be specified in each map, for the duration of the session.
tmap_options(bg.color = "black", legend.text.color = "white")
tm_shape(World) +
tm_polygons("HPI", legend.title = "Happy Planet Index")
A style is a certain configuration of the tmap options.
tmap_style("classic")
## tmap style set to "classic"
## other available styles are: "white", "gray", "natural", "cobalt", "col_blind", "albatross", "beaver", "bw", "watercolor"
tm_shape(World) +
tm_polygons("HPI", legend.title = "Happy Planet Index")
# see what options have been changed
tmap_options_diff()
## current tmap options (style "classic") that are different from default tmap options (style "white"):
## $sepia.intensity
## [1] 0.7
##
## $frame.double.line
## [1] TRUE
##
## $fontfamily
## [1] "serif"
##
## $compass.type
## [1] "rose"
##
## $basemaps
## [1] "Esri.WorldTopoMap"
##
## $basemaps.alpha
## [1] 0.5
# reset the options to the default values
tmap_options_reset()
## tmap options successfully reset
New styles can be created; see ?tmap_options
.
<- tm_shape(World) +
tm tm_polygons("HPI", legend.title = "Happy Planet Index")
## save an image ("plot" mode)
tmap_save(tm, filename = "world_map.png")
## save as stand-alone HTML file ("view" mode)
tmap_save(tm, filename = "world_map.html")
It is possible to use tmap in shiny:
# in UI part:
tmapOutput("my_tmap")
# in server part
$my_tmap = renderTmap({
outputtm_shape(World) + tm_polygons("HPI", legend.title = "Happy Planet Index")
})
See ?renderTmap
for a working example.
Maps can also be made with one function call. This function is qtm
:
qtm(World, fill = "HPI", fill.pallete = "RdYlGn")
Run:
tmap_tip()