8000 fix FancyArrowPatch picker fails depending on arrowstyle #8384 and up… · matplotlib/matplotlib@28bc4f8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 28bc4f8

Browse files
committed
fix FancyArrowPatch picker fails depending on arrowstyle #8384 and update fix based on reviewers' suggestion
1 parent 8bc52ad commit 28bc4f8

File tree

3 files changed

+54
-3
lines changed

3 files changed

+54
-3
lines changed

lib/matplotlib/patches.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,18 @@ def contains(self, mouseevent, radius=None):
138138
if callable(self._contains):
139139
return self._contains(self, mouseevent)
140140
radius = self._process_radius(radius)
141-
inside = self.get_path().contains_point(
142-
(mouseevent.x, mouseevent.y), self.get_transform(), radius)
143-
return inside, {}
141+
codes = self.get_path().codes
142+
vertices = self.get_path().vertices
143+
# if the current path is concatenated by multiple sub paths.
144+
# get the indexes of the starting code(MOVETO) of all sub paths
145+
idxs, = np.where(codes == 1)
146+
# Don't split before the first MOVETO.
147+
idxs = idxs[1:]
148+
return any(
149+
subpath.contains_point(
150+
(mouseevent.x, mouseevent.y), self.get_transform(), radius)
151+
for subpath in map(
152+
Path, np.split(vertices, idxs), np.split(codes, idxs))), {}
144153

145154
def contains_point(self, point, radius=None):
146155
"""
Loading

lib/matplotlib/tests/test_path.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
from numpy.testing import assert_array_equal
77
import pytest
88

9+
from matplotlib import patches
910
from matplotlib.path import Path
1011
from matplotlib.patches import Polygon
1112
from matplotlib.testing.decorators import image_comparison
1213
import matplotlib.pyplot as plt
1314
from matplotlib import transforms
15+
from matplotlib.backend_bases import MouseEvent
1416

1517

1618
def test_readonly_path():
@@ -65,6 +67,46 @@ def test_nonlinear_containment():
6567
ax.transData.transform_point((50, .5)), ax.transData)
6668

6769

70+
@image_comparison(
71+
baseline_images=['arrow_contains_point'], extensions=['png'],
72+
remove_text=True, style='mpl20')
73+
def test_arrow_contains_point():
74+
# fix bug (#8384)
75+
fig, ax = plt.subplots()
76+
ax.set_xlim((0, 2))
77+
ax.set_ylim((0, 2))
78+
79+
# create an arrow with Curve style
80+
arrow = patches.FancyArrowPatch((0.5, 0.25), (1.5, 0.75),
81+
arrowstyle='->',
82+
mutation_scale=40)
83+
ax.add_patch(arrow)
84+
# create an arrow with Bracket style
85+
arrow1 = patches.FancyArrowPatch((0.5, 1), (1.5, 1.25),
86+
arrowstyle=']-[',
87+
mutation_scale=40)
88+
ax.add_patch(arrow1)
89+
# create an arrow with other arrow style
90+
arrow2 = patches.FancyArrowPatch((0.5, 1.5), (1.5, 1.75),
91+
arrowstyle='fancy',
92+
fill=False,
93+
mutation_scale=40)
94+
ax.add_patch(arrow2)
95+
patches_list = [arrow, arrow1, arrow2]
96+
97+
# generate some points
98+
X, Y = np.meshgrid(np.arange(0, 2, 0.1),
99+
np.arange(0, 2, 0.1))
100+
for k, (x, y) in enumerate(zip(X.ravel(), Y.ravel())):
101+
xdisp, ydisp = ax.transData.transform_point([x, y])
102+
event = MouseEvent('button_press_event', fig.canvas, xdisp, ydisp)
103+
for m, patch in enumerate(patches_list):
104+
# set the points to red only if the arrow contains the point
105+
inside, res = patch.contains(event)
106+
if inside:
107+
plt.scatter(x, y, s=5, c="r")
108+
109+
68110
@image_comparison(baseline_images=['path_clipping'],
69111
extensions=['svg'], remove_text=True)
70112
def test_path_clipping():

0 commit comments

Comments
 (0)
0