A Python package that simplifies the creation of geographic maps using Cartopy. Projmap handles projection setup, map styling, and common plotting tasks so you can focus on your data. Originally developed for oceanography but applicable to any domain.
pip install projmapimportprojmapmp=projmap.Map("westcoast")
mp.nice()nice() draws land, ocean background, and country borders in one call.
Run this once in your project directory to create a skeleton projmap_settings.toml:
projmap.init()This creates a projmap_settings.toml with the default, nwa, korea, and antarctic regions as a starting point. To overwrite an existing file, pass overwrite=True.
Maps are defined by regions stored in TOML configuration files. Projmap searches for settings in this order:
/etc/projmap/projmap_settings.toml~/.config/projmap/projmap_settings.toml./projmap_settings.toml(current directory)- Path in the environment variable
PROJMAP_SETTINGS_FILE_FOR_DYNACONF
Each region is a top-level TOML table with projection parameters and optional styling:
[myregion]
description = "My custom region"lat1 = 48.0lat2 = 62.0lon1 = -10.0lon2 = 20.0projection = "lcc"# Lambert Conformal Conic
[myregion.style]
oceancolor = "0.15"landface = "0.6"landresolution = "10m"# Natural Earth resolution: 10m, 50m, 110mSupported projections:lcc (Lambert Conformal), merc (Mercator), eckert4 (Eckert IV), north_stereo, south_stereo, and Robinson (default).
projmap.show_regions() # list all available regions across all settings filesprojmap.show_region("nwa") # show all settings for a specific regionProjection parameters can also be passed directly to the constructor to override or extend a region:
mp=projmap.Map("default", lat1=48, lat2=62, lon1=-10, lon2=20)importprojmapmp=projmap.Map("myregion")
mp.nice() # land + ocean + bordersmp.nice(rivers=True, states=True) # optionally add rivers and state bordersAll plotting methods accept lon/lat arrays and pass extra keyword arguments through to the underlying Matplotlib/Cartopy call. A colorbar keyword can be added to any of them.
importnumpyasnp# Filled contoursmp.contourf(lon, lat, data, levels=20, cmap="RdBu_r", colorbar=True)
# Contour lines with automatic labels on all levelsmp.contour(lon, lat, data, levels=[-1000, -500, -200, -100],
colors="0.5", linewidths=0.5, clabel=True)
# Contour labels with custom optionsmp.contour(lon, lat, data, levels=[-1000, -500, -200, -100],
colors="0.4", clabel=dict(fontsize=6, fmt=" {:.0f} ".format))
# Pseudocolormp.pcolor(lon, lat, data, cmap="viridis", colorbar=True)
# Scatter plotmp.scatter(lons, lats, c=values, s=10, cmap="plasma", colorbar=True)
# Line / trackmp.plot(lons, lats, color="red", linewidth=1)
# Vector fieldmp.streamplot(u, v, lon=lon, lat=lat, color="white", density=1.5)mp=projmap.Map("myregion")
axes=mp.subplots(nrows=1, ncols=2)
mp.pcolor(lon, lat, sst, ax=axes[0], cmap="RdYlBu_r")
mp.contourf(lon, lat, ssh, ax=axes[1], levels=20, cmap="viridis")mp.text(lon, lat, "Label", fontsize=8, color="white")
mp.rectangle(lon1=-5, lat1=50, lon2=10, lat2=58, edgecolor="red", linewidth=1)mp.contourf(lon, lat, data, cmap="RdBu_r")
mp.colorbar() # add colorbar after the factimportcartopy.io.img_tilesascimgtmp=projmap.Map("myregion")
mp.add_tiles(zoom=8) # OpenStreetMap (default)mp.add_tiles(zoom=10, tile_source=cimgt.Stamen("terrain"))mp=projmap.Map("myregion")
mp.set_style(landfill="0.65", landedge="0.4")
mp.nice()Style values can also be set permanently in your projmap_settings.toml:
[myregion.style]
landface = "0.65"landedge = "0.4"oceancolor = "0.15"landresolution = "10m"# Natural Earth resolution: 10m, 50m, 110mAdd labelled point markers to a region by defining them in projmap_settings.toml:
[[myregion.locations]]
name = "Oslo"lon = 10.75lat = 59.91color = "white"ha = "left"# horizontal alignmentva = "bottom"# vertical alignmentThey are drawn automatically by mp.nice() / mp.add_locations().
| Method | Description |
|---|---|
Map(region, **proj_kw) | Create a map for the given region |
nice(borders, rivers, states) | Draw a complete base map |
pcolor(lon, lat, data, **kw) | Pseudocolor plot |
contourf(lon, lat, data, **kw) | Filled contour plot |
contour(lon, lat, data, **kw) | Contour lines (supports clabel=True) |
scatter(lons, lats, **kw) | Scatter plot |
plot(lons, lats, **kw) | Line plot |
streamplot(u, v, lon, lat, **kw) | Vector streamlines |
hatch(lon, lat, mask, **kw) | Hatching over masked regions |
text(lon, lat, s, **kw) | Text annotation |
rectangle(lon1, lat1, lon2, lat2, **kw) | Projection-correct rectangle |
colorbar(**kw) | Add horizontal colorbar |
add_tiles(zoom, tile_source) | Add tile imagery |
add_land(**kw) | Draw land features |
subplots(nrows, ncols, **kw) | Create multi-panel figure |
set_style(landfill, landedge) | Override map style |
set_extent(**kw) | Set geographic extent |
set_circle_boundary() | Circular boundary (polar projections) |
init(path, overwrite) | Create a skeleton projmap_settings.toml in the current directory |
show_regions() | List all available regions |
show_region(region) | Print all settings for a specific region |
All plotting methods accept a colorbar=True keyword to add a colorbar, and pass remaining keyword arguments to the underlying Matplotlib/Cartopy function.
- Cartopy >= 0.25
- Matplotlib >= 3.10
- NumPy >= 2.4
- Dynaconf >= 3.2
- matplotlib-scalebar >= 0.9
See LICENSE for details.