From 15eb7e70dcced7bf818d9a94df6860b3e43eb9e7 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Mon, 16 Jan 2017 11:48:59 -0800 Subject: [PATCH 1/2] Fix containment test with nonlinear transforms. --- lib/matplotlib/path.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/matplotlib/path.py b/lib/matplotlib/path.py index 58e984d2cc5d..71ec9358b810 100644 --- a/lib/matplotlib/path.py +++ b/lib/matplotlib/path.py @@ -22,9 +22,8 @@ import numpy as np -from matplotlib import _path -from matplotlib.cbook import simple_linear_interpolation, maxdict -from matplotlib import rcParams +from . import _path, rcParams +from .cbook import simple_linear_interpolation, maxdict class Path(object): @@ -493,9 +492,14 @@ def contains_point(self, point, transform=None, radius=0.0): """ if transform is not None: transform = transform.frozen() - result = _path.point_in_path(point[0], point[1], radius, self, - transform) - return result + # `point_in_path` does not handle nonlinear transforms, so we + # transform the path ourselves. If `transform` is affine, letting + # `point_in_path` handle the transform avoids allocating an extra + # buffer. + if transform and not transform.is_affine: + self = transform.transform_path(self) + transform = None + return _path.point_in_path(point[0], point[1], radius, self, transform) def contains_points(self, points, transform=None, radius=0.0): """ From 76173e1aae1a6f92e0e0deba00cd156edfa6ba83 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Sat, 28 Jan 2017 13:36:51 -0800 Subject: [PATCH 2/2] Test path containment w/ nonlin. transforms; group containment tests. --- lib/matplotlib/tests/test_path.py | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/lib/matplotlib/tests/test_path.py b/lib/matplotlib/tests/test_path.py index 71fcb7c89bc7..1b1345af8466 100644 --- a/lib/matplotlib/tests/test_path.py +++ b/lib/matplotlib/tests/test_path.py @@ -45,6 +45,27 @@ def test_contains_points_negative_radius(): assert np.all(result == expected) +def test_point_in_path_nan(): + box = np.array([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]) + p = Path(box) + test = np.array([[np.nan, 0.5]]) + contains = p.contains_points(test) + assert len(contains) == 1 + assert not contains[0] + + +def test_nonlinear_containment(): + fig, ax = plt.subplots() + ax.set(xscale="log", ylim=(0, 1)) + polygon = ax.axvspan(1, 10) + assert polygon.get_path().contains_point( + ax.transData.transform_point((5, .5)), ax.transData) + assert not polygon.get_path().contains_point( + ax.transData.transform_point((.5, .5)), ax.transData) + assert not polygon.get_path().contains_point( + ax.transData.transform_point((50, .5)), ax.transData) + + @image_comparison(baseline_images=['path_clipping'], extensions=['svg'], remove_text=True) def test_path_clipping(): @@ -66,15 +87,6 @@ def test_path_clipping(): xy, facecolor='none', edgecolor='red', closed=True)) -def test_point_in_path_nan(): - box = np.array([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]) - p = Path(box) - test = np.array([[np.nan, 0.5]]) - contains = p.contains_points(test) - assert len(contains) == 1 - assert not contains[0] - - @image_comparison(baseline_images=['semi_log_with_zero'], extensions=['png']) def test_log_transform_with_zero(): x = np.arange(-10, 10)