Make Beautiful Spatial Visualizations with Plotly and Mapbox | by Will Norris | Towards Data Science

I recently wrote a post about visualizing weather data from NOAA. We walked through processing the data and making some basic interactive maps with Plotly. In this article I want to use the same data but focus on the options we have available for improving our web maps with Plotly and Mapbox. Web maps can serve many purposes, and having a quality base map that helps emphasize or provide context to your data points can make a huge difference in the quality of your visualizations.
Mapbox is a startup that provides the maps for websites like Foursquare and The Weather Channel along with developing some of the most powerful open source tools for creating web maps. The Mapbox JavaScript library has been the best web mapping tool available for several years and now we can take advantage of Mapbox in Python using Plotly.
Plotly has two main types of maps, Geo maps and Mapbox maps. Geo maps are outline based and Mapbox maps are tile based. The main difference between the two is that an outline based map draws everything at once, while a tile based map has a hierarchy of information that is rendered at different levels of zoom.
If I have a map that starts at a global scale and I want users to be able to zoom into see fine levels of granularity, then a tile based map may suit my needs better than an outline map. Since tile based maps don’t have to load in all of the information right away they can be less memory intensive, but having to process the granularity changes when zooming increases a tile maps processing power overhead. This means that tile based maps are fantastic for making a lot of information available without cluttering the map, but they require more data and processing power.
Here is the same map rendered both as an outline map and a tile based map. Try zooming in and see if you can find some notable differences between the two.
At first glance these maps may look quite similar aside from using different projections. But when you start to zoom in you begin to see the advantages of a tile based map. Country borders become visible as they become relevant and less obtrusive to the data points; even cities, roads, and rivers load into the base map as you zoom into finer and finer scales.
Having access to this kind of detail can really make a visualization feel professional, and the varying granularity is helpful when working at multiple scales. If we wanted to show country borders using Plotly’s Scattergeo function we would need to draw them at all scales, like this:
This plot is much busier than the two without country borders at this scale. And we still lack details that the tile map offers like country names and cities. These kinds of features can be configured on the outline map, but they aren’t very practical for an outline map that can quickly become cluttered.
Despite these downsides, outline maps do still have a place. When creating maps of smaller regions we often don’t need to render data at multiple scales, which means there is no reason to add the data and processing overhead of a tile based map. Also, when making maps for presentations it can be advantageous to customize an outline based map to maximize quick readability from a distance. Not to mention that conference rooms don’t always have the best wifi, and I have seen my fair share of web maps load extremely slowly to the dismay of the person speaking.
Mapbox GL JS is a JavaScript library made for web mapping with interactive tile maps. Plotly refers to the Mapbox JavaScript library when we invoke one of the Plotly Mapbox functions in Python. Since some versions of the Mapbox GL JS library are open source, using these functions with an open source base map does not require a Mapbox API key. However, Mapbox as a company has extremely high quality vector tile base maps available that will require a Mapbox API key to use. Mapbox has a great free tier that allows up to 50,000 map loads per month, which is plenty for most users.
Most web maps have traditionally used raster tiles to construct a map, but Mapbox allows us to take advantage of vector tiles as well. If you are familiar with GIS data, a raster is a grid of values (images) and vector data is geometry data — normally points, lines, and polygons.
Raster tiles are a set of images that line up next to each other to form a complete map. As you zoom in, different levels of raster tiles can be loaded to show new features at different scales. Vector tiles work very similarly to this, however the tiles contain pre-generated vector data that suit the zoom and location you are viewing.
There are a lot of upsides to vector tiles. They don’t have to be exactly the same size like raster tiles and they are rendered by the client’s computer, which can make them much lighter weight to host. Vector data also is generally much smaller than raster data making using the map snappier since you are relying less on a fast internet connection. Vector data can even render rasters if needed making it incredibly flexible.
With Plotly we have access to both raster and vector tile base maps. The raster tile base maps we have access to are open source, like Open Street Map’s base maps. Mapbox provides access to vector tile base maps, but they require a Mapbox API token to access. Below I will go through some of the available base maps and show you the practical differences.
All of the raster tile base maps that we have access to are open source and don’t require an API token to make use of. Here are a few examples of what is available:
Open Street Map
Even though we are using a base map from Open Street Map, we still invoke the “Scattermapbox()” function. This is because Plotly makes use of the open source Mapbox JavaScript library to plot tiled maps regardless of whether they are raster or vector tiles.
USGS Imagery Raster Tiles
The United States Geological Survey has a plethora of imagery available online, including some great base maps! The easiest way to use a raster tile image layer like this is to render an empty white canvas and then manually render the base map underneath the data or “traces”.
It’s pretty cool what kinds of maps can be so easily created and shared using Plotly! Imagery like this can provide really useful context to climate data, although you will probably notice that my color scale could use some adjustment to accommodate the dark colors in this base map. Since tile based web maps are a popular standard, there are many available base maps out there that can be easily accessed.
Note: If you are running on a slower internet connection it may take longer for these maps to load. Raster tiles can be quite large, which means a lot of data has to be transferred to your browser.
USGS Hydrological Raster Tiles
If we use this link instead as our source, we can get a hydrological base map from USGS as well:
source = ["https://basemap.nationalmap.gov/arcgis/rest/services/USGSHydroCached/MapServer/tile/{z}/{y}/{x}"]
You will notice with some USGS data products that the data is much more complete in North America, so there may not be useful hydrologic information in some parts of the world. Overall it is really impressive how much free and useful data is available from USGS, NOAA, etc.
USGS Shaded Relief Base Map
Here is a shaded relief base map as one final example of what is available for free from USGS. Keep in mind that there are other raster tile map data sets available online as well that I will link in the Resources section at the end.
"source": [          "https://basemap.nationalmap.gov/arcgis/rest/services/USGSShadedReliefOnly/MapServer/tile/{z}/{y}/{x}"]
Vector tile base maps are acquired from Mapbox’s servers, which means we need a Mapbox account and API token to use them. If your computer is fairly modern, you will likely notice a fairly large improvement in the responsiveness and detail from these vector tile maps. Since vector data is rendered by your computer there is less data being transferred from a server to your machine, which generally means faster loading times.
Mapbox Dark Style
The syntax for plotting with a Mapbox base map is quite similar to the open source alternatives. Instead of specifying the layers, we simply pass a “mapbox” dictionary with our API key and other parameters. The “style” is what determines which Mapbox base map your map uses.
Streets Style
If you are looking for more detail in streets and cities then the “streets” style will suit your use case well. It trades off a lot of the detail in outdoor recreation from the previous map for extremes detail in streets, paths, and parks. This base map allows us to zoom in to see the names of even very small streets. This base map even has all of the campus building names and walking paths mapped in my hometown of Boulder, Colorado.
Outdoors Style
Mapbox even has base maps like the “outdoors” style, which has important land marks and details for hiking, biking, and other outdoor activities. You can even zoom into areas like Breckenridge, Colorado and see the ski runs rendered as you get close enough:
We can see that Plotly and Mapbox give us access to a wide range of base maps to suit many different user needs. Even loading in raster tiles from a third party like USGS is fairly straightforward. It is awesome to have access to such a powerful web mapping tool in Python since being able to produce quality maps without using JavaScript can reduce a lot of friction in your workflow.
USGS Base Maps