@@ -117,6 +117,11 @@ class AxesWidget(Widget):
117117 def __init__ (self , ax ):
118118 self .ax = ax
119119 self ._cids = []
120+ self ._blit_background_id = None
121+
122+ def __del__ (self ):
123+ if self ._blit_background_id is not None :
124+ self .canvas ._release_blit_background_id (self ._blit_background_id )
120125
121126 canvas = property (
122127 lambda self : getattr (self .ax .get_figure (root = True ), 'canvas' , None )
@@ -155,6 +160,26 @@ def _set_cursor(self, cursor):
155160 """Update the canvas cursor."""
156161 self .ax .get_figure (root = True ).canvas .set_cursor (cursor )
157162
163+ def _save_blit_background (self , background ):
164+ """
165+ Save a blit background.
166+
167+ The background is stored on the canvas in a uniquely identifiable way.
168+ It should be read back via `._load_blit_background`. Be prepared that
169+ some events may invalidate the background, in which case
170+ `._load_blit_background` will return None.
171+
172+ This currently allows at most one background per widget, which is
173+ good enough for all existing widgets.
174+ """
175+ if self ._blit_background_id is None :
176+ self ._blit_background_id = self .canvas ._get_blit_background_id ()
177+ self .canvas ._blit_backgrounds [self ._blit_background_id ] = background
178+
179+ def _load_blit_background (self ):
180+ """Load a blit background; may be None at any time."""
181+ return self .canvas ._blit_backgrounds .get (self ._blit_background_id )
182+
158183
159184class Button (AxesWidget ):
160185 """
@@ -1063,7 +1088,6 @@ def __init__(self, ax, labels, actives=None, *, useblit=True,
10631088 actives = [False ] * len (labels )
10641089
10651090 self ._useblit = useblit and self .canvas .supports_blit
1066- self ._background = None
10671091
10681092 ys = np .linspace (1 , 0 , len (labels )+ 2 )[1 :- 1 ]
10691093
@@ -1110,7 +1134,7 @@ def _clear(self, event):
11101134 """Internal event handler to clear the buttons."""
11111135 if self .ignore (event ) or self .canvas .is_saving ():
11121136 return
1113- self ._background = self .canvas .copy_from_bbox (self .ax .bbox )
1137+ self ._save_blit_background ( self .canvas .copy_from_bbox (self .ax .bbox ) )
11141138 self .ax .draw_artist (self ._checks )
11151139
11161140 def _clicked (self , event ):
@@ -1215,8 +1239,9 @@ def set_active(self, index, state=None):
12151239
12161240 if self .drawon :
12171241 if self ._useblit :
1218- if self ._background is not None :
1219- self .canvas .restore_region (self ._background )
1242+ background = self ._load_blit_background ()
1243+ if background is not None :
1244+ self .canvas .restore_region (background )
12201245 self .ax .draw_artist (self ._checks )
12211246 self .canvas .blit (self .ax .bbox )
12221247 else :
@@ -1650,7 +1675,6 @@ def __init__(self, ax, labels, active=0, activecolor=None, *,
16501675 ys = np .linspace (1 , 0 , len (labels ) + 2 )[1 :- 1 ]
16511676
16521677 self ._useblit = useblit and self .canvas .supports_blit
1653- self ._background = None
16541678
16551679 label_props = _expand_text_props (label_props )
16561680 self .labels = [
@@ -1692,7 +1716,7 @@ def _clear(self, event):
16921716 """Internal event handler to clear the buttons."""
16931717 if self .ignore (event ) or self .canvas .is_saving ():
16941718 return
1695- self ._background = self .canvas .copy_from_bbox (self .ax .bbox )
1719+ self ._save_blit_background ( self .canvas .copy_from_bbox (self .ax .bbox ) )
16961720 self .ax .draw_artist (self ._buttons )
16971721
16981722 def _clicked (self , event ):
@@ -1785,8 +1809,9 @@ def set_active(self, index):
17851809
17861810 if self .drawon :
17871811 if self ._useblit :
1788- if self ._background is not None :
1789- self .canvas .restore_region (self ._background )
1812+ background = self ._load_blit_background ()
1813+ if background is not None :
1814+ self .canvas .restore_region (background )
17901815 self .ax .draw_artist (self ._buttons )
17911816 self .canvas .blit (self .ax .bbox )
17921817 else :
@@ -1942,15 +1967,14 @@ def __init__(self, ax, *, horizOn=True, vertOn=True, useblit=False,
19421967 self .lineh = ax .axhline (ax .get_ybound ()[0 ], visible = False , ** lineprops )
19431968 self .linev = ax .axvline (ax .get_xbound ()[0 ], visible = False , ** lineprops )
19441969
1945- self .background = None
19461970 self .needclear = False
19471971
19481972 def clear (self , event ):
19491973 """Internal event handler to clear the cursor."""
19501974 if self .ignore (event ) or self .canvas .is_saving ():
19511975 return
19521976 if self .useblit :
1953- self .background = self .canvas .copy_from_bbox (self .ax .bbox )
1977+ self ._save_blit_background ( self .canvas .copy_from_bbox (self .ax .bbox ) )
19541978
19551979 def onmove (self , event ):
19561980 """Internal event handler to draw the cursor when the mouse moves."""
@@ -1975,8 +1999,9 @@ def onmove(self, event):
19751999 return
19762000 # Redraw.
19772001 if self .useblit :
1978- if self .background is not None :
1979- self .canvas .restore_region (self .background )
2002+ background = self ._load_blit_background ()
2003+ if background is not None :
2004+ self .canvas .restore_region (background )
19802005 self .ax .draw_artist (self .linev )
19812006 self .ax .draw_artist (self .lineh )
19822007 self .canvas .blit (self .ax .bbox )
@@ -2137,8 +2162,6 @@ def __init__(self, ax, onselect=None, useblit=False, button=None,
21372162 self ._state_modifier_keys .update (state_modifier_keys or {})
21382163 self ._use_data_coordinates = use_data_coordinates
21392164
2140- self .background = None
2141-
21422165 if isinstance (button , Integral ):
21432166 self .validButtons = [button ]
21442167 else :
@@ -2194,7 +2217,7 @@ def update_background(self, event):
21942217 for artist in artists :
21952218 stack .enter_context (artist ._cm_set (visible = False ))
21962219 self .canvas .draw ()
2197- self .background = self .canvas .copy_from_bbox (self .ax .bbox )
2220+ self ._save_blit_background ( self .canvas .copy_from_bbox (self .ax .bbox ) )
21982221 if needs_redraw :
21992222 for artist in artists :
22002223 self .ax .draw_artist (artist )
@@ -2241,8 +2264,9 @@ def update(self):
22412264 self .ax .get_figure (root = True )._get_renderer () is None ):
22422265 return
22432266 if self .useblit :
2244- if self .background is not None :
2245- self .canvas .restore_region (self .background )
2267+ background = self ._load_blit_background ()
2268+ if background is not None :
2269+ self .canvas .restore_region (background )
22462270 else :
22472271 self .update_background (None )
22482272 # We need to draw all artists, which are not included in the
0 commit comments