Quantcast
Channel: Active questions tagged python - Stack Overflow
Viewing all articles
Browse latest Browse all 14155

cache or reuse cartopy features

$
0
0

I'm using Cartopy to display the GSHHSFeature coastlines in multiple Matplotlib subplots and overlay different data on them.

import matplotlib.pyplot as pltimport cartopy.crs as ccrsimport cartopy.feature as cfeatureimport numpy as npxss = np.linspace(-21, 36, 36)extent = [-21, 36, 33, 64]  # west,east,south,northrows=3cols=2fig, ax = plt.subplots(nrows=rows, ncols=cols, figsize=(13, 15),                        subplot_kw={'projection': ccrs.PlateCarree()})for i in range(rows):    for j in range(cols):        ax[i][j].set_extent(extent)        ax[i][j].add_feature(cfeature.GSHHSFeature(scale="intermediate", edgecolor="black", facecolor="#bca89f"))        # Plot individual data sets on subplots        ax[i][j].plot(xss, np.random.uniform(low=33, high=64, size=(len(xss),)), color='cyan', zorder=20, transform=ccrs.PlateCarree(), linewidth=2)        # Write map title        ax[i][j].set_title("Row:"+str(i)+", Col:"+str(j))plt.tight_layout()plt.show()

Drawing the coastlines is a time consuming operation, particularly when using a ‘full’ dataset scale. Since the basemap is the same in each subplot, I was looking for ways to create it only once and reuse it in the loop.

Is there a way I can either cache the feature or even the entire subplot axis and define functions like ax[i][j].plot_my_basemap(map_ax) or ax[i][j] = copy_axis_from(map_ax)?

# Create a plot axes of choicemap_ax = plt.axes(projection=ccrs.PlateCarree())map_ax.set_extent(extentd)# Request and process the basemap featuresmap_ax.add_feature(cfeature.GSHHSFeature(scale="intermediate", edgecolor="black", facecolor="#bca89f"))fig, ax = plt.subplots(nrows=3, ncols=2, figsize=(13, 15),                        subplot_kw={'projection': ccrs.PlateCarree()})for i in range(rows):    for j in range(cols):        ax[i][j].plot_my_basemap(map_ax)        # Plot individual data sets on subplots        ax[i][j].plot(xss, np.random.uniform(low=33, high=64, size=(len(xss),)), color='cyan', zorder=20, transform=ccrs.PlateCarree(), linewidth=2)        # Write map title        ax[i][j].set_title("Row:"+str(i)+", Col:"+str(j))plt.tight_layout()plt.show()

The answer to this question (from which I adapted my example) shows how to do it with Google tiled images, but this approach doesn't work in my case because the coastlines are not image objects, but cartopy.mpl.feature_artist.FeatureArtist.

I also tried to reuse directly map_ax, change its properties and assign it to the subplots, but this doesn't work in matplotlib:

for i in range(rows):    for j in range(cols):        props = ax[i][j].properties()        props = dict((k, props[k]) for k in ["position", "subplotspec"])        ax[i][j] = map_ax.update(props)        # Plot individual data sets on subplots        ax[i][j].plot(xss, np.random.uniform(low=33, high=64, size=(len(xss),)), color='cyan', zorder=20, transform=ccrs.PlateCarree(), linewidth=2)        # Write map title        ax[i][j].set_title("Row:"+str(i)+", Col:"+str(j))

I was hoping to be able to define and reuse something like Basemap objects https://github.com/matplotlib/basemap/issues/354 (but I don't want to use Basemap because it's going to be substituted by Cartopy and it has already compatibility issues with Matplotlib 3.8)


Viewing all articles
Browse latest Browse all 14155

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>