If you are using python for spatial processing, it is sometimes useful to plot your data. In these cases, it may be helpful to also render a basemap to help locate the data. This notebook will show you how plot a web map tiles using cartopy and pyplot.
You must have the GEOS and PROJ libraries installed on your system libraries to use cartopy. For the full list of cartopy's dependencies, refer to https://scitools.org.uk/cartopy/docs/latest/installing.html
You should use cartopy >= v18.0, as older versions of cartopy do not work with PROJ 6.0.0 or the latest OSM tile server. As of writing, cartopy v18.0 is only available as a beta release. You can install it using:
In [ ]:
!pip install cython https://github.com/SciTools/cartopy/archive/v0.18.0b1.zip
Cartopy supports many common tile servers, listed on https://scitools.org.uk/cartopy/docs/latest/cartopy/io/img_tiles.html
For this example, we will use OSM.
In [1]:
import cartopy.io.img_tiles as cimgt
request = cimgt.OSM()
Can define your own https://scitools.org.uk/cartopy/docs/latest/crs/index.html or use one of the constant values. We will use Google Mercator for this example
In [2]:
import cartopy.crs as ccrs
carto_proj = ccrs.GOOGLE_MERCATOR
To display the tileset, add a subplot to your plot, and add the tileset as an image.
The projection parameter is added to pyplot by cartopy, and will be used to render the tileset and display the image. The second parameter of add_image is the zoom level to use and will correlate directly to level of detail (and rendering time).
Since we are fetching tiles from an online service, this does require an internet connection.
In [21]:
%matplotlib notebook
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection=carto_proj)
# Add mapbox basemap via cartopy
request = cimgt.OSM()
tile_image = ax.add_image(request, 3)
To render a specific region, call set_extent
with the geodetic (lat/lon) bounds of the region, before calling add_image
. You'll also want to update your zoom level to something appropriate for those bounds.
In [22]:
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection=carto_proj)
ax.set_extent([-123.0, -122.0, 37.5, 38.0])
tile_image = ax.add_image(request, 10)
In [ ]: