Show Sidebar Hide Sidebar

Mapbox Layers in R

How to make Mapbox maps in R with various base layers, with or without needing a Mapbox Access token.

New to Plotly?

Plotly's R library is free and open source!
You can set up Plotly to work in online or offline mode.
We also have a quick-reference cheatsheet (new!) to help you get started!

Version Check

Version 4 of Plotly's R package is now available!
Check out this post for more information on breaking changes and new features available in this version.

library(plotly)
packageVersion('plotly')

## [1] '4.9.0.9000'


To create mapbox maps with Plotly, you'll need a Mapbox account and a Mapbox Access Token that you can add to your Plotly Settings. If you're using a Chart Studio Enterprise server, please see additional instructions here: https://help.plot.ly/mapbox-atlas/.

library(plotly)

Sys.setenv('MAPBOX_TOKEN' = 'your_mapbox_token_here')


How Layers work in Mapbox Maps

If your figure contains one or more traces of type Scattermapbox, Choroplethmapbox or Densitymapbox, the layout object in your figure contains configuration information for the map itself. The map is composed of various layers, of three different types.

1. layout.mapbox.style defines the lowest layers, also known as your "base map"
2. The various traces in data are by default rendered above the base map (although this can be controlled via the below attribute).
3. layout.mapbox.layers is an array that defines more layers that are by default rendered above the traces in data (although this can also be controlled via the below attribute).

The word "mapbox" in the trace names and layout.mapbox refers to the Mapbox.js open-source library. If your basemap in layout.mapbox.style uses data from the Mapbox service, then you will need to register for a free account at https://mapbox.com/ and obtain a Mapbox Access token. This token should be provided either in mapboxAccessToken in setPlotConfig function, or as a variable that would be passed as an argument of newPlot. If your layout.mapbox.style does not use data from the Mapbox service, you do not need to register for a Mapbox account.

Base Maps in layout.mapbox.style
The accepted values for layout.mapbox.style are one of the following tiles.
1. "white-bg" yields an empty white canvas which results in no external HTTP requests
2. "open-street-map", "carto-positron", "carto-darkmatter", "stamen-terrain", "stamen-toner" or "stamen-watercolor" yeild maps composed of raster tiles from various public tile servers which do not require signups or access tokens
3. "basic", "streets", "outdoors", "light", "dark", "satellite", or "satellite-streets" yeild maps composed of vector tiles from the Mapbox service, and do require a Mapbox Access Token or an on-premise Mapbox installation.
4. A Mapbox service style URL, which requires a Mapbox Access Token or an on-premise Mapbox installation.
5. A Mapbox Style object as defined at https://docs.mapbox.com/mapbox-gl-js/style-spec/

OpenStreetMap Tiles, no Token Needed

Here is a simple map rendered with "open-street-map" tiles, without needing a Mapbox Access Token.

library(plotly)

p <- us_cities %>%
plot_ly(
lat = ~lat,
lon = ~lon,
marker = list(color = "fuchsia"),
type = 'scattermapbox',
hovertext = us_cities[,"City"]) %>%
layout(
mapbox = list(
style = 'open-street-map',
zoom =2.5,
center = list(lon = -88, lat = 34)))

# Set up API credentials: https://plot.ly/r/getting-started


Using layout.mapbox.layers to Specify a Base Map

If you have access to your own private tile servers, or wish to use a tile server not included in the list above, the recommended approach is to set layout.mapbox.style to "white-bg" and to use layout.mapbox.layers with below to specify a custom base map.

If you omit the below attribute when using this approach, your data will likely be hidden by fully-opaque raster tiles!

Base Tiles from the USGS: no Token Needed

Here is an example of a map which uses a public USGS imagery map, specified in layout.mapbox.layers, and which is rendered below the data layer.

library(plotly)

p <-  us_cities %>%
plot_ly(
lat = ~lat,
lon = ~lon,
type = "scattermapbox",
hovertext = us_cities[,"City"],
marker = list(color = "fuchsia")) %>%
layout(mapbox= list(
style = "white-bg",
zoom = 3,
center = list(lon = -93 ,lat= 41),
layers = list(list(
below = 'traces',
sourcetype = "raster",
source = list("https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryOnly/MapServer/tile/{z}/{y}/{x}")))))

# Set up API credentials: https://plot.ly/r/getting-started


Base Tiles from the USGS, Radar Overlay from Environment Canada: no Token Needed

Here is the same example, with in addition, a WMS layer from Environment Canada which displays near-real-time radar imagery in partly-transparent raster tiles, rendered above the go.Scattermapbox trace, as is the default:

library(plotly)
p <- us_cities %>%
plot_ly(
lat = ~lat,
lon = ~lon,
type = "scattermapbox",
hovertext = us_cities[,"City"],
marker = list(color = "fuchsia")) %>%
layout(
mapbox= list(
style = "white-bg",
sourcetype = 'raster',
zoom = 3,
center = list(lon = -93 ,lat= 41),
layers = list(list(
below = 'traces',
sourcetype = "raster",
source = list("https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryOnly/MapServer/tile/{z}/{y}/{x}")),
list(
sourcetype = "raster",

# Set up API credentials: https://plot.ly/r/getting-started


Dark Tiles from Mapbox Service: Free Token Needed

Here is a map rendered with the "dark" style from the Mapbox service, which requires an Access Token:

library(plotly)

p <- us_cities %>%
plot_ly(
lat = ~lat,
lon = ~lon,
marker = list(color = "fuchsia"),
type = 'scattermapbox',
hovertext = us_cities[,"City"]) %>%
layout(
mapbox = list(
style = 'dark',
accesstoken = token,
zoom =2.5,
center = list(lon = -88, lat = 34)))