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

Skip to content

Backport PR #25129 on branch v3.7.x (Undeprecate Cursor event handlers) #25160

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
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
33 changes: 27 additions & 6 deletions examples/event_handling/cursor_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import matplotlib.pyplot as plt
import numpy as np

from matplotlib.backend_bases import MouseEvent


class Cursor:
"""
Expand Down Expand Up @@ -56,8 +58,8 @@ def on_mouse_move(self, event):
self.set_cross_hair_visible(True)
x, y = event.xdata, event.ydata
# update the line positions
self.horizontal_line.set_ydata(y)
self.vertical_line.set_xdata(x)
self.horizontal_line.set_ydata([y])
self.vertical_line.set_xdata([x])
self.text.set_text('x=%1.2f, y=%1.2f' % (x, y))
self.ax.figure.canvas.draw()

Expand All @@ -71,6 +73,11 @@ def on_mouse_move(self, event):
cursor = Cursor(ax)
fig.canvas.mpl_connect('motion_notify_event', cursor.on_mouse_move)

# Simulate a mouse move to (0.5, 0.5), needed for online docs
t = ax.transData
MouseEvent(
"motion_notify_event", ax.figure.canvas, *t.transform((0.5, 0.5))
)._process()

##############################################################################
# Faster redrawing using blitting
Expand All @@ -85,6 +92,7 @@ def on_mouse_move(self, event):
# created whenever the figure changes. This is achieved by connecting to the
# ``'draw_event'``.


class BlittedCursor:
"""
A cross-hair cursor using blitting for faster redraw.
Expand Down Expand Up @@ -132,8 +140,8 @@ def on_mouse_move(self, event):
self.set_cross_hair_visible(True)
# update the line positions
x, y = event.xdata, event.ydata
self.horizontal_line.set_ydata(y)
self.vertical_line.set_xdata(x)
self.horizontal_line.set_ydata([y])
self.vertical_line.set_xdata([x])
self.text.set_text('x=%1.2f, y=%1.2f' % (x, y))

self.ax.figure.canvas.restore_region(self.background)
Expand All @@ -152,6 +160,11 @@ def on_mouse_move(self, event):
blitted_cursor = BlittedCursor(ax)
fig.canvas.mpl_connect('motion_notify_event', blitted_cursor.on_mouse_move)

# Simulate a mouse move to (0.5, 0.5), needed for online docs
t = ax.transData
MouseEvent(
"motion_notify_event", ax.figure.canvas, *t.transform((0.5, 0.5))
)._process()

##############################################################################
# Snapping to data points
Expand All @@ -165,6 +178,7 @@ def on_mouse_move(self, event):
# the lag due to many redraws. Of course, blitting could still be added on top
# for additional speedup.


class SnappingCursor:
"""
A cross-hair cursor that snaps to the data point of a line, which is
Expand Down Expand Up @@ -204,8 +218,8 @@ def on_mouse_move(self, event):
x = self.x[index]
y = self.y[index]
# update the line positions
self.horizontal_line.set_ydata(y)
self.vertical_line.set_xdata(x)
self.horizontal_line.set_ydata([y])
self.vertical_line.set_xdata([x])
self.text.set_text('x=%1.2f, y=%1.2f' % (x, y))
self.ax.figure.canvas.draw()

Expand All @@ -218,4 +232,11 @@ def on_mouse_move(self, event):
line, = ax.plot(x, y, 'o')
snap_cursor = SnappingCursor(ax, line)
fig.canvas.mpl_connect('motion_notify_event', snap_cursor.on_mouse_move)

# Simulate a mouse move to (0.5, 0.5), needed for online docs
t = ax.transData
MouseEvent(
"motion_notify_event", ax.figure.canvas, *t.transform((0.5, 0.5))
)._process()

plt.show()
14 changes: 14 additions & 0 deletions examples/widgets/annotated_cursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import numpy as np
import matplotlib.pyplot as plt

from matplotlib.backend_bases import MouseEvent


class AnnotatedCursor(Cursor):
"""
Expand Down Expand Up @@ -312,6 +314,12 @@ def _update(self):
color='red',
linewidth=2)

# Simulate a mouse move to (-2, 10), needed for online docs
t = ax.transData
MouseEvent(
"motion_notify_event", ax.figure.canvas, *t.transform((-2, 10))
)._process()

plt.show()

###############################################################################
Expand Down Expand Up @@ -339,4 +347,10 @@ def _update(self):
useblit=True,
color='red', linewidth=2)

# Simulate a mouse move to (-2, 10), needed for online docs
t = ax.transData
MouseEvent(
"motion_notify_event", ax.figure.canvas, *t.transform((-2, 10))
)._process()

plt.show()
8 changes: 5 additions & 3 deletions lib/matplotlib/tests/test_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -1654,7 +1654,9 @@ def test_MultiCursor(horizOn, vertOn):
# Can't use `do_event` as that helper requires the widget
# to have a single .ax attribute.
event = mock_event(ax1, xdata=.5, ydata=.25)
multi._onmove(event)
multi.onmove(event)
# force a draw + draw event to exercise clear
ax1.figure.canvas.draw()

# the lines in the first two ax should both move
for l in multi.vlines:
Expand All @@ -1671,7 +1673,7 @@ def test_MultiCursor(horizOn, vertOn):
multi.horizOn = not multi.horizOn
multi.vertOn = not multi.vertOn
event = mock_event(ax1, xdata=.5, ydata=.25)
multi._onmove(event)
multi.onmove(event)
assert len([line for line in multi.vlines if line.get_visible()]) == (
0 if vertOn else 2)
assert len([line for line in multi.hlines if line.get_visible()]) == (
Expand All @@ -1680,7 +1682,7 @@ def test_MultiCursor(horizOn, vertOn):
# test a move event in an Axes not part of the MultiCursor
# the lines in ax1 and ax2 should not have moved.
event = mock_event(ax3, xdata=.75, ydata=.75)
multi._onmove(event)
multi.onmove(event)
for l in multi.vlines:
assert l.get_xdata() == (.5, .5)
for l in multi.hlines:
Expand Down
44 changes: 10 additions & 34 deletions lib/matplotlib/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -1953,8 +1953,8 @@ def __init__(self, ax, horizOn=True, vertOn=True, useblit=False,
**lineprops):
super().__init__(ax)

self.connect_event('motion_notify_event', self._onmove)
self.connect_event('draw_event', self._clear)
self.connect_event('motion_notify_event', self.onmove)
self.connect_event('draw_event', self.clear)

self.visible = True
self.horizOn = horizOn
Expand All @@ -1967,29 +1967,16 @@ def __init__(self, ax, horizOn=True, vertOn=True, useblit=False,
self.linev = ax.axvline(ax.get_xbound()[0], visible=False, **lineprops)

self.background = None
self._needclear = False

needclear = _api.deprecate_privatize_attribute("3.7")
self.needclear = False

@_api.deprecated('3.7')
def clear(self, event):
"""Internal event handler to clear the cursor."""
self._clear(event)
if self.ignore(event):
return
self.linev.set_visible(False)
self.lineh.set_visible(False)

def _clear(self, event):
"""Internal event handler to clear the cursor."""
if self.ignore(event):
return
if self.useblit:
self.background = self.canvas.copy_from_bbox(self.ax.bbox)

onmove = _api.deprecate_privatize_attribute('3.7')

def _onmove(self, event):
def onmove(self, event):
"""Internal event handler to draw the cursor when the mouse moves."""
if self.ignore(event):
return
Expand All @@ -1999,11 +1986,11 @@ def _onmove(self, event):
self.linev.set_visible(False)
self.lineh.set_visible(False)

if self._needclear:
if self.needclear:
self.canvas.draw()
self._needclear = False
self.needclear = False
return
self._needclear = True
self.needclear = True

self.linev.set_xdata((event.xdata, event.xdata))
self.linev.set_visible(self.visible and self.vertOn)
Expand Down Expand Up @@ -2106,8 +2093,8 @@ def connect(self):
"""Connect events."""
for canvas, info in self._canvas_infos.items():
info["cids"] = [
canvas.mpl_connect('motion_notify_event', self._onmove),
canvas.mpl_connect('draw_event', self._clear),
canvas.mpl_connect('motion_notify_event', self.onmove),
canvas.mpl_connect('draw_event', self.clear),
]

def disconnect(self):
Expand All @@ -2117,26 +2104,15 @@ def disconnect(self):
canvas.mpl_disconnect(cid)
info["cids"].clear()

@_api.deprecated('3.7')
def clear(self, event):
"""Clear the cursor."""
if self.ignore(event):
return
self._clear(event)
for line in self.vlines + self.hlines:
line.set_visible(False)

def _clear(self, event):
"""Clear the cursor."""
if self.ignore(event):
return
if self.useblit:
for canvas, info in self._canvas_infos.items():
info["background"] = canvas.copy_from_bbox(canvas.figure.bbox)

onmove = _api.deprecate_privatize_attribute('3.7')

def _onmove(self, event):
def onmove(self, event):
if (self.ignore(event)
or event.inaxes not in self.axes
or not event.canvas.widgetlock.available(self)):
Expand Down