diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 5354d8fd79f2..770da8142ea8 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -687,7 +687,8 @@ def text(self, x, y, s, fontdict=None, **kwargs): **kwargs, } t = mtext.Text(x, y, text=s, **effective_kwargs) - t.set_clip_path(self.patch) + if t.get_clip_path() is None: + t.set_clip_path(self.patch) self._add_text(t) return t @@ -700,7 +701,7 @@ def annotate(self, text, xy, xytext=None, xycoords='data', textcoords=None, textcoords=textcoords, arrowprops=arrowprops, annotation_clip=annotation_clip, **kwargs) a.set_transform(mtransforms.IdentityTransform()) - if 'clip_on' in kwargs: + if kwargs.get('clip_on', False) and a.get_clip_path() is None: a.set_clip_path(self.patch) self._add_text(a) return a diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index 7893d7434f0d..189b15634c2c 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -2218,7 +2218,8 @@ def add_artist(self, a): self._children.append(a) a._remove_method = self._children.remove self._set_artist_props(a) - a.set_clip_path(self.patch) + if a.get_clip_path() is None: + a.set_clip_path(self.patch) self.stale = True return a @@ -2426,7 +2427,8 @@ def add_table(self, tab): _api.check_isinstance(mtable.Table, tab=tab) self._set_artist_props(tab) self._children.append(tab) - tab.set_clip_path(self.patch) + if tab.get_clip_path() is None: + tab.set_clip_path(self.patch) tab._remove_method = self._children.remove return tab diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index 04b1f5dfa727..8f2e2566577e 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -508,7 +508,7 @@ def add_artist(self, artist, clip=False): if not artist.is_transform_set(): artist.set_transform(self.transSubfigure) - if clip: + if clip and artist.get_clip_path() is None: artist.set_clip_path(self.patch) self.stale = True diff --git a/lib/matplotlib/patheffects.py b/lib/matplotlib/patheffects.py index a2014aa52df0..b0b8aea74d43 100644 --- a/lib/matplotlib/patheffects.py +++ b/lib/matplotlib/patheffects.py @@ -368,7 +368,7 @@ def draw_path(self, renderer, gc, tpath, affine, rgbFace): self.patch.set_transform(affine + self._offset_transform(renderer)) self.patch.set_clip_box(gc.get_clip_rectangle()) clip_path = gc.get_clip_path() - if clip_path: + if clip_path and self.patch.get_clip_path() is None: self.patch.set_clip_path(*clip_path) self.patch.draw(renderer) diff --git a/lib/matplotlib/tests/baseline_images/test_axes/preset_clip_paths.png b/lib/matplotlib/tests/baseline_images/test_axes/preset_clip_paths.png new file mode 100644 index 000000000000..0b60b60f4849 Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_axes/preset_clip_paths.png differ diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index c8e1f53465f2..ee3af7382e50 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -18,7 +18,7 @@ import matplotlib import matplotlib as mpl -from matplotlib import rc_context +from matplotlib import rc_context, patheffects from matplotlib._api import MatplotlibDeprecationWarning import matplotlib.colors as mcolors import matplotlib.dates as mdates @@ -8455,6 +8455,43 @@ def test_zorder_and_explicit_rasterization(): fig.savefig(b, format='pdf') +@image_comparison(["preset_clip_paths.png"], remove_text=True, style="mpl20") +def test_preset_clip_paths(): + fig, ax = plt.subplots() + + poly = mpl.patches.Polygon( + [[1, 0], [0, 1], [-1, 0], [0, -1]], facecolor="#ddffdd", + edgecolor="#00ff00", linewidth=2, alpha=0.5) + + ax.add_patch(poly) + + line = mpl.lines.Line2D((-1, 1), (0.5, 0.5), clip_on=True, clip_path=poly) + line.set_path_effects([patheffects.withTickedStroke()]) + ax.add_artist(line) + + line = mpl.lines.Line2D((-1, 1), (-0.5, -0.5), color='r', clip_on=True, + clip_path=poly) + ax.add_artist(line) + + poly2 = mpl.patches.Polygon( + [[-1, 1], [0, 1], [0, -0.25]], facecolor="#beefc0", alpha=0.3, + edgecolor="#faded0", linewidth=2, clip_on=True, clip_path=poly) + ax.add_artist(poly2) + + # When text clipping works, the "Annotation" text should be clipped + ax.annotate('Annotation', (-0.75, -0.75), xytext=(0.1, 0.75), + arrowprops={'color': 'k'}, clip_on=True, clip_path=poly) + + poly3 = mpl.patches.Polygon( + [[0, 0], [0, 0.5], [0.5, 0.5], [0.5, 0]], facecolor="g", edgecolor="y", + linewidth=2, alpha=0.3, clip_on=True, clip_path=poly) + + fig.add_artist(poly3, clip=True) + + ax.set_xlim(-1, 1) + ax.set_ylim(-1, 1) + + @mpl.style.context('default') def test_rc_axes_label_formatting(): mpl.rcParams['axes.labelcolor'] = 'red'