Context geo-tiles in Python for retrieving and working with basemap tiles from the internet
npx @tessl/cli install tessl/pypi-contextily@1.6.0A Python library for retrieving tile maps from the internet and adding them as basemaps to matplotlib figures or writing tile maps to disk as geospatial raster files. Contextily enables seamless integration of web-based map tiles with geospatial data visualization, supporting coordinate transformations between WGS84 (EPSG:4326) and Spherical Mercator (EPSG:3857) projections.
pip install contextily or conda install contextilyimport contextily as ctxFor specific functionality:
from contextily import add_basemap, bounds2img, Placeimport contextily as ctx
import matplotlib.pyplot as plt
import numpy as np
# Add a basemap to an existing matplotlib plot
fig, ax = plt.subplots(figsize=(10, 8))
# Example: plot some geographic data (in Web Mercator projection)
x = [-8239310, -8238310, -8237310] # Web Mercator X coordinates
y = [4969450, 4970450, 4971450] # Web Mercator Y coordinates
ax.scatter(x, y, s=100, c='red', alpha=0.8)
# Add contextily basemap
ctx.add_basemap(ax, source=ctx.providers.OpenStreetMap.HOT)
ax.set_xlim(min(x)-1000, max(x)+1000)
ax.set_ylim(min(y)-1000, max(y)+1000)
plt.show()
# Download and save map tiles as a raster file
west, south, east, north = -74.1, 40.7, -73.9, 40.8 # NYC bounds (lon/lat)
img, extent = ctx.bounds2raster(west, south, east, north,
'nyc_basemap.tiff', zoom=12, ll=True)
# Geocode a place and get its map
place = ctx.Place("Times Square, New York", zoom=15)
place.plot()
plt.show()Contextily is organized around three main functional areas:
The library integrates with the broader Python geospatial ecosystem through dependencies on rasterio (geospatial data), matplotlib (visualization), mercantile (tile math), and xyzservices (provider definitions).
Add web or local basemaps to existing matplotlib axes with automatic coordinate handling, provider support, and custom styling options.
def add_basemap(ax, zoom='auto', source=None, interpolation='bilinear',
attribution=None, attribution_size=8, reset_extent=True,
crs=None, resampling=Resampling.bilinear, zoom_adjust=None,
**extra_imshow_args):
"""Add a basemap to matplotlib axes."""
def add_attribution(ax, text, font_size=8, **kwargs):
"""Add attribution text to matplotlib axes."""Download map tiles for specified geographic bounds, with support for various zoom levels, tile providers, caching, and output formats.
def bounds2img(w, s, e, n, zoom='auto', source=None, ll=False,
wait=0, max_retries=2, n_connections=1, use_cache=True,
zoom_adjust=None):
"""Download tiles and return as image array with extent."""
def bounds2raster(w, s, e, n, path, zoom='auto', source=None, ll=False,
wait=0, max_retries=2, n_connections=1, use_cache=True):
"""Download tiles and write to raster file."""
def howmany(w, s, e, n, zoom, verbose=True, ll=False):
"""Calculate number of tiles required for bounding box and zoom."""
def set_cache_dir(path):
"""Set custom cache directory for tile downloads."""Reproject and transform map tiles and images between different coordinate reference systems with support for various resampling methods.
def warp_tiles(img, extent, t_crs='EPSG:4326', resampling=Resampling.bilinear):
"""Reproject Web Mercator basemap into any CRS."""
def warp_img_transform(img, transform, s_crs, t_crs, resampling=Resampling.bilinear):
"""Reproject image with given transform and CRS."""Geocode locations by name and retrieve corresponding map tiles with integrated plotting capabilities for location-based visualizations.
class Place:
"""Geocode a place by name and get its map."""
def __init__(self, search, zoom=None, path=None, zoom_adjust=None,
source=None, geocoder=None): ...
def plot(self, ax=None, zoom='auto', interpolation='bilinear',
attribution=None): ...
def plot_map(place, bbox=None, title=None, ax=None, axis_off=True,
latlon=True, attribution=None):
"""Plot map of given place (deprecated)."""Contextily integrates with xyzservices to provide access to numerous tile providers:
# Access via contextily.providers (re-exported from xyzservices.providers)
ctx.providers.OpenStreetMap.HOT # OpenStreetMap Humanitarian tiles
ctx.providers.Stamen.Toner # Stamen Toner tiles
ctx.providers.CartoDB.Positron # CartoDB light tiles
ctx.providers.ESRI.WorldImagery # ESRI satellite imagery
# Alternative direct import
from contextily import providers
providers.OpenStreetMap.HOTCustom tile providers can be specified as URLs or TileProvider objects with {x}, {y}, {z} placeholders for tile coordinates.
# From rasterio.enums
class Resampling(Enum):
"""Resampling algorithms for warping operations."""
bilinear = 'bilinear'
nearest = 'nearest'
cubic = 'cubic'
# ... other resampling methods
# From xyzservices
class TileProvider:
"""Tile provider configuration."""
def __init__(self, url: str, attribution: str = '', name: str = ''): ...
def build_url(self, x: int, y: int, z: int) -> str: ...
# Standard return types
ImageArray = numpy.ndarray # 3D array (height, width, bands) of image data
Extent = tuple[float, float, float, float] # (minX, maxX, minY, maxY) bounding box