@@ -977,6 +977,7 @@ class CheckButtons(AxesWidget):
977977 ----------
978978 ax : `~matplotlib.axes.Axes`
979979 The parent Axes for the widget.
980+
980981 labels : list of `.Text`
981982
982983 rectangles : list of `.Rectangle`
@@ -986,21 +987,22 @@ class CheckButtons(AxesWidget):
986987 each box, but have ``set_visible(False)`` when its box is not checked.
987988 """
988989
989- def __init__ (self , ax , labels , actives = None ):
990+ def __init__ (self , ax , labels , actives = None , * , useblit = True ):
990991 """
991992 Add check buttons to `matplotlib.axes.Axes` instance *ax*.
992993
993994 Parameters
994995 ----------
995996 ax : `~matplotlib.axes.Axes`
996997 The parent Axes for the widget.
997-
998998 labels : list of str
999999 The labels of the check buttons.
1000-
10011000 actives : list of bool, optional
10021001 The initial check states of the buttons. The list must have the
10031002 same length as *labels*. If not given, all buttons are unchecked.
1003+ useblit : bool, default: True
1004+ Use blitting for faster drawing if supported by the backend.
1005+ See the tutorial :doc:`/tutorials/advanced/blitting` for details.
10041006 """
10051007 super ().__init__ (ax )
10061008
@@ -1011,6 +1013,9 @@ def __init__(self, ax, labels, actives=None):
10111013 if actives is None :
10121014 actives = [False ] * len (labels )
10131015
1016+ self ._useblit = useblit and self .canvas .supports_blit
1017+ self ._background = None
1018+
10141019 ys = np .linspace (1 , 0 , len (labels )+ 2 )[1 :- 1 ]
10151020 text_size = mpl .rcParams ["font.size" ] / 2
10161021
@@ -1026,13 +1031,26 @@ def __init__(self, ax, labels, actives=None):
10261031 self ._crosses = ax .scatter (
10271032 [0.15 ] * len (ys ), ys , marker = 'x' , linewidth = 1 , s = text_size ** 2 ,
10281033 c = ["k" if active else "none" for active in actives ],
1029- transform = ax .transAxes
1034+ transform = ax .transAxes , animated = self . _useblit ,
10301035 )
10311036
10321037 self .connect_event ('button_press_event' , self ._clicked )
1038+ if self ._useblit :
1039+ self .connect_event ('draw_event' , self ._clear )
10331040
10341041 self ._observers = cbook .CallbackRegistry (signals = ["clicked" ])
10351042
1043+ def _clear (self , event ):
1044+ """Internal event handler to clear the buttons."""
1045+ if self .ignore (event ):
1046+ return
1047+ self ._background = self .canvas .copy_from_bbox (self .ax .bbox )
1048+ self .ax .draw_artist (self ._crosses )
1049+ if hasattr (self , '_lines' ):
1050+ for l1 , l2 in self ._lines :
1051+ self .ax .draw_artist (l1 )
1052+ self .ax .draw_artist (l2 )
1053+
10361054 def _clicked (self , event ):
10371055 if self .ignore (event ) or event .button != 1 or event .inaxes != self .ax :
10381056 return
@@ -1093,7 +1111,17 @@ def set_active(self, index):
10931111 l2 .set_visible (not l2 .get_visible ())
10941112
10951113 if self .drawon :
1096- self .ax .figure .canvas .draw ()
1114+ if self ._useblit :
1115+ if self ._background is not None :
1116+ self .canvas .restore_region (self ._background )
1117+ self .ax .draw_artist (self ._crosses )
1118+ if hasattr (self , "_lines" ):
1119+ for l1 , l2 in self ._lines :
1120+ self .ax .draw_artist (l1 )
1121+ self .ax .draw_artist (l2 )
1122+ self .canvas .blit (self .ax .bbox )
1123+ else :
1124+ self .canvas .draw ()
10971125
10981126 if self .eventson :
10991127 self ._observers .process ('clicked' , self .labels [index ].get_text ())
@@ -1152,7 +1180,8 @@ def lines(self):
11521180 current_status = self .get_status ()
11531181 lineparams = {'color' : 'k' , 'linewidth' : 1.25 ,
11541182 'transform' : self .ax .transAxes ,
1155- 'solid_capstyle' : 'butt' }
1183+ 'solid_capstyle' : 'butt' ,
1184+ 'animated' : self ._useblit }
11561185 for i , y in enumerate (ys ):
11571186 x , y = 0.05 , y - h / 2
11581187 l1 = Line2D ([x , x + w ], [y + h , y ], ** lineparams )
0 commit comments