Skip to content

Commit d350785

Browse files
committed
Prevent blitting errors after canvas swap in RadioButtons and CheckButtons
This guards blitting-related functionality of RadioButtons and CheckButtons behind a `self.canvas.supports_blit` check, so that we don't get errors when trying to call blitting functionality on canvases that don't support it. Note: RadioButtons and CheckButtons do still not fully support canvas swapping as they carry persitent state that depends on blitting capability ("animated"). This is currently not updated when canvases are changed. However, this should at most lead to incorrect rendering in some edge cases after canvas swap. It will not error out anymore. In other words the "# TODO: make dynamic" is partially solved, and reduced to a smaller problem outlined in the new TODO.
1 parent a326d07 commit d350785

1 file changed

Lines changed: 17 additions & 8 deletions

File tree

lib/matplotlib/widgets.py

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,7 +1108,7 @@ def __init__(self, ax, labels, actives=None, *, useblit=True,
11081108
if actives is None:
11091109
actives = [False] * len(labels)
11101110

1111-
self._useblit = useblit and self.canvas.supports_blit # TODO: make dynamic
1111+
self._useblit = useblit
11121112

11131113
ys = np.linspace(1, 0, len(labels)+2)[1:-1]
11141114

@@ -1136,7 +1136,10 @@ def __init__(self, ax, labels, actives=None, *, useblit=True,
11361136
**cbook.normalize_kwargs(check_props, collections.PathCollection),
11371137
'marker': 'x',
11381138
'transform': ax.transAxes,
1139-
'animated': self._useblit,
1139+
'animated': self._useblit and self.canvas.supports_blit,
1140+
# TODO: This may need an update when switching out the canvas.
1141+
# Can set this to `_useblit` only and live with the animated=True
1142+
# overhead on unsupported backends.
11401143
}
11411144
check_props.setdefault('facecolor', check_props.pop('color', 'black'))
11421145
self._checks = ax.scatter([0.15] * len(ys), ys, **check_props)
@@ -1155,7 +1158,8 @@ def _clear(self, event):
11551158
"""Internal event handler to clear the buttons."""
11561159
if self.ignore(event) or self.canvas.is_saving():
11571160
return
1158-
self._save_blit_background(self.canvas.copy_from_bbox(self.ax.bbox))
1161+
if self._useblit and self.canvas.supports_blit:
1162+
self._save_blit_background(self.canvas.copy_from_bbox(self.ax.bbox))
11591163
self.ax.draw_artist(self._checks)
11601164

11611165
@_call_with_reparented_event
@@ -1260,7 +1264,7 @@ def set_active(self, index, state=None):
12601264
self._checks.set_facecolor(facecolors)
12611265

12621266
if self.drawon:
1263-
if self._useblit:
1267+
if self._useblit and self.canvas.supports_blit:
12641268
background = self._load_blit_background()
12651269
if background is not None:
12661270
self.canvas.restore_region(background)
@@ -1701,7 +1705,7 @@ def __init__(self, ax, labels, active=0, activecolor=None, *,
17011705

17021706
ys = np.linspace(1, 0, len(labels) + 2)[1:-1]
17031707

1704-
self._useblit = useblit and self.canvas.supports_blit # TODO: make dynamic
1708+
self._useblit = useblit
17051709

17061710
label_props = _expand_text_props(label_props)
17071711
self.labels = [
@@ -1716,7 +1720,11 @@ def __init__(self, ax, labels, active=0, activecolor=None, *,
17161720
**radio_props,
17171721
'marker': 'o',
17181722
'transform': ax.transAxes,
1719-
'animated': self._useblit,
1723+
'animated': self._useblit and self.canvas.supports_blit,
1724+
# TODO: This may need an update when switching out the canvas.
1725+
# Can set this to `_useblit` only and live with the animated=True
1726+
# overhead on unsupported backends.
1727+
17201728
}
17211729
radio_props.setdefault('edgecolor', radio_props.get('color', 'black'))
17221730
radio_props.setdefault('facecolor',
@@ -1743,7 +1751,8 @@ def _clear(self, event):
17431751
"""Internal event handler to clear the buttons."""
17441752
if self.ignore(event) or self.canvas.is_saving():
17451753
return
1746-
self._save_blit_background(self.canvas.copy_from_bbox(self.ax.bbox))
1754+
if self._useblit and self.canvas.supports_blit:
1755+
self._save_blit_background(self.canvas.copy_from_bbox(self.ax.bbox))
17471756
self.ax.draw_artist(self._buttons)
17481757

17491758
@_call_with_reparented_event
@@ -1836,7 +1845,7 @@ def set_active(self, index):
18361845
self._buttons.set_facecolor(button_facecolors)
18371846

18381847
if self.drawon:
1839-
if self._useblit:
1848+
if self._useblit and self.canvas.supports_blit:
18401849
background = self._load_blit_background()
18411850
if background is not None:
18421851
self.canvas.restore_region(background)

0 commit comments

Comments
 (0)