Skip to content

Fix toggling of MultiCursor.{horizOn,vertOn} #24845

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
Jan 3, 2023
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
2 changes: 1 addition & 1 deletion doc/api/next_api_changes/deprecations/19763-ES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Access to the event handlers for the `.Cursor` and `.MultiCursor` widgets is
now deprecated.
now deprecated. The related *needclear* attribute is also deprecated.
19 changes: 17 additions & 2 deletions lib/matplotlib/tests/test_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -1575,8 +1575,8 @@ def test_MultiCursor(horizOn, vertOn):
)

# Only two of the axes should have a line drawn on them.
assert len(multi.vlines) == (2 if vertOn else 0)
assert len(multi.hlines) == (2 if horizOn else 0)
assert len(multi.vlines) == 2
assert len(multi.hlines) == 2

# mock a motion_notify_event
# Can't use `do_event` as that helper requires the widget
Expand All @@ -1589,6 +1589,21 @@ def test_MultiCursor(horizOn, vertOn):
assert l.get_xdata() == (.5, .5)
for l in multi.hlines:
assert l.get_ydata() == (.25, .25)
# The relevant lines get turned on after move.
assert len([line for line in multi.vlines if line.get_visible()]) == (
2 if vertOn else 0)
assert len([line for line in multi.hlines if line.get_visible()]) == (
2 if horizOn else 0)

# After toggling settings, the opposite lines should be visible after move.
multi.horizOn = not multi.horizOn
multi.vertOn = not multi.vertOn
event = mock_event(ax1, xdata=.5, ydata=.25)
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()]) == (
0 if horizOn else 2)

# test a move event in an Axes not part of the MultiCursor
# the lines in ax1 and ax2 should not have moved.
Expand Down
42 changes: 17 additions & 25 deletions lib/matplotlib/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -1746,7 +1746,9 @@ 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
self._needclear = False

needclear = _api.deprecate_privatize_attribute("3.7")

@_api.deprecated('3.7')
def clear(self, event):
Expand Down Expand Up @@ -1776,11 +1778,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 @@ -1863,28 +1865,21 @@ def __init__(self, canvas, axes, useblit=True, horizOn=False, vertOn=True,
self.useblit = (
useblit
and all(canvas.supports_blit for canvas in self._canvas_infos))
self.needclear = False

if self.useblit:
lineprops['animated'] = True

if vertOn:
self.vlines = [ax.axvline(xmid, visible=False, **lineprops)
for ax in axes]
else:
self.vlines = []

if horizOn:
self.hlines = [ax.axhline(ymid, visible=False, **lineprops)
for ax in axes]
else:
self.hlines = []
self.vlines = [ax.axvline(xmid, visible=False, **lineprops)
for ax in axes]
self.hlines = [ax.axhline(ymid, visible=False, **lineprops)
for ax in axes]

self.connect()

canvas = _api.deprecate_privatize_attribute("3.6")
background = _api.deprecated("3.6")(lambda self: (
self._backgrounds[self.axes[0].figure.canvas] if self.axes else None))
needclear = _api.deprecated("3.7")(lambda self: False)

def connect(self):
"""Connect events."""
Expand Down Expand Up @@ -1925,15 +1920,12 @@ def _onmove(self, event):
or event.inaxes not in self.axes
or not event.canvas.widgetlock.available(self)):
return
self.needclear = True
if self.vertOn:
for line in self.vlines:
line.set_xdata((event.xdata, event.xdata))
line.set_visible(self.visible)
if self.horizOn:
for line in self.hlines:
line.set_ydata((event.ydata, event.ydata))
line.set_visible(self.visible)
for line in self.vlines:
line.set_xdata((event.xdata, event.xdata))
line.set_visible(self.visible and self.vertOn)
for line in self.hlines:
line.set_ydata((event.ydata, event.ydata))
line.set_visible(self.visible and self.horizOn)
if self.visible and (self.vertOn or self.horizOn):
self._update()

Expand Down