Search code examples
performanceclippingcartopy

Speeding up high-res coastline plotting with Cartopy


I would like to speedup the execution of this code:

import cartopy.crs as ccrs
from cartopy.feature import NaturalEarthFeature
import matplotlib.pyplot as plt

# the extent in the original code is calculated on the fly
extent = [0, 50, 20, 60]

plt.figure("Test Map")
ax = plt.subplot(111, projection=ccrs.PlateCarree())
ax.set_extent(extent, crs=ccrs.PlateCarree())

ax.add_feature(NaturalEarthFeature('physical', 'ocean', '50m'))

plt.show()

The code currently takes a few seconds to visualize the resulting plot. When I pan in the resulting plot, I can see that cartopy has actually plotted all the polygons! Does cartopy have any clipping functionality?


Solution

  • The short answer is that no, CartoPy does not have any built-in clipping operations. However, Shapely, which CartoPy uses, does.

    I'm guessing the performance issues you're seeing are somewhere in your own plot. The code you posted runs in ~45ms on my system. Here's an example where you can use Shapely to compute the intersection of the map feature with the extent box.

    import cartopy.crs as ccrs
    from cartopy.feature import NaturalEarthFeature
    import matplotlib.pyplot as plt
    import shapely.geometry as sgeom
    
    # the extent in the original code is calculated on the fly
    extent = [0, 50, 20, 60]
    
    feat = NaturalEarthFeature('physical', 'ocean', '50m')
    box = sgeom.box(extent[0], extent[2], extent[1], extent[3])
    geoms = [geom.intersection(box) for geom in feat.geometries()]
    
    plt.figure("Test Map")
    ax = plt.subplot(111, projection=ccrs.PlateCarree())
    ax.set_extent(extent, crs=ccrs.PlateCarree())
    
    ax.add_geometries(geoms, crs=ccrs.PlateCarree())
    
    plt.show()
    

    This example actually runs slower (~97ms) for me though.