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

Skip to content

Commit 81e2937

Browse files
zhoubeckydstansby
authored andcommitted
fix FancyArrowPatch picker fails depending on arrowstyle #8384 and update fix based on reviewers' suggestion
1 parent 7bcf618 commit 81e2937

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
@@ -130,9 +130,18 @@ def contains(self, mouseevent, radius=None):
130130
if callable(self._contains):
131131
return self._contains(self, mouseevent)
132132
radius = self._process_radius(radius)
133-
inside = self.get_path().contains_point(
134-
(mouseevent.x, mouseevent.y), self.get_transform(), radius)
135-
return inside, {}
133+
codes = self.get_path().codes
134+
vertices = self.get_path().vertices
135+
# if the current path is concatenated by multiple sub paths.
136+
# get the indexes of the starting code(MOVETO) of all sub paths
137+
idxs, = np.where(codes == 1)
138+
# Don't split before the first MOVETO.
139+
idxs = idxs[1:]
140+
return any(
141+
subpath.contains_point(
142+
(mouseevent.x, mouseevent.y), self.get_transform(), radius)
143+
for subpath in map(
144+
Path, np.split(vertices, idxs), np.split(codes, idxs))), {}
136145

137146
def contains_point(self, point, radius=None):
138147
"""
Loading

lib/matplotlib/tests/test_path.py

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

8+
from matplotlib import patches
89
from matplotlib.path import Path
910
from matplotlib.patches import Polygon
1011
from matplotlib.testing.decorators import image_comparison
1112
import matplotlib.pyplot as plt
1213
from matplotlib import transforms
14+
from matplotlib.backend_bases import MouseEvent
1315

1416

1517
def test_empty_closed_path():
@@ -70,6 +72,46 @@ def test_nonlinear_containment():
7072
ax.transData.transform_point((50, .5)), ax.transData)
7173

7274

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

0 commit comments

Comments
 (0)
0