Skip to content

Backport PR #9389 on branch v2.1.x #9631

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 31, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 14 additions & 17 deletions lib/matplotlib/backend_bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -1537,22 +1537,19 @@ def __init__(self, name, canvas, x, y, guiEvent=None):
else:
axes_list = [self.canvas.mouse_grabber]

if axes_list: # Use highest zorder.
self.inaxes = max(axes_list, key=lambda x: x.zorder)
else: # None found.
self.inaxes = None
self._update_enter_leave()
return

try:
trans = self.inaxes.transData.inverted()
xdata, ydata = trans.transform_point((x, y))
except ValueError:
self.xdata = None
self.ydata = None
if axes_list:
self.inaxes = cbook._topmost_artist(axes_list)
try:
trans = self.inaxes.transData.inverted()
xdata, ydata = trans.transform_point((x, y))
except ValueError:
self.xdata = None
self.ydata = None
else:
self.xdata = xdata
self.ydata = ydata
else:
self.xdata = xdata
self.ydata = ydata
self.inaxes = None

self._update_enter_leave()

Expand Down Expand Up @@ -1815,7 +1812,7 @@ def onRemove(self, ev):
canvas.mpl_connect('mouse_press_event',canvas.onRemove)
"""
# Find the top artist under the cursor
under = sorted(self.figure.hitlist(ev), key=lambda x: x.zorder)
under = cbook._topmost_artist(self.figure.hitlist(ev))
h = None
if under:
h = under[-1]
Expand Down Expand Up @@ -2899,7 +2896,7 @@ def mouse_move(self, event):
if a.contains(event) and a.get_visible()]

if artists:
a = max(artists, key=lambda x: x.zorder)
a = cbook._topmost_artist(artists)
if a is not event.inaxes.patch:
data = a.get_cursor_data(event)
if data is not None:
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/backend_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ def send_message(self, event):
if a.contains(event) and a.get_visible()]

if artists:
a = max(artists, key=lambda x: x.zorder)
a = cbook._topmost_artist(artists)
if a is not event.inaxes.patch:
data = a.get_cursor_data(event)
if data is not None:
Expand Down
14 changes: 14 additions & 0 deletions lib/matplotlib/cbook/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from itertools import repeat
import locale
import numbers
import operator
import os
import re
import sys
Expand Down Expand Up @@ -2752,3 +2753,16 @@ def _get_key_params(self):
(params, str_func))

return str_func, params


def _topmost_artist(
artists,
_cached_max=functools.partial(max, key=operator.attrgetter("zorder"))):
"""Get the topmost artist of a list.

In case of a tie, return the *last* of the tied artists, as it will be
drawn on top of the others. `max` returns the first maximum in case of ties
(on Py2 this is undocumented but true), so we need to iterate over the list
in reverse order.
"""
return _cached_max(reversed(artists))