In "view" mode, a basemap is added by default and the map becomes interactive — zoom, pan, tooltips, popups, and more. Basemaps are covered in the next section.
Mode-specific options
Use tm_view() to control interactive-mode behaviour:
See ?tm_view for all options (control box position, zoom limits, etc.).
Basemaps
What are basemaps?
A basemap is a pre-built map used as a geographic background
Drawn at the bottom, below all data layers
In "view" mode, basemaps are added by default
In "plot" mode, you need to add them explicitly via tm_basemap()
Use tm_basemap() to control which basemap is shown.
Basemap providers
Most basemaps are generated from OpenStreetMap data
Each provider styles OSM elements differently (colours, line widths, labels…)
The available providers depend on the mode: many work across modes, but there are differences — use tmap_providers() to see what is available for the active mode
The three basemaps appear as radio buttons — only one visible at a time.
Multiple basemaps — combining into a layer group
Assign both data layers to the same group so they toggle together:
tmap_mode("view")tm_shape(NLD_muni) +tm_polygons("employment_rate", group ="Choropleth") +tm_shape(NLD_prov) +tm_borders(lwd =3, group ="Choropleth") +tm_basemap(c("OpenStreetMap","CartoDB.Positron","Esri.WorldImagery"))
Now the municipality fill and province borders share a single “Choropleth” checkbox in the layer control.
Multiple basemaps — radio toggle between basemap and choropleth
Use tm_group() with control = "radio" to make the choropleth switch like a basemap — so only one of the basemap or the choropleth is visible at a time:
tmap_mode("view")tm_shape(NLD_muni) +tm_polygons("employment_rate", group ="Choropleth") +tm_shape(NLD_prov) +tm_borders(lwd =3, group ="Choropleth") +tm_basemap("OpenStreetMap") +tm_group("Choropleth", control ="radio")
Overlay maps with tm_tiles()
An overlay map contains only vector elements (roads, labels, boundaries) with a transparent background
Use tm_tiles() — drawn in call order, unlike tm_basemap() which is always at the bottom
Multiple overlays become check box toggles (vs radio buttons for basemaps)
Note: Thunderforest and Stadia maps require a free API key.
CRS in view mode
Leaflet and Web Mercator
In "view" mode, Leaflet uses Web Mercator (EPSG:3857) by default — because the vast majority of basemap tiles are served in this CRS, Leaflet adopts it as the map’s projection:
Your spatial data is reprojected on the fly to Web Mercator for display
Coordinates are shown as latitude/longitude (EPSG:4326)
The original CRS of your data is preserved in R — only the display uses 3857
tmap_mode("view")# NLD_muni is in RD New (EPSG:28992), the official CRS for the Netherlandstm_shape(NLD_muni) +tm_polygons("employment_rate")
Using a different CRS in view mode
You can set a different CRS via tm_crs(), but basemaps will usually disappear:
tmap_mode("view")tm_shape(NLD_muni) +tm_polygons("employment_rate") +tm_crs(28992) +# RD New — virtually no tile providers support thistm_basemap(NULL) # disable basemap explicitly
Tile servers for CRS other than 3857 do exist, but require a custom tile URL template — not covered here
In practice: if you need a non-Web-Mercator CRS in view mode, disable basemaps
CRS in view mode — summary
By default, "view" mode uses Web Mercator (EPSG:3857) with basemaps. When you switch to any other CRS, basemaps are usually not available:
Mode
Default CRS
Basemaps
"view" (default)
Web Mercator (3857)
✅ available
"view" + custom tm_crs()
any
❌ usually not available
"maplibre" / "mapbox"
Web Mercator (3857)
✅ available
"maplibre" / "mapbox" + Globe
Globe
✅ some — even in 3D!
The "maplibre" and "mapbox" modes from tmap.mapgl work the same way, but add a Globe CRS and support 3D basemaps — more on that in Sessions 7 and 8. 🌐
World maps in view mode
Web Mercator distorts the poles heavily — fine for navigation and location, not recommended for thematic world maps.
Option 1 — use a world CRS and disable basemaps:
tmap_mode("view")tm_shape(World) +tm_polygons("HPI") +tm_crs("+proj=eqearth") +# Equal Earth, Robinson, etc.tm_basemap(NULL) # basemaps not available for this CRS
Option 2 — use the "maplibre" mode from tmap.mapgl (Globe CRS by default, no distortion):