proplot: Slower speed of saving plotted Geographic data with cartopy
Description
I’m plotting large datasets using proplot (0.9.5.post78) and cartopy (0.20.0). The speed is much slower than the pyplot one.
Steps to reproduce
import time
import numpy as np
import proplot as pplt
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')
offset = -40
lon = np.linspace(offset, 360 + offset - 1, 3000)
lat = np.linspace(-60, 60 + 1, 500)
state = np.random.RandomState(51423)
data = state.rand(len(lat), len(lon))
def proplot_test():
start = time.time()
fig, axs = pplt.subplots(proj='stere', figsize=(4,4))
axs.coastlines()
axs.pcolormesh(lon, lat, data, cmap='viridis')
end = time.time()
print('proplot plot cost: ', end - start)
fig.savefig('test_proplot.jpg', dpi=300)
save_end = time.time()
print('proplot save cost: ', save_end - end)
def pyplot_test():
start = time.time()
fig, ax = plt.subplots(figsize=(4,4), subplot_kw=dict(projection=ccrs.Stereographic()))
ax.coastlines()
ax.pcolormesh(lon, lat, data, cmap='viridis', transform=ccrs.PlateCarree())
end = time.time()
print('pyplot plot cost: ', end - start)
fig.savefig('test_pyplot.jpg', dpi=300)
save_end = time.time()
print('pyplot save cost: ', save_end - end)
proplot_test()
pyplot_test()
Expected behavior: [What you expected to happen]
The speed is similar with pyplot.
Actual behavior: [What actually happened]
proplot plot cost: 2.1709158420562744
proplot save cost: 5.2430949211120605
pyplot plot cost: 1.9175093173980713
pyplot save cost: 1.4209530353546143
In jupyterlab, the cost of plotting data by proplot is 7s while the pyplot one is 3.7s. I suppose this is the same problem of saving figures, because jupyter notebook needs to show the figure inline.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 17
Commits related to this issue
- Significantly faster tight layout calc (see #306) This follows issue #306 discussion to significantly improve performance when plotting extremely high-resolution datasets under default auto layout co... — committed to proplot-dev/proplot by lukelbd 3 years ago
- Simplify tight layout improvement (see #306) — committed to proplot-dev/proplot by lukelbd 3 years ago
Ok cool. Yep in your first example cartopy wasn’t having to transform anything at all (because the default is native map coordinates rather than longitude-latitude), so it was faster. Keep in mind proplot’s only dependency is
matplotlib
(no specific version) so yourproj
version differences aren’t due to proplot – something else is going on.I also figured out that the speedup shown above is only relevant for cartopy plots. This fix seems obvious because it is obvious – matplotlib’s
Axes.get_tightbbox()
already skips artists that are bounded by the subplot edge, however its method for skipping them (for some reason) fails with cartopy artists, while my method (for some reason) succeeds. May submit a cartopy PR at some point. Relevant lines:https://github.com/matplotlib/matplotlib/blob/9765379ce6e7343070e815afc0988874041b98e2/lib/matplotlib/axes/_base.py#L4646-L4657
Great! Not so much a “bug” just a limitation of how “tight layout” is calculated – in order to get the positions of every object in the subplot (and, thus, ensure the subplots are sufficiently separated to prevent overlapping content), we have to draw every object in the subplot. Then, in order to save or display the figure, we have to draw the objects again using the relevant backend. However, it could probably be massively improved by skipping objects that are “clipped” by the subplot edges (i.e., skipping objects with
obj.get_clip_on()
set toTrue
). I’ll experiment with this for the next version.