Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8c459da

Browse files
committed
axes_grid1: add host/parasite axes pick methods
Fixes #5581
1 parent 121102b commit 8c459da

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

lib/mpl_toolkits/axes_grid1/parasite_axes.py

Lines 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

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,20 @@
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
24+
import queue
2325

2426
import pytest
2527
import platform
2628

2729
import numpy as np
2830
from numpy.testing import assert_array_equal, assert_array_almost_equal
2931

32+
import pytest
33+
3034

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

0 commit comments

Comments
 (0)