Saving a tmap with a basemap as an image?

Viewed 2918

I have created a map in R using tmap, with a basemap, and want to save it as an image.

Whenever I use tmap_save to save it as a .png, I lose the basemap.

Presumably, this is because the basemap is not visible in plot mode and only in view mode.

Is there a good way of saving the map, with the basemap, as an image?

I have a workaround that involves saving it as HTML first, but it's not a great solution.

2 Answers

I ran into a similar issue trying to create a static map. I've found the tmaptools::read_osm function seems to solve it for me. Here's a reproducible example of three maps:

  • map_a looks good, until you save it
  • map_b doesn't look good at all
  • map_c looks good, even when saved

Create an example map in interactive view. But in the saved file, the basemap doesn't appear.

library(tmaptools) 
library(tmap)
data(metro)

tmap_mode("view")
map_a <- tm_basemap("OpenStreetMap.Mapnik") +
  tm_shape(metro) +
  tm_bubbles(size = "pop2020", col = "red") 
map_a
tmap_save(map_a, filename="map_a.png")

Try to create a similar map as a plot, but basemap doesn't appear at all, and the red dots float without a map.

tmap_mode("plot")
map_b <- tm_basemap("OpenStreetMap.Mapnik") +
  tm_shape(metro) +
  tm_bubbles(size = "pop2020", col = "red") 
map_b
tmap_save(map_b, filename="map_b.png")

Here is a solution: use read_osm. The basemap appears and can be saved.

c_osm <- tmaptools::read_osm(bb(metro), ext = 1.05)
map_c <- tm_shape(c_osm) +
  tm_rgb() +
  tm_shape(metro) + 
  tm_bubbles(size = "pop2020", col = "red") 
map_c
tmap_save(map_c, filename="map_c.png")

Another option is to save the tmap object as a leaflet object and then use the mapshot() function in mapview package to save it as an image. Below is an example.

library(mapview)
#May need this for mapshot to work
#webshot::install_phantomjs()

data("World")

map <- tm_basemap(leaflet::providers$Esri.WorldTopoMap) + 
tm_shape(World) + tm_polygons(alpha = 0,border.col = "black", lwd = 2)

lf <- tmap_leaflet(map)
mapshot(lf, file = "world_map.png")
Related