Skip to content

Commit 0611b61

Browse files
authored
Merge pull request #7844 from anntzer/nonlinear-transformed-path-containment
Fix containment test with nonlinear transforms.
2 parents f238c58 + 76173e1 commit 0611b61

File tree

2 files changed

+31
-15
lines changed

2 files changed

+31
-15
lines changed

lib/matplotlib/path.py

+10-6
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,8 @@
2222

2323
import numpy as np
2424

25-
from matplotlib import _path
26-
from matplotlib.cbook import simple_linear_interpolation, maxdict
27-
from matplotlib import rcParams
25+
from . import _path, rcParams
26+
from .cbook import simple_linear_interpolation, maxdict
2827

2928

3029
class Path(object):
@@ -493,9 +492,14 @@ def contains_point(self, point, transform=None, radius=0.0):
493492
"""
494493
if transform is not None:
495494
transform = transform.frozen()
496-
result = _path.point_in_path(point[0], point[1], radius, self,
497-
transform)
498-
return result
495+
# `point_in_path` does not handle nonlinear transforms, so we
496+
# transform the path ourselves. If `transform` is affine, letting
497+
# `point_in_path` handle the transform avoids allocating an extra
498+
# buffer.
499+
if transform and not transform.is_affine:
500+
self = transform.transform_path(self)
501+
transform = None
502+
return _path.point_in_path(point[0], point[1], radius, self, transform)
499503

500504
def contains_points(self, points, transform=None, radius=0.0):
501505
"""

lib/matplotlib/tests/test_path.py

+21-9
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,27 @@ def test_contains_points_negative_radius():
4545
assert np.all(result == expected)
4646

4747

48+
def test_point_in_path_nan():
49+
box = np.array([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]])
50+
p = Path(box)
51+
test = np.array([[np.nan, 0.5]])
52+
contains = p.contains_points(test)
53+
assert len(contains) == 1
54+
assert not contains[0]
55+
56+
57+
def test_nonlinear_containment():
58+
fig, ax = plt.subplots()
59+
ax.set(xscale="log", ylim=(0, 1))
60+
polygon = ax.axvspan(1, 10)
61+
assert polygon.get_path().contains_point(
62+
ax.transData.transform_point((5, .5)), ax.transData)
63+
assert not polygon.get_path().contains_point(
64+
ax.transData.transform_point((.5, .5)), ax.transData)
65+
assert not polygon.get_path().contains_point(
66+
ax.transData.transform_point((50, .5)), ax.transData)
67+
68+
4869
@image_comparison(baseline_images=['path_clipping'],
4970
extensions=['svg'], remove_text=True)
5071
def test_path_clipping():
@@ -66,15 +87,6 @@ def test_path_clipping():
6687
xy, facecolor='none', edgecolor='red', closed=True))
6788

6889

69-
def test_point_in_path_nan():
70-
box = np.array([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]])
71-
p = Path(box)
72-
test = np.array([[np.nan, 0.5]])
73-
contains = p.contains_points(test)
74-
assert len(contains) == 1
75-
assert not contains[0]
76-
77-
7890
@image_comparison(baseline_images=['semi_log_with_zero'], extensions=['png'])
7991
def test_log_transform_with_zero():
8092
x = np.arange(-10, 10)

0 commit comments

Comments
 (0)