proplot-dev / proplot

🎨 A succinct matplotlib wrapper for making beautiful, publication-quality graphics
https://proplot.readthedocs.io
MIT License
1.11k stars 102 forks source link

Can not add patch in every axes #398

Closed jwy-wbe closed 1 year ago

jwy-wbe commented 1 year ago

Description

I try to draw the Nino3 area in every axes, BUT here it is the Error:"ValueError: Can not reset the axes. You are probably trying to re-use an artist in more than one Axes which is not supported". The nino3 area is only drawn on the first axs. so How can i fix this? Thanks a lot.

image

Here is the code for add patch:

from matplotlib.path import Path
from matplotlib.patches import PathPatch
codes = [Path.MOVETO] + [Path.LINETO]*3 + [Path.CLOSEPOLY]
vertices = [(210,-5), (210,5), (270,5), (270,-5), (0, 0)]
path = Path(vertices, codes)
pathpatch = PathPatch(path, facecolor='none', edgecolor='k',lw=1.5,label='Nino3',transform = ccrs.PlateCarree(),alpha = 0.6)
axs[0].add_patch(pathpatch)
axs[1].add_patch(pathpatch)
axs[2].add_patch(pathpatch)

Proplot version

0.9.5.post332

664787022 commented 1 year ago

Hi, I got the same problem as you. The solution is creating pathpatch everytime before add_patch. For example,

from matplotlib.path import Path
from matplotlib.patches import PathPatch
import cartopy.crs as ccrs
import proplot as pplt

fig, axs = pplt.subplots(ncols=3,proj='cyl')
codes = [Path.MOVETO] + [Path.LINETO]*3 + [Path.CLOSEPOLY]
vertices = [(210,-5), (210,5), (270,5), (270,-5), (0, 0)]
path = Path(vertices, codes)

pathpatch = PathPatch(path, facecolor='none', edgecolor='k',lw=1.5,label='Nino3',transform = ccrs.PlateCarree(),alpha = 0.6)
axs[0].add_patch(pathpatch)

pathpatch = PathPatch(path, facecolor='none', edgecolor='k',lw=1.5,label='Nino3',transform = ccrs.PlateCarree(),alpha = 0.6)
axs[1].add_patch(pathpatch)

pathpatch = PathPatch(path, facecolor='none', edgecolor='k',lw=1.5,label='Nino3',transform = ccrs.PlateCarree(),alpha = 0.6)
axs[2].add_patch(pathpatch)
jwy-wbe commented 1 year ago

Hi, I got the same problem with you. The solution is creating pathpatch everytime before add_patch. For example,

from matplotlib.path import Path
from matplotlib.patches import PathPatch
import cartopy.crs as ccrs
import proplot as pplt

fig, axs = pplt.subplots(ncols=3,proj='cyl')
codes = [Path.MOVETO] + [Path.LINETO]*3 + [Path.CLOSEPOLY]
vertices = [(210,-5), (210,5), (270,5), (270,-5), (0, 0)]
path = Path(vertices, codes)

pathpatch = PathPatch(path, facecolor='none', edgecolor='k',lw=1.5,label='Nino3',transform = ccrs.PlateCarree(),alpha = 0.6)
axs[0].add_patch(pathpatch)

pathpatch = PathPatch(path, facecolor='none', edgecolor='k',lw=1.5,label='Nino3',transform = ccrs.PlateCarree(),alpha = 0.6)
axs[1].add_patch(pathpatch)

pathpatch = PathPatch(path, facecolor='none', edgecolor='k',lw=1.5,label='Nino3',transform = ccrs.PlateCarree(),alpha = 0.6)
axs[2].add_patch(pathpatch)

Thanks a lot! I will try it later!

L1angY commented 1 year ago

I cant answer why "Can not add patch in every axes". BUT, maybe I can give you a solution. Actually, you can use ax.plot() to draw area box (plot line). For example: ax1.plot([210, 270, 270, 210, 210], [-5, -5, 5, 5, -5], c='r', linestyle='-')

jwy-wbe commented 1 year ago

I cant answer why "Can not add patch in every axes". BUT, maybe I can give you a solution. Actually, you can use ax.plot() to draw area box (plot line). For example: ax1.plot([210, 270, 270, 210, 210], [-5, -5, 5, 5, -5], c='r', linestyle='-')

Thanks, I will try it later

lukelbd commented 1 year ago

This is a matplotlib limitation -- artists have to be duplicated when adding to multiple axes. I think copying the artist before adding to other axes with copy.copy(pathpatch) (and adding import copy to your imports) would also work.