Create Beautiful Thematic Maps with tmap


The tmap package in R is designed for creating thematic maps, allowing users to visualize spatial data in an intuitive and flexible way.
This post showcases the key features of tmap and provides a set of map examples using the package.

Documentation

{tmap}

Quick start


The tmap package in R is designed for creating thematic maps, allowing users to visualize spatial data in an intuitive and flexible way.

It offers a set of functions that make it easy to create complex maps with a consistent and user-friendly syntax, similar to ggplot2. It’s built on top of sf and leaflet.

✍️ author → Martijn Tennekes

📘 documentationwebsite

⭐️ more than 800 stars on github

Installation


To get started with tmap, you can install it directly from CRAN using the install.packages function:

install.packages("tmap")

Basic usage


The tmap package uses a layered approach to building maps, similar to ggplot2. You start with tm_shape() to define the data, then add layers with various tm_*() functions.

Here’s a basic example:

library(tmap)
data("World")

tm_shape(World) +
  tm_polygons("pop_est", style = "quantile", title = "Population")

Key features


→ Draw borders

You can create minimalist maps using the tm_borders() function:

library(tmap)
data("World")

tm_shape(World) +
  tm_borders()


→ Multiple Layers

You can add multiple layers to your map using the + operator. The following example will add the name of each country with a size proportional to the AREA column:

library(tmap)
data("World")

tm_shape(World) +
  tm_polygons("income_grp", palette = "Blues") +
  tm_text("name", size = "AREA")


→ Faceted Maps

Use tm_facets() to create small multiples based on a variable. Here, we use the continent column to create a facet:

library(tmap)
data("World")

tm_shape(World) +
  tm_polygons("gdp_cap_est", style = "quantile") +
  tm_facets("continent", free.coords = FALSE)


→ Style Customization

You can apply any custom style to your tmap maps. In the following example, we:

  • Color and Style:
    • Uses a reversed RdYlBu palette for life expectancy
    • Applies the “pretty” style for class intervals
    • Sets white borders with reduced opacity for countries
  • Text:
    • Overlays country codes (ISO A3) on each country
  • Legend:
    • Moves the legend outside the map
    • Customizes legend appearance (frame, background color, text size)
  • Layout:
    • Adds a title with custom positioning and size
    • Sets a background color for the entire plot
    • Adds a frame around the map
    • Customizes inner margins
  • Additional Elements:
    • Includes a compass and scale bar
    • Adds credits for the data source
  • Overall Style:
    • Applies the “natural” built-in style as a base
library(tmap)
library(dplyr)

# Prepare the data
data("World")
world_data <- World %>%
  filter(!is.na(life_exp)) %>%
  mutate(pop_density = pop_est / area)

# Create the customized map
tm_shape(world_data) +
  tm_polygons("life_exp",
    palette = "-RdYlBu",
    style = "pretty",
    n = 7,
    title = "Life Expectancy",
    popup.vars = c("name", "life_exp", "gdp_cap_est"),
    border.col = "white",
    border.alpha = 0.5
  ) +
  tm_text("iso_a3", size = "AREA", col = "black", fontface = "bold", alpha = 0.7) +
  tm_layout(
    title = "Global Life Expectancy and Economic Indicators",
    title.position = c("center", "top"),
    title.size = 1.5,
    bg.color = "#f5f5f5",
    inner.margins = c(0.1, 0.1, 0.1, 0.1),
    frame = TRUE,
    frame.lwd = 2,
    legend.outside = TRUE,
    legend.outside.position = "right",
    legend.frame = TRUE,
    legend.bg.color = "white",
    legend.text.size = 0.7
  ) +
  tm_compass(position = c("left", "top"), size = 2) +
  tm_scale_bar(position = c("left", "bottom"), text.size = 0.6) +
  tm_credits("Data: {tmap} World dataset", position = c("right", "bottom"), size = 0.6) +
  tm_style("natural")


→ Interactive Maps

You can super easily make all your tmap maps switch to interactive mode with tmap_mode("view"). In this example, we:

  • Filters the World dataset to focus on European countries.
  • Uses GDP per capita for the polygon fill color, with a “jenks” classification method and the “viridis” color palette.
  • Adds popup information for country name, population, and GDP per capita.
  • Includes country borders with reduced opacity.
  • Adds bubbles representing population size and colored by life expectancy.
  • Customizes the layout with a title and places the legend outside the map.
  • Includes a scale bar and compass for better orientation.
library(tmap)
library(dplyr)
data("World")

europe <- World %>%
  filter(continent == "Europe")

tmap_mode("view")

my_tmap <- tm_shape(europe) +
  tm_polygons("gdp_cap_est",
    style = "jenks",
    palette = "viridis",
    title = "GDP per capita",
    popup.vars = c("name", "pop_est", "gdp_cap_est"),
    id = "name"
  ) +
  tm_borders(alpha = 0.5) +
  tm_bubbles(
    size = "pop_est",
    col = "life_exp",
    scale = 0.5,
    title.size = "Population",
    title.col = "Life Expectancy",
    popup.vars = TRUE
  ) +
  tm_layout(
    title = "European Countries: GDP, Population, and Life Expectancy",
    legend.outside = TRUE,
    legend.outside.position = "right"
  ) +
  tm_scale_bar(position = c("left", "bottom")) +
  tm_compass(position = c("right", "top"))

tmap_save(my_tmap, filename = "../HtmlWidget/my_interactive_map.html")

Note: You can return to static display mode by running:tmap_mode("plot")





❤️ 10 best R tricks ❤️

👋 After crafting hundreds of R charts over 12 years, I've distilled my top 10 tips and tricks. Receive them via email! One insight per day for the next 10 days! 🔥