@@ -977,6 +977,7 @@ class CheckButtons(AxesWidget):
977
977
----------
978
978
ax : `~matplotlib.axes.Axes`
979
979
The parent Axes for the widget.
980
+
980
981
labels : list of `.Text`
981
982
982
983
rectangles : list of `.Rectangle`
@@ -986,21 +987,22 @@ class CheckButtons(AxesWidget):
986
987
each box, but have ``set_visible(False)`` when its box is not checked.
987
988
"""
988
989
989
- def __init__ (self , ax , labels , actives = None ):
990
+ def __init__ (self , ax , labels , actives = None , * , useblit = True ):
990
991
"""
991
992
Add check buttons to `matplotlib.axes.Axes` instance *ax*.
992
993
993
994
Parameters
994
995
----------
995
996
ax : `~matplotlib.axes.Axes`
996
997
The parent Axes for the widget.
997
-
998
998
labels : list of str
999
999
The labels of the check buttons.
1000
-
1001
1000
actives : list of bool, optional
1002
1001
The initial check states of the buttons. The list must have the
1003
1002
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.
1004
1006
"""
1005
1007
super ().__init__ (ax )
1006
1008
@@ -1011,6 +1013,9 @@ def __init__(self, ax, labels, actives=None):
1011
1013
if actives is None :
1012
1014
actives = [False ] * len (labels )
1013
1015
1016
+ self ._useblit = useblit and self .canvas .supports_blit
1017
+ self ._background = None
1018
+
1014
1019
ys = np .linspace (1 , 0 , len (labels )+ 2 )[1 :- 1 ]
1015
1020
text_size = mpl .rcParams ["font.size" ] / 2
1016
1021
@@ -1026,13 +1031,26 @@ def __init__(self, ax, labels, actives=None):
1026
1031
self ._crosses = ax .scatter (
1027
1032
[0.15 ] * len (ys ), ys , marker = 'x' , linewidth = 1 , s = text_size ** 2 ,
1028
1033
c = ["k" if active else "none" for active in actives ],
1029
- transform = ax .transAxes
1034
+ transform = ax .transAxes , animated = self . _useblit ,
1030
1035
)
1031
1036
1032
1037
self .connect_event ('button_press_event' , self ._clicked )
1038
+ if self ._useblit :
1039
+ self .connect_event ('draw_event' , self ._clear )
1033
1040
1034
1041
self ._observers = cbook .CallbackRegistry (signals = ["clicked" ])
1035
1042
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
+
1036
1054
def _clicked (self , event ):
1037
1055
if self .ignore (event ) or event .button != 1 or event .inaxes != self .ax :
1038
1056
return
@@ -1093,7 +1111,17 @@ def set_active(self, index):
1093
1111
l2 .set_visible (not l2 .get_visible ())
1094
1112
1095
1113
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 ()
1097
1125
1098
1126
if self .eventson :
1099
1127
self ._observers .process ('clicked' , self .labels [index ].get_text ())
@@ -1152,7 +1180,8 @@ def lines(self):
1152
1180
current_status = self .get_status ()
1153
1181
lineparams = {'color' : 'k' , 'linewidth' : 1.25 ,
1154
1182
'transform' : self .ax .transAxes ,
1155
- 'solid_capstyle' : 'butt' }
1183
+ 'solid_capstyle' : 'butt' ,
1184
+ 'animated' : self ._useblit }
1156
1185
for i , y in enumerate (ys ):
1157
1186
x , y = 0.05 , y - h / 2
1158
1187
l1 = Line2D ([x , x + w ], [y + h , y ], ** lineparams )
0 commit comments