Skip to content

Commit 1503ac4

Browse files
authored
Merge pull request #25573 from tacaswell/fix_removed_widget_axes
FIX: be very paranoid about checking what the current canvas is
2 parents 2b75c9e + 5c83d7b commit 1503ac4

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

lib/matplotlib/tests/test_widgets.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import operator
44
from unittest import mock
55

6-
from matplotlib.backend_bases import MouseEvent
6+
from matplotlib.backend_bases import MouseEvent, DrawEvent
77
import matplotlib.colors as mcolors
88
import matplotlib.widgets as widgets
99
import matplotlib.pyplot as plt
@@ -1757,3 +1757,26 @@ def test_MultiCursor(horizOn, vertOn):
17571757
assert l.get_xdata() == (.5, .5)
17581758
for l in multi.hlines:
17591759
assert l.get_ydata() == (.25, .25)
1760+
1761+
1762+
def test_parent_axes_removal():
1763+
1764+
fig, (ax_radio, ax_checks) = plt.subplots(1, 2)
1765+
1766+
radio = widgets.RadioButtons(ax_radio, ['1', '2'], 0)
1767+
checks = widgets.CheckButtons(ax_checks, ['1', '2'], [True, False])
1768+
1769+
ax_checks.remove()
1770+
ax_radio.remove()
1771+
with io.BytesIO() as out:
1772+
# verify that saving does not raise
1773+
fig.savefig(out, format='raw')
1774+
1775+
# verify that this method which is triggered by a draw_event callback when
1776+
# blitting is enabled does not raise. Calling private methods is simpler
1777+
# than trying to force blitting to be enabled with Agg or use a GUI
1778+
# framework.
1779+
renderer = fig._get_renderer()
1780+
evt = DrawEvent('draw_event', fig.canvas, renderer)
1781+
radio._clear(evt)
1782+
checks._clear(evt)

lib/matplotlib/widgets.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@ def __init__(self, ax):
117117
self.ax = ax
118118
self._cids = []
119119

120-
canvas = property(lambda self: self.ax.get_figure(root=True).canvas)
120+
canvas = property(
121+
lambda self: getattr(self.ax.get_figure(root=True), 'canvas', None)
122+
)
121123

122124
def connect_event(self, event, callback):
123125
"""
@@ -144,6 +146,10 @@ def _get_data_coords(self, event):
144146
return ((event.xdata, event.ydata) if event.inaxes is self.ax
145147
else self.ax.transData.inverted().transform((event.x, event.y)))
146148

149+
def ignore(self, event):
150+
# docstring inherited
151+
return super().ignore(event) or self.canvas is None
152+
147153

148154
class Button(AxesWidget):
149155
"""
@@ -2181,7 +2187,9 @@ def connect_default_events(self):
21812187

21822188
def ignore(self, event):
21832189
# docstring inherited
2184-
if not self.active or not self.ax.get_visible():
2190+
if super().ignore(event):
2191+
return True
2192+
if not self.ax.get_visible():
21852193
return True
21862194
# If canvas was locked
21872195
if not self.canvas.widgetlock.available(self):

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy