Note
Click here to download the full example code
Converting between GeoPandas and CartoPy for visualizing data.
CartoPy is a Python library that specializes in creating geospatial visualizations. It has a slightly different way of representing Coordinate Reference Systems (CRS) as well as constructing plots. This example steps through a round-trip transfer of data between GeoPandas and CartoPy.
First we’ll load in the data using GeoPandas.
# sphinx_gallery_thumbnail_number = 7 import matplotlib.pyplot as plt import geopandas from cartopy import crs as ccrs path = geopandas.datasets.get_path('naturalearth_lowres') df = geopandas.read_file(path) # Add a column we'll use later df['gdp_pp'] = df['gdp_md_est'] / df['pop_est']
First we’ll visualize the map using GeoPandas
df.plot()
Cartopy also handles Shapely objects well, but it uses a different system for CRS. To plot this data with CartoPy, we’ll first need to project it into a new CRS. We’ll use a CRS defined within CartoPy and use the GeoPandas to_crs method to make the transformation.
to_crs
# Define the CartoPy CRS object. crs = ccrs.AzimuthalEquidistant() # This can be converted into a `proj4` string/dict compatible with GeoPandas crs_proj4 = crs.proj4_init df_ae = df.to_crs(crs_proj4) # Here's what the plot looks like in GeoPandas df_ae.plot()
Now that our data is in a CRS based off of CartoPy, we can easily plot it.
fig, ax = plt.subplots(subplot_kw={'projection': crs}) ax.add_geometries(df_ae['geometry'], crs=crs)
Note that we could have easily done this with an EPSG code like so:
crs_epsg = ccrs.epsg('3857') df_epsg = df.to_crs(epsg='3857') # Generate a figure with two axes, one for CartoPy, one for GeoPandas fig, axs = plt.subplots(1, 2, subplot_kw={'projection': crs_epsg}, figsize=(10, 5)) # Make the CartoPy plot axs[0].add_geometries(df_epsg['geometry'], crs=crs_epsg, facecolor='white', edgecolor='black') # Make the GeoPandas plot df_epsg.plot(ax=axs[1], color='white', edgecolor='black')
Next we’ll perform a CRS projection in CartoPy, and then convert it back into a GeoPandas object.
crs_new = ccrs.AlbersEqualArea() new_geometries = [crs_new.project_geometry(ii, src_crs=crs) for ii in df_ae['geometry'].values] fig, ax = plt.subplots(subplot_kw={'projection': crs_new}) ax.add_geometries(new_geometries, crs=crs_new)
Now that we’ve created new Shapely objects with the CartoPy CRS, we can use this to create a GeoDataFrame.
df_aea = geopandas.GeoDataFrame(df['gdp_pp'], geometry=new_geometries, crs=crs_new.proj4_init) df_aea.plot()
We can even combine these into the same figure. Here we’ll plot the shapes of the countries with CartoPy. We’ll then calculate the centroid of each with GeoPandas and plot it on top.
# Generate a CartoPy figure and add the countries to it fig, ax = plt.subplots(subplot_kw={'projection': crs_new}) ax.add_geometries(new_geometries, crs=crs_new) # Calculate centroids and plot df_aea_centroids = df_aea.geometry.centroid # Need to provide "zorder" to ensure the points are plotted above the polygons df_aea_centroids.plot(ax=ax, markersize=5, color='r', zorder=10) plt.show()
Total running time of the script: ( 0 minutes 2.390 seconds)
Gallery generated by Sphinx-Gallery