Skip to content

Commit 458bde0

Browse files
committed
ENH: clip_path keyword for contour and contourf
1 parent a861b8a commit 458bde0

File tree

4 files changed

+45
-2
lines changed

4 files changed

+45
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Clipping for contour plots
2+
--------------------------
3+
4+
`~.Axes.contour` and `~.Axes.contourf` now accept the *clip_path* parameter.
5+
6+
.. plot::
7+
:include-source: true
8+
9+
import numpy as np
10+
import matplotlib.pyplot as plt
11+
import matplotlib.patches as mpatches
12+
13+
x = y = np.arange(-3.0, 3.01, 0.025)
14+
X, Y = np.meshgrid(x, y)
15+
Z1 = np.exp(-X**2 - Y**2)
16+
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
17+
Z = (Z1 - Z2) * 2
18+
19+
fig, ax = plt.subplots()
20+
patch = mpatches.RegularPolygon((0, 0), 5, radius=2,
21+
transform=ax.transData)
22+
ax.contourf(X, Y, Z, clip_path=patch)
23+
24+
plt.show()

lib/matplotlib/contour.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,7 @@ def __init__(self, ax, *args,
751751
hatches=(None,), alpha=None, origin=None, extent=None,
752752
cmap=None, colors=None, norm=None, vmin=None, vmax=None,
753753
extend='neither', antialiased=None, nchunk=0, locator=None,
754-
transform=None, negative_linestyles=None,
754+
transform=None, negative_linestyles=None, clip_path=None,
755755
**kwargs):
756756
"""
757757
Draw contour lines or filled regions, depending on
@@ -805,6 +805,7 @@ def __init__(self, ax, *args,
805805
super().__init__(
806806
antialiaseds=antialiased,
807807
alpha=alpha,
808+
clip_path=clip_path,
808809
transform=transform,
809810
)
810811
self.axes = ax
@@ -1870,6 +1871,11 @@ def _initialize_x_y(self, z):
18701871
18711872
The default is taken from :rc:`contour.algorithm`.
18721873
1874+
clip_path : `~matplotlib.patches.Patch` or `.Path` or `.TransformedPath`
1875+
Set the clip path. See `~matplotlib.artist.Artist.set_clip_path`.
1876+
1877+
.. versionadded:: 3.8
1878+
18731879
data : indexable object, optional
18741880
DATA_PARAMETER_PLACEHOLDER
18751881

lib/matplotlib/contour.pyi

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ from matplotlib.axes import Axes
44
from matplotlib.collections import Collection, PathCollection
55
from matplotlib.colors import Colormap, Normalize
66
from matplotlib.font_manager import FontProperties
7+
from matplotlib.path import Path
8+
from matplotlib.patches import Patch
79
from matplotlib.text import Text
8-
from matplotlib.transforms import Transform
10+
from matplotlib.transforms import Transform, TransformedPatchPath, TransformedPath
911
from matplotlib.ticker import Locator, Formatter
1012

1113
from numpy.typing import ArrayLike
@@ -99,6 +101,7 @@ class ContourSet(ContourLabeler, Collection):
99101
negative_linestyles: None | Literal[
100102
"solid", "dashed", "dashdot", "dotted"
101103
] | Iterable[Literal["solid", "dashed", "dashdot", "dotted"]]
104+
clip_path: Patch | Path | TransformedPath | TransformedPatchPath | None
102105
labelTexts: list[Text]
103106
labelCValues: list[ColorType]
104107
allkinds: list[np.ndarray]
@@ -145,6 +148,7 @@ class ContourSet(ContourLabeler, Collection):
145148
negative_linestyles: Literal["solid", "dashed", "dashdot", "dotted"]
146149
| Iterable[Literal["solid", "dashed", "dashdot", "dotted"]]
147150
| None = ...,
151+
clip_path: Patch | Path | TransformedPath | TransformedPatchPath | None = ...,
148152
**kwargs
149153
) -> None: ...
150154
def legend_elements(

lib/matplotlib/tests/test_contour.py

+9
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import matplotlib as mpl
1010
from matplotlib import pyplot as plt, rc_context, ticker
1111
from matplotlib.colors import LogNorm, same_color
12+
import matplotlib.patches as mpatches
1213
from matplotlib.testing.decorators import image_comparison
1314
import pytest
1415

@@ -752,6 +753,14 @@ def test_contour_no_args():
752753
ax.contour(Z=data)
753754

754755

756+
def test_contour_clip_path():
757+
fig, ax = plt.subplots()
758+
data = [[0, 1], [1, 0]]
759+
circle = mpatches.Circle([0.5, 0.5], 0.5, transform=ax.transAxes)
760+
cs = ax.contour(data, clip_path=circle)
761+
assert cs.get_clip_path() is not None
762+
763+
755764
def test_bool_autolevel():
756765
x, y = np.random.rand(2, 9)
757766
z = (np.arange(9) % 2).reshape((3, 3)).astype(bool)

0 commit comments

Comments
 (0)