TileMapBase
TileMapBase is a Python library that enables the use of OpenStreetMap and other WMTS tiles as basemaps within Matplotlib figures. It simplifies fetching, caching, and rendering geographical tiles, allowing users to overlay their data on real-world maps. Currently at version 0.4.7, it is actively maintained with periodic updates.
Common errors
-
requests.exceptions.HTTPError: 403 Client Error: Forbidden for url: ...
cause Most tile servers require a User-Agent HTTP header to identify the client, or they block requests to prevent abuse.fixCall `tilemapbase.init()` with a `user_agent` parameter at the start of your script, e.g., `tilemapbase.init(user_agent="MyPythonApp/1.0")`. -
AttributeError: module 'tilemapbase' has no attribute 'transform'
cause This error typically occurs in `tilemapbase` versions 0.4.0 and later when trying to import `map_to_pixels` or `pixels_to_map` from the deprecated `tilemapbase.transform` module.fixRemove the `from tilemapbase.transform import ...` statement. The functions are now directly available under the `tilemapbase` module: use `tilemapbase.map_to_pixels(...)` or `tilemapbase.pixels_to_map(...)` after `import tilemapbase`. -
My plotted data appears in the wrong place or is heavily distorted on the map.
cause The Matplotlib axes created by `PlottingContext` are in a projected coordinate system (e.g., Mercator), but your data is likely in geographic (latitude/longitude) coordinates without proper transformation.fixWhen plotting your data (e.g., `ax.plot`, `ax.scatter`), specify the transform to tell Matplotlib your data's coordinate system: `ax.plot(lon, lat, transform=tilemapbase.crs_geographic)`. -
FileNotFoundError: [Errno 2] No such file or directory: '.../tile_cache'
cause This can occur if the default tile cache directory is inaccessible or if a custom cache path is specified incorrectly.fixEnsure the user running the script has write permissions to the cache directory. If specifying a custom cache path in `tilemapbase.init(cache_dir=...)`, make sure the directory exists and is writable, or `tilemapbase` will attempt to create it (which might fail due to permissions).
Warnings
- gotcha Failing to call `tilemapbase.init()` or not providing a `user_agent` string can lead to HTTP 403 (Forbidden) errors from tile servers.
- breaking The `map_to_pixels` and `pixels_to_map` functions were moved from `tilemapbase.transform` directly to the `tilemapbase` top-level module in version 0.4.0.
- gotcha When overlaying your own data (e.g., points, lines) on a TileMapBase map, you must correctly handle coordinate systems. Matplotlib's default coordinates won't match the projected map tiles.
- gotcha Aggressive tile fetching or ignoring tile server terms of service can lead to IP bans or temporary blocks from tile providers.
Install
-
pip install tilemapbase
Imports
- init
import tilemapbase tilemapbase.init(...)
- PlottingContext
from tilemapbase.plotting import PlottingContext
- add_tile_wmts
from tilemapbase.plotting import add_tile_wmts
- map_to_pixels
from tilemapbase.transform import map_to_pixels
import tilemapbase tilemapbase.map_to_pixels(...)
- crs_geographic
import tilemapbase ax.plot(..., transform=tilemapbase.crs_geographic)
Quickstart
import matplotlib.pyplot as plt
import tilemapbase
# Crucial initialization step for tilemapbase. Set a user_agent to avoid 403 errors.
# python_accelerated=True can speed up rendering if numba is installed.
tilemapbase.init(python_accelerated=True, user_agent="my-tilemapbase-app")
# Define the map extent [lon_min, lon_max, lat_min, lat_max]
extent = [-0.20, 0.05, 51.45, 51.55] # Example: Central London
fig, ax = plt.subplots(figsize=(10, 10), dpi=100)
ax.set_xlabel("Longitude")
ax.set_ylabel("Latitude")
ax.set_title("London with TileMapBase")
# Create a PlottingContext. This sets up the matplotlib axes for the map projection.
# 'merc' is the standard projection for web maps.
plot_context = tilemapbase.plotting.PlottingContext(
extent,
ax=ax,
proj="merc"
)
# Add OpenStreetMap tiles to the axes
tilemapbase.plotting.add_tile_wmts(
ax, url=tilemapbase.get_providers_as_dict()["OpenStreetMap"], zoom=13
)
# Set axes limits based on the PlottingContext's projected extent
ax.set_xlim(plot_context.x_min, plot_context.x_max)
ax.set_ylim(plot_context.y_min, plot_context.y_max)
ax.set_aspect(plot_context.get_aspect())
# Example: Overlay a point (London Eye) in geographic coordinates
london_eye_lon, london_eye_lat = -0.1106, 51.5033
ax.plot(
london_eye_lon, london_eye_lat,
'o', color='red', markersize=8,
transform=tilemapbase.crs_geographic, # Crucial: plot in geographic coordinates
label="London Eye"
)
ax.legend()
plt.show()