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

Skip to content

Commit 7a8a8e7

Browse files
committed
Assign event to later Axes if zorders are tied.
If axes zorders are tied, axes appearing later in figure.axes get drawn above those appearing earlier, so events should be preferably assigned to them. By default, max() returns the *first* maximum in case of ties, so the previous implementation was not satisfactory.
1 parent 8bc197a commit 7a8a8e7

3 files changed

Lines changed: 29 additions & 18 deletions

File tree

lib/matplotlib/backend_bases.py

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,22 +1527,19 @@ def __init__(self, name, canvas, x, y, guiEvent=None):
15271527
else:
15281528
axes_list = [self.canvas.mouse_grabber]
15291529

1530-
if axes_list: # Use highest zorder.
1531-
self.inaxes = max(axes_list, key=lambda x: x.zorder)
1532-
else: # None found.
1533-
self.inaxes = None
1534-
self._update_enter_leave()
1535-
return
1536-
1537-
try:
1538-
trans = self.inaxes.transData.inverted()
1539-
xdata, ydata = trans.transform_point((x, y))
1540-
except ValueError:
1541-
self.xdata = None
1542-
self.ydata = None
1530+
if axes_list:
1531+
self.inaxes = cbook._topmost_artist(axes_list)
1532+
try:
1533+
trans = self.inaxes.transData.inverted()
1534+
xdata, ydata = trans.transform_point((x, y))
1535+
except ValueError:
1536+
self.xdata = None
1537+
self.ydata = None
1538+
else:
1539+
self.xdata = xdata
1540+
self.ydata = ydata
15431541
else:
1544-
self.xdata = xdata
1545-
self.ydata = ydata
1542+
self.inaxes = None
15461543

15471544
self._update_enter_leave()
15481545

@@ -1805,7 +1802,7 @@ def onRemove(self, ev):
18051802
canvas.mpl_connect('mouse_press_event',canvas.onRemove)
18061803
"""
18071804
# Find the top artist under the cursor
1808-
under = sorted(self.figure.hitlist(ev), key=lambda x: x.zorder)
1805+
under = cbook._topmost_artist(self.figure.hitlist(ev))
18091806
h = None
18101807
if under:
18111808
h = under[-1]
@@ -2893,7 +2890,7 @@ def mouse_move(self, event):
28932890
if a.contains(event) and a.get_visible()]
28942891

28952892
if artists:
2896-
a = max(artists, key=lambda x: x.zorder)
2893+
a = cbook._topmost_artist(artists)
28972894
if a is not event.inaxes.patch:
28982895
data = a.get_cursor_data(event)
28992896
if data is not None:

lib/matplotlib/backend_tools.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ def send_message(self, event):
340340
if a.contains(event) and a.get_visible()]
341341

342342
if artists:
343-
a = max(artists, key=lambda x: x.zorder)
343+
a = cbook._topmost_artist(artists)
344344
if a is not event.inaxes.patch:
345345
data = a.get_cursor_data(event)
346346
if data is not None:

lib/matplotlib/cbook/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from itertools import repeat
2222
import locale
2323
import numbers
24+
import operator
2425
import os
2526
import re
2627
import sys
@@ -2752,3 +2753,16 @@ def _get_key_params(self):
27522753
(params, str_func))
27532754

27542755
return str_func, params
2756+
2757+
2758+
def _topmost_artist(
2759+
artists,
2760+
_cached_max=functools.partial(max, key=operator.attrgetter("zorder"))):
2761+
"""Get the topmost artist of a list.
2762+
2763+
In case of a tie, return the *last* of the tied artists, as it will be
2764+
drawn on top of the others. `max` returns the first maximum in case of ties
2765+
(on Py2 this is undocumented but true), so we need to iterate over the list
2766+
in reverse order.
2767+
"""
2768+
return _cached_max(reversed(artists))

0 commit comments

Comments
 (0)