8000 Merge pull request #13503 from meeseeksmachine/auto-backport-of-pr-10… · matplotlib/matplotlib@20f54aa · GitHub
[go: up one dir, main page]

Skip to content

Commit 20f54aa

Browse files
authored
Merge pull request #13503 from meeseeksmachine/auto-backport-of-pr-10776-on-v3.1.x
Backport PR #10776 on branch v3.1.x (fix FancyArrowPatch picker fails depending on arrowstyle)
2 parents aa32430 + d54e0bc commit 20f54aa

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

138147
def contains_point(self, point, radius=None):
139148
"""
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+
ax.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