@@ -152,7 +152,7 @@ class Button(AxesWidget):
152
152
"""
153
153
154
154
def __init__ (self , ax , label , image = None ,
155
- color = '0.85' , hovercolor = '0.95' ):
155
+ color = '0.85' , hovercolor = '0.95' , * , useblit = True ):
156
156
"""
157
157
Parameters
158
158
----------
@@ -167,6 +167,9 @@ def __init__(self, ax, label, image=None,
167
167
The color of the button when not activated.
168
168
hovercolor : color
169
169
The color of the button when the mouse is over it.
170
+ useblit : bool, default: True
171
+ Use blitting for faster drawing if supported by the backend.
172
+ See the tutorial :doc:`/tutorials/advanced/blitting` for details.
170
173
"""
171
174
super ().__init__ (ax )
172
175
@@ -177,6 +180,8 @@ def __init__(self, ax, label, image=None,
177
180
horizontalalignment = 'center' ,
178
181
transform = ax .transAxes )
179
182
183
+ self ._useblit = useblit and self .canvas .supports_blit
184
+
180
185
self ._observers = cbook .CallbackRegistry (signals = ["clicked" ])
181
186
182
187
self .connect_event ('button_press_event' , self ._click )
@@ -209,7 +214,11 @@ def _motion(self, event):
209
214
if not colors .same_color (c , self .ax .get_facecolor ()):
210
215
self .ax .set_facecolor (c )
211
216
if self .drawon :
212
- self .ax .figure .canvas .draw ()
217
+ if self ._useblit :
218
+ self .ax .draw_artist (self .ax )
219
+ self .canvas .blit (self .ax .bbox )
220
+ else :
221
+ self .canvas .draw ()
213
222
214
223
def on_clicked (self , func ):
215
224
"""
@@ -968,6 +977,7 @@ class CheckButtons(AxesWidget):
968
977
----------
969
978
ax : `~matplotlib.axes.Axes`
970
979
The parent Axes for the widget.
980
+
971
981
labels : list of `.Text`
972
982
973
983
rectangles : list of `.Rectangle`
@@ -977,21 +987,22 @@ class CheckButtons(AxesWidget):
977
987
each box, but have ``set_visible(False)`` when its box is not checked.
978
988
"""
979
989
980
- def __init__ (self , ax , labels , actives = None ):
990
+ def __init__ (self , ax , labels , actives = None , * , useblit = True ):
981
991
"""
982
992
Add check buttons to `matplotlib.axes.Axes` instance *ax*.
983
993
984
994
Parameters
985
995
----------
986
996
ax : `~matplotlib.axes.Axes`
987
997
The parent Axes for the widget.
988
-
989
998
labels : list of str
990
999
The labels of the check buttons.
991
-
992
1000
actives : list of bool, optional
993
1001
The initial check states of the buttons. The list must have the
994
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.
995
1006
"""
996
1007
super ().__init__ (ax )
997
1008
@@ -1002,6 +1013,9 @@ def __init__(self, ax, labels, actives=None):
1002
1013
if actives is None :
1003
1014
actives = [False ] * len (labels )
1004
1015
1016
+ self ._useblit = useblit and self .canvas .supports_blit
1017
+ self ._background = None
1018
+
1005
1019
ys = np .linspace (1 , 0 , len (labels )+ 2 )[1 :- 1 ]
1006
1020
text_size = mpl .rcParams ["font.size" ] / 2
1007
1021
@@ -1017,13 +1031,26 @@ def __init__(self, ax, labels, actives=None):
1017
1031
self ._crosses = ax .scatter (
1018
1032
F438
[0.15 ] * len (ys ), ys , marker = 'x' , linewidth = 1 , s = text_size ** 2 ,
1019
1033
c = ["k" if active else "none" for active in actives ],
1020
- transform = ax .transAxes
1034
+ transform = ax .transAxes , animated = self . _useblit ,
1021
1035
)
1022
1036
1023
1037
self .connect_event ('button_press_event' , self ._clicked )
1038
+ if self ._useblit :
1039
+ self .connect_event ('draw_event' , self ._clear )
1024
1040
1025
1041
self ._observers = cbook .CallbackRegistry (signals = ["clicked" ])
1026
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
+
1027
1054
def _clicked (self , event ):
1028
1055
if self .ignore (event ) or event .button != 1 or event .inaxes != self .ax :
1029
1056
return
@@ -1084,7 +1111,17 @@ def set_active(self, index):
1084
1111
l2 .set_visible (not l2 .get_visible ())
1085
1112
1086
1113
if self .drawon :
1087
- 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 ()
1088
1125
1089
1126
if self .eventson :
1090
1127
self ._observers .process ('clicked' , self .labels [index ].get_text ())
@@ -1143,7 +1180,8 @@ def lines(self):
1143
1180
current_status = self .get_status ()
1144
1181
lineparams = {'color' : 'k' , 'linewidth' : 1.25 ,
1145
1182
'transform' : self .ax .transAxes ,
1146
- 'solid_capstyle' : 'butt' }
1183
+ 'solid_capstyle' : 'butt' ,
1184
+ 'animated' : self ._useblit }
1147
1185
for i , y in enumerate (ys ):
1148
1186
x , y = 0.05 , y - h / 2
1149
1187
l1 = Line2D ([x , x + w ], [y + h , y ], ** lineparams )
@@ -1447,7 +1485,8 @@ class RadioButtons(AxesWidget):
1447
1485
The label text of the currently selected button.
1448
1486
"""
1449
1487
1450
- def __init__ (self , ax , labels , active = 0 , activecolor = 'blue' ):
1488
+ def __init__ (self , ax , labels , active = 0 , activecolor = 'blue' , * ,
1489
+ useblit = True ):
1451
1490
"""
1452
1491
Add radio buttons to an `~.axes.Axes`.
1453
1492
@@ -1461,6 +1500,9 @@ def __init__(self, ax, labels, active=0, activecolor='blue'):
1461
1500
The index of the initially selected button.
1462
1501
activecolor : color
1463
1502
The color of the selected button.
1503
+ useblit : bool, default: True
1504
+ Use blitting for faster drawing if supported by the backend.
1505
+ See the tutorial :doc:`/tutorials/advanced/blitting` for details.
1464
1506
"""
1465
1507
super ().__init__ (ax )
1466
1508
self .activecolor = activecolor
@@ -1473,19 +1515,34 @@ def __init__(self, ax, labels, active=0, activecolor='blue'):
1473
1515
ys = np .linspace (1 , 0 , len (labels ) + 2 )[1 :- 1 ]
1474
1516
text_size = mpl .rcParams ["font.size" ] / 2
1475
1517
1518
+ self ._useblit = useblit and self .canvas .supports_blit
1519
+ self ._background = None
1520
+
1476
1521
self .labels = [
1477
1522
ax .text (0.25 , y , label , transform = ax .transAxes ,
1478
1523
horizontalalignment = "left" , verticalalignment = "center" )
1479
1524
for y , label in zip (ys , labels )]
1480
1525
self ._buttons = ax .scatter (
1481
1526
[.15 ] * len (ys ), ys , transform = ax .transAxes , s = text_size ** 2 ,
1482
1527
c = [activecolor if i == active else "none" for i in range (len (ys ))],
1483
- edgecolor = "black" )
1528
+ edgecolor = "black" , animated = self . _useblit )
1484
1529
1485
1530
self .connect_event ('button_press_event' , self ._clicked )
1531
+ if self ._useblit :
1532
+ self .connect_event ('draw_event' , self ._clear )
1486
1533
1487
1534
self ._observers = cbook .CallbackRegistry (signals = ["clicked" ])
1488
1535
1536
+ def _clear (self , event ):
1537
+ """Internal event handler to clear the buttons."""
1538
+ if self .ignore (event ):
1539
+ return
1540
+ self ._background = self .canvas .copy_from_bbox (self .ax .bbox )
1541
+ self .ax .draw_artist (self ._buttons )
1542
+ if hasattr (self , "_circles" ):
1543
+ for circle in self ._circles :
1544
+ self .ax .draw_artist (circle )
1545
+
1489
1546
def _clicked (self , event ):
1490
1547
if self .ignore (event ) or event .button != 1 or event .inaxes != self .ax :
1491
1548
return
@@ -1524,8 +1581,20 @@ def set_active(self, index):
1524
1581
if hasattr (self , "_circles" ): # Remove once circles is removed.
1525
1582
for i , p in enumerate (self ._circles ):
1526
1583
p .set_facecolor (self .activecolor if i == index else "none" )
1584
+ if self .drawon and self ._useblit :
1585
+ self .ax .draw_artist (p )
1527
1586
if self .drawon :
1528
- self .ax .figure .canvas .draw ()
1587
+ if self ._useblit :
1588
+ if self ._background is not None :
1589
+ self .canvas .restore_region (self ._background )
1590
+ self .ax .draw_artist (self ._buttons )
1591
+ if hasattr (self , "_circles" ):
1592
+ for p in self ._circles :
1593
+ self .ax .draw_artist (p )
1594
+ self .canvas .blit (self .ax .bbox )
1595
+ else :
1596
+ self .canvas .draw ()
1597
+
1529
1598
if self .eventson :
1530
1599
self ._observers .process ('clicked' , self .labels [index ].get_text ())
1531
1600
@@ -1549,7 +1618,8 @@ def circles(self):
1549
1618
circles = self ._circles = [
1550
1619
Circle (xy = self ._buttons .get_offsets ()[i ], edgecolor = "black" ,
1551
1620
facecolor = self ._buttons .get_facecolor ()[i ],
1552
- radius = radius , transform = self .ax .transAxes )
1621
+ radius = radius , transform = self .ax .transAxes ,
1622
+ animated = self ._useblit )
1553
1623
for i in range (len (self .labels ))]
1554
1624
self ._buttons .set_visible (False )
1555
1625
for circle in circles :
0 commit comments