CARTOPY
Mapping the world with Python
What is Cartopy?
Cartopy is a Python library designed for geospatial data processing and mapping. Cartopy makes use of the powerful PROJ, NumPy and Shapely libraries and includes a programmatic interface built on top of Matplotlib for the creation of publication quality maps. It is widely used in meteorology, oceanography, and environmental sciences for tasks like plotting weather patterns, climate data, and geographic visualizations.
Installation
Using Conda (Recommended)
If you have Anaconda or Miniconda installed, run:conda install -c conda-forge cartopy
Using pip
Using pip to install will require you to download its dependencies (for example, pyproj and pyshp etc.)pip install cartopy
Key features
1. High-Quality Map Visualizations
Cartopy builds on Matplotlib to create publication-ready maps with customizable features:
- Coastlines, borders, and rivers at various resolutions.
- Natural Earth datasets for land, ocean, lakes, and ice features.
- Custom annotations, gridlines, legends, and colorbars.
For example, a map of Africa with its features is shown below
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
def main():
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection=ccrs.PlateCarree())
ax.set_extent([-20, 60, -40, 45], crs=ccrs.PlateCarree())
ax.add_feature(cfeature.LAND)
ax.add_feature(cfeature.OCEAN)
ax.add_feature(cfeature.COASTLINE)
ax.add_feature(cfeature.BORDERS, linestyle=':')
ax.add_feature(cfeature.LAKES, alpha=0.5)
ax.add_feature(cfeature.RIVERS)
plt.show()
if __name__ == '__main__':
main()

2. Map Projections
Map projections flatten the Earth’s 3D surface onto a 2D map. Cartopy supports a wide range of these:
- PlateCarree (Equirectangular): Simple mapping of lat/lon to x/y. Distorts near poles.
- Mercator: Great for navigation. Keeps angles accurate but distorts size near poles.
- LambertConformal: Excellent for weather maps; preserves local shapes.
- Orthographic: Globe-like natural view.
- Robinson: Balances shape and area for global maps.
3. Built-in Natural Earth Datasets
Cartopy includes Natural Earth datasets for quick and accurate mapping:
- Physical Data – Coastlines, rivers, lakes.
- Cultural Data – Country/state borders, populated places.
- Resolutions – 10m (high), 50m (medium), 110m (low).
4. Geospatial Plotting
Plot various geospatial data types directly on maps:
- Points – Cities, events.
- Lines – Hurricane tracks, migration paths.
- Polygons – State boundaries, buffer zones.
For example, Delhi and the Ganges river are plotted on the map below
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from shapely.geometry import LineString
ax = plt.axes(projection=ccrs.PlateCarree())
ax.set_extent([65, 100, 0, 40], crs=ccrs.PlateCarree())
ax.add_feature(cfeature.LAND)
ax.add_feature(cfeature.OCEAN)
ax.add_feature(cfeature.COASTLINE)
ax.add_feature(cfeature.BORDERS, linestyle=':')
ganges_lons = [78.57, 81.63, 83.23, 85.12, 87.03, 89.03]
ganges_lats = [25.45, 25.12, 25.75, 25.55, 24.90, 22.90]
ax.plot(ganges_lons, ganges_lats, color='blue',markersize=2, linewidth=1, marker='o', transform=ccrs.Geodetic(), label='Ganges River')
ax.plot(77.23, 28.61, 'r*', markersize=3, transform=ccrs.Geodetic(),label='Delhi')
plt.legend(loc='lower left')
plt.show()

5. Geometric Operations with Shapely
Cartopy integrates with Shapely for complex geometric operations like intersections, buffers, and unions:
- Buffering – Create zones around points or paths (e.g., hurricane tracks).
- Intersections – Find overlapping areas between shapes.
- Distance Calculations – Measure distances between points.
6. Advanced Mapping Techniques
Cartopy supports advanced mapping techniques for enhanced geospatial visualizations:
- Custom Map Projections – Create specialized projections tailored to specific regions for improved spatial accuracy.
- Web Map Service (WMS) Integration – Overlay real-time or high-resolution map tiles from external sources like OpenStreetMap or NASA’s Blue Marble.
- Gridlines, Ticks, and Annotations – Add precise gridlines, axis ticks, and annotations for better map readability and presentation.
- Vector Field Visualization – Plot wind patterns, ocean currents, or any directional data using arrows or streamlines to represent magnitude and direction.
For example, a custom map projection is shown below
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
projection = ccrs.LambertConformal(central_longitude=-96, central_latitude=39)
fig, ax = plt.subplots(subplot_kw={'projection': projection})
ax.add_feature(cfeature.LAND)
ax.add_feature(cfeature.OCEAN)
ax.gridlines(draw_labels=True)
plt.show()

Applications and Use-cases
This tool can be used in various fields:
- Weather and Environment Studies: Visualizing temperature, precipitation, wind patterns, ocean currents and pollutants dispersion.
- Natural Disaster Tracking: Mapping the paths of hurricanes, earthquakes, and wildfires.
- Urban planning and infrastructue: Mapping road networks, zoning boundaries, pipelines and powergrids.
- Navigation and Logistics: Plotting flight paths, no-fly zones, shipping routes and delivery netwroks.
- Socio-economic Analysis: VIsualizing population density, disease outbreak and voting patterns.
A few images from the net showing the plots made with cartopy



Code Examples
Australia with its states and water bodies
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import cartopy.io.shapereader as shpreader
import matplotlib.pyplot as plt
# Projection Setup and setting extent
fig = plt.figure(figsize=(12, 14),dpi=150)
ax = plt.axes(projection=ccrs.PlateCarree())
ax.set_extent([110, 155, -45, -8], crs=ccrs.PlateCarree())
# Load the admin_1_states_provinces shapefile
shpfilename = shpreader.natural_earth(resolution='10m', category='cultural', name='admin_1_states_provinces')
reader = shpreader.Reader(shpfilename)
states = reader.records()
color = plt.get_cmap('Set1')
idx=0
for state in states:
if state.attributes['admin'] == 'Australia':
ax.add_geometries([state.geometry], ccrs.PlateCarree(), edgecolor='black', facecolor=color(idx),linewidth=0.5)
idx+=1
# Add physical features and grid
ax.add_feature(cfeature.LAND, facecolor='lightgreen')
ax.add_feature(cfeature.OCEAN)
ax.add_feature(cfeature.RIVERS.with_scale('10m'), edgecolor='blue', linewidth=0.5)
ax.add_feature(cfeature.LAKES.with_scale('10m'), facecolor='blue')
ax.gridlines(draw_labels=True, linestyle='--', alpha=0.8)
plt.show()

Flight path from Mumbai to Toronto via Paris
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pyplot as plt
# Airport coordinates (Longitude, Latitude)
airports = {
"Mumbai": (72.8656, 19.0896),
"Paris": (2.55, 49.00),
"Toronto": (-79.6306, 43.6777)
}
#Projection Setup
fig = plt.figure(figsize=(15, 6), dpi=300)
ax = plt.axes(projection=ccrs.PlateCarree())
#Add map features
ax.add_feature(cfeature.BORDERS, linestyle=":")
ax.add_feature(cfeature.LAND, facecolor='green')
ax.add_feature(cfeature.OCEAN)
ax.gridlines(draw_labels=True)
#Extract and plot
lons, lats = zip(*airports.values())
ax.plot(lons, lats, linewidth=2, c='r', marker='o', transform=ccrs.Geodetic())
for city, (lon, lat) in airports.items():
ax.text(lon-4, lat+1, city, fontsize=12, fontweight='bold', transform=ccrs.PlateCarree())
plt.show()

States affected by Hurricane Katrina(taken from official documentation of Cartopy)
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
import shapely.geometry as sgeom
import cartopy.crs as ccrs
import cartopy.io.shapereader as shpreader
"""
The data was originally sourced from the HURDAT2 dataset from AOML/NOAA:
https://www.aoml.noaa.gov/hrd/hurdat/newhurdat-all.html on 14th Dec 2012.
"""
lons = [-75.1, -75.7, -76.2, -76.5, -76.9, -77.7, -78.4, -79.0,
-79.6, -80.1, -80.3, -81.3, -82.0, -82.6, -83.3, -84.0,
-84.7, -85.3, -85.9, -86.7, -87.7, -88.6, -89.2, -89.6,
-89.6, -89.6, -89.6, -89.6, -89.1, -88.6, -88.0, -87.0,
-85.3, -82.9]
lats = [23.1, 23.4, 23.8, 24.5, 25.4, 26.0, 26.1, 26.2, 26.2, 26.0,
25.9, 25.4, 25.1, 24.9, 24.6, 24.4, 24.4, 24.5, 24.8, 25.2,
25.7, 26.3, 27.2, 28.2, 29.3, 29.5, 30.2, 31.1, 32.6, 34.1,
35.6, 37.0, 38.6, 40.1]
fig = plt.figure()
# to get the effect of having just the states without a map "background"
# turn off the background patch and axes frame
ax = fig.add_axes([0, 0, 1, 1], projection=ccrs.LambertConformal(), frameon=False)
ax.patch.set_visible(False)
ax.set_extent([-125, -66.5, 20, 50], ccrs.Geodetic())
shapename = 'admin_1_states_provinces_lakes'
states_shp = shpreader.natural_earth(resolution='110m',
category='cultural', name=shapename)
ax.set_title('US States which intersect the track of '
'Hurricane Katrina (2005)')
# turn the lons and lats into a shapely LineString
track = sgeom.LineString(zip(lons, lats))
# buffer the linestring by two degrees (note: this is a non-physical distance)
track_buffer = track.buffer(2)
def colorize_state(geometry):
facecolor = (0.9375, 0.9375, 0.859375)
if geometry.intersects(track):
facecolor = 'red'
elif geometry.intersects(track_buffer):
facecolor = '#FF7E00'
return {'facecolor': facecolor, 'edgecolor': 'black'}
ax.add_geometries(
shpreader.Reader(states_shp).geometries(),
ccrs.PlateCarree(),
styler=colorize_state)
ax.add_geometries([track_buffer], ccrs.PlateCarree(),
facecolor='#C8A2C8', alpha=0.5)
ax.add_geometries([track], ccrs.PlateCarree(),
facecolor='none', edgecolor='k')
# make two proxy artists to add to a legend
direct_hit = mpatches.Rectangle((0, 0), 1, 1, facecolor="red")
within_2_deg = mpatches.Rectangle((0, 0), 1, 1, facecolor="#FF7E00")
labels = ['State directly intersects\nwith track',
'State is within \n2 degrees of track']
ax.legend([direct_hit, within_2_deg], labels,
loc='lower left', bbox_to_anchor=(0.025, -0.1), fancybox=True)
plt.show()

Why use Cartopy?
Whether you're working in oceanography, environmental science, navigation, or any field that requires geographic data visualization, Cartopy offers the flexibility and precision needed to create high-quality maps with ease.
Cartopy is the ideal python library for advanced map projections of high quality due to its accuracy and integration with other libraries. It provides you a lot of in-built features which makes mapping easier and user-friendly. Cartopy is especially used for large areas/small scale data where the spherical data usually breaks down. It is preferred by meteorologist and climatologist for scientific purposes.
References
Official DocumentationPlotting with Cartopy and Geopandas