Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c582fa1

Browse filesBrowse files
committed
axes_grid1: add host/parasite axes pick methods
Fixes #5581
1 parent 121102b commit c582fa1
Copy full SHA for c582fa1

File tree

Expand file treeCollapse file tree

2 files changed

+78
-0
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+78
-0
lines changed

‎lib/mpl_toolkits/axes_grid1/parasite_axes.py

Copy file name to clipboardExpand all lines: lib/mpl_toolkits/axes_grid1/parasite_axes.py
+19Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,18 @@ def cla(self):
3636
self.xaxis.set_zorder(2.5)
3737
self.yaxis.set_zorder(2.5)
3838

39+
def pick(self, mouseevent):
40+
# This most likely goes to Artist.pick (depending on axes_class given
41+
# to the factory), which only handles pick events registered on the
42+
# axes associated with each child:
43+
super().pick(mouseevent)
44+
# But parasite axes are additionally given pick events from their host
45+
# axes (cf. HostAxesBase.pick), which we handle here:
46+
for a in self.get_children():
47+
if (hasattr(mouseevent.inaxes, "parasites")
48+
and self in mouseevent.inaxes.parasites):
49+
a.pick(mouseevent)
50+
3951

4052
@functools.lru_cache(None)
4153
def parasite_axes_class_factory(axes_class=None):
@@ -232,6 +244,13 @@ def cla(self):
232244
ax.cla()
233245
super().cla()
234246

247+
def pick(self, mouseevent):
248+
super().pick(mouseevent)
249+
# Also pass pick events on to parasite axes and, in turn, their
250+
# children (cf. ParasiteAxesBase.pick)
251+
for a in self.parasites:
252+
a.pick(mouseevent)
253+
235254
def twinx(self, axes_class=None):
236255
"""
237256
create a twin of Axes for generating a plot with a sharex

‎lib/mpl_toolkits/tests/test_axes_grid1.py

Copy file name to clipboardExpand all lines: lib/mpl_toolkits/tests/test_axes_grid1.py
+59Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
AnchoredSizeBar,
1818
AnchoredDirectionArrows)
1919

20+
from matplotlib.backend_bases import MouseEvent
2021
from matplotlib.colors import LogNorm
2122
from matplotlib.transforms import Bbox, TransformedBbox
2223
from itertools import product
@@ -422,3 +423,61 @@ def test_gettightbbox():
422423
bbox = fig.get_tightbbox(fig.canvas.get_renderer())
423424
np.testing.assert_array_almost_equal(bbox.extents,
424425
[-17.7, -13.9, 7.2, 5.4])
426+
427+
428+
@pytest.mark.parametrize("click_on", ["big", "small"])
429+
@pytest.mark.parametrize("big_on_axes,small_on_axes", [
430+
("gca", "gca"),
431+
("host", "host"),
432+
("host", "parasite"),
433+
("parasite", "host"),
434+
("parasite", "parasite")
435+
])
436+
def test_picking_callbacks_overlap(big_on_axes, small_on_axes, click_on):
437+
"""Test pick events on normal, host or parasite axes."""
438+
# Two rectangles are drawn and "clicked on", a small one and a big one
439+
# enclosing the small one. The axis on which they are drawn as well as the
440+
# rectangle that is clicked on are varied.
441+
# In each case we expect that both rectangles are picked if we click on the
442+
# small one and only the big one is picked if we click on the big one.
443+
# Also tests picking on normal axes ("gca") as a control.
444+
big = plt.Rectangle((0.25, 0.25), 0.5, 0.5, picker=5)
445+
small = plt.Rectangle((0.4, 0.4), 0.2, 0.2, facecolor="r", picker=5)
446+
# Machinery for "receiving" events
447+
received_events = []
448+
def on_pick(event):
449+
received_events.append(event)
450+
plt.gcf().canvas.mpl_connect('pick_event', on_pick)
451+
# Shortcut
452+
rectangles_on_axes = (big_on_axes, small_on_axes)
453+
# Axes setup
454+
axes = {"gca": None, "host": None, "parasite": None}
455+
if "gca" in rectangles_on_axes:
456+
axes["gca"] = plt.gca()
457+
if "host" in rectangles_on_axes or "parasite" in rectangles_on_axes:
458+
axes["host"] = host_subplot(111)
459+
axes["parasite"] = axes["host"].twin()
460+
# Add rectangles to axes
461+
axes[big_on_axes].add_patch(big)
462+
axes[small_on_axes].add_patch(small)
463+
# Simulate picking with click mouse event
464+
if click_on == "big":
465+
click_axes = axes[big_on_axes]
466+
axes_coords = (0.3, 0.3)
467+
else:
468+
click_axes = axes[small_on_axes]
469+
axes_coords = (0.5, 0.5)
470+
# In reality mouse events never happen on parasite axes, only host axes
471+
if click_axes is axes["parasite"]:
472+
click_axes = axes["host"]
473+
(x, y) = click_axes.transAxes.transform(axes_coords)
474+
m = MouseEvent("button_press_event", click_axes.figure.canvas, x, y,
475+
button=1)
476+
click_axes.pick(m)
477+
# Checks
478+
expected_n_events = 2 if click_on == "small" else 1
479+
assert len(received_events) == expected_n_events
480+
event_rects = [event.artist for event in received_events]
481+
assert big in event_rects
482+
if click_on == "small":
483+
assert small in event_rects

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.