@@ -987,7 +987,8 @@ class CheckButtons(AxesWidget):
987
987
each box, but have ``set_visible(False)`` when its box is not checked.
988
988
"""
989
989
990
- def __init__ (self , ax , labels , actives = None , * , useblit = True ):
990
+ def __init__ (self , ax , labels , actives = None , * , useblit = True ,
991
+ label_props = None , frame_props = None , check_props = None ):
991
992
"""
992
993
Add check buttons to `matplotlib.axes.Axes` instance *ax*.
993
994
@@ -1003,6 +1004,17 @@ def __init__(self, ax, labels, actives=None, *, useblit=True):
1003
1004
useblit : bool, default: True
1004
1005
Use blitting for faster drawing if supported by the backend.
1005
1006
See the tutorial :doc:`/tutorials/advanced/blitting` for details.
1007
+ label_props : dict or list of dict, optional
1008
+ Dictionary of `.Text` properties to be used for the labels. May
1009
+ also be a list of dictionaries, one for each label.
1010
+ frame_props : dict, optional
1011
+ Dictionary of scatter `.Collection` properties to be used for the
1012
+ check button frame. Defaults to 's' marker, (label font size /
1013
+ 2)**2 size, black edgecolor, no facecolor, and 1.0 linewidth.
1014
+ check_props : dict, optional
1015
+ Dictionary of scatter `.Collection` properties to be used for the
1016
+ check button check. Defaults to 'x' marker, (label font size /
1017
+ 2)**2 size, black color, and 1.0 linewidth.
1006
1018
"""
1007
1019
super ().__init__ (ax )
1008
1020
@@ -1017,22 +1029,49 @@ def __init__(self, ax, labels, actives=None, *, useblit=True):
1017
1029
self ._background = None
1018
1030
1019
1031
ys = np .linspace (1 , 0 , len (labels )+ 2 )[1 :- 1 ]
1020
- text_size = mpl .rcParams ["font.size" ] / 2
1021
1032
1033
+ if label_props is None :
1034
+ label_props = [{}] * len (labels )
1035
+ if isinstance (label_props , dict ):
1036
+ label_props = [label_props ] * len (labels )
1022
1037
self .labels = [
1023
1038
ax .text (0.25 , y , label , transform = ax .transAxes ,
1024
- horizontalalignment = "left" , verticalalignment = "center" )
1025
- for y , label in zip (ys , labels )]
1026
-
1027
- self ._squares = ax .scatter (
1028
- [0.15 ] * len (ys ), ys , marker = 's' , s = text_size ** 2 ,
1029
- c = "none" , linewidth = 1 , transform = ax .transAxes , edgecolor = "k"
1030
- )
1031
- self ._crosses = ax .scatter (
1032
- [0.15 ] * len (ys ), ys , marker = 'x' , linewidth = 1 , s = text_size ** 2 ,
1033
- c = ["k" if active else "none" for active in actives ],
1034
- transform = ax .transAxes , animated = self ._useblit ,
1035
- )
1039
+ horizontalalignment = "left" , verticalalignment = "center" ,
1040
+ ** props )
1041
+ for y , label , props in zip (ys , labels , label_props )]
1042
+ text_size = np .array ([text .get_fontsize () for text in self .labels ]) / 2
1043
+
1044
+ frame_props = {
1045
+ 'marker' : 's' , 's' : text_size ** 2 ,
1046
+ 'facecolor' : 'none' , 'linewidth' : 1 , 'edgecolor' : 'k' ,
1047
+ ** (frame_props or {}),
1048
+ 'transform' : ax .transAxes ,
1049
+ }
1050
+ self ._squares = ax .scatter ([0.15 ] * len (ys ), ys , ** frame_props )
1051
+ check_props = {
1052
+ 'marker' : 'x' , 'linewidth' : 1 , 's' : text_size ** 2 , 'c' : 'k' ,
1053
+ ** (check_props or {}),
1054
+ 'transform' : ax .transAxes ,
1055
+ 'animated' : self ._useblit ,
1056
+ }
1057
+ self ._checks = ax .scatter ([0.15 ] * len (ys ), ys , ** check_props )
1058
+ # The user may have passed custom marker and colours in check_props, so
1059
+ # we need to create the checks, and modify the visibility after getting
1060
+ # whatever the user set.
1061
+ self ._check_edgecolors = self ._checks .get_edgecolor ()
1062
+ if len (self ._check_edgecolors ) == 1 :
1063
+ self ._check_edgecolors = np .repeat (self ._check_edgecolors ,
1064
+ len (labels ), axis = 0 )
1065
+ self ._checks .set_edgecolor (
1066
+ [ec if active else "none"
1067
+ for ec , active in zip (self ._check_edgecolors , actives )])
1068
+ self ._check_facecolors = self ._checks .get_facecolor ()
1069
+ if len (self ._check_facecolors ) == 1 :
1070
+ self ._check_facecolors = np .repeat (self ._check_facecolors ,
1071
+ len (labels ), axis = 0 )
1072
+ self ._checks .set_facecolor (
1073
+ [fc if active else "none"
1074
+ for fc , active in zip (self ._check_facecolors , actives )])
1036
1075
1037
1076
self .connect_event ('button_press_event' , self ._clicked )
1038
1077
if self ._useblit :
@@ -1045,7 +1084,7 @@ def _clear(self, event):
1045
1084
if self .ignore (event ):
1046
1085
return
1047
1086
self ._background = self .canvas .copy_from_bbox (self .ax .bbox )
1048
- self .ax .draw_artist (self ._crosses )
1087
+ self .ax .draw_artist (self ._checks )
1049
1088
if hasattr (self , '_lines' ):
1050
1089
for l1 , l2 in self ._lines :
1051
1090
self .ax .draw_artist (l1 )
@@ -1095,15 +1134,25 @@ def set_active(self, index):
1095
1134
if index not in range (len (self .labels )):
1096
1135
raise ValueError (f'Invalid CheckButton index: { index } ' )
1097
1136
1098
- cross_facecolors = self ._crosses .get_facecolor ()
1099
- cross_facecolors [index ] = colors .to_rgba (
1100
- "black"
1137
+ check_facecolors = self ._checks .get_facecolor ()
1138
+ check_facecolors [index ] = colors .to_rgba (
1139
+ self ._check_facecolors [index ]
1140
+ if colors .same_color (
1141
+ check_facecolors [index ], colors .to_rgba ("none" )
1142
+ )
1143
+ else "none"
1144
+ )
1145
+ self ._checks .set_facecolor (check_facecolors )
1146
+
1147
+ check_edgecolors = self ._checks .get_edgecolor ()
1148
+ check_edgecolors [index ] = colors .to_rgba (
1149
+ self ._check_edgecolors [index ]
1101
1150
if colors .same_color (
1102
- cross_facecolors [index ], colors .to_rgba ("none" )
1151
+ check_edgecolors [index ], colors .to_rgba ("none" )
1103
1152
)
1104
1153
else "none"
1105
1154
)
1106
- self ._crosses . set_facecolor ( cross_facecolors )
1155
+ self ._checks . set_edgecolor ( check_edgecolors )
1107
1156
1108
1157
if hasattr (self , "_lines" ):
1109
1158
l1 , l2 = self ._lines [index ]
@@ -1114,7 +1163,7 @@ def set_active(self, index):
1114
1163
if self ._useblit :
1115
1164
if self ._background is not None :
1116
1165
self .canvas .restore_region (self ._background )
1117
- self .ax .draw_artist (self ._crosses )
1166
+ self .ax .draw_artist (self ._checks )
1118
1167
if hasattr (self , "_lines" ):
1119
1168
for l1 , l2 in self ._lines :
1120
1169
self .ax .draw_artist (l1 )
@@ -1131,7 +1180,7 @@ def get_status(self):
1131
1180
Return a list of the status (True/False) of all of the check buttons.
1132
1181
"""
1133
1182
return [not colors .same_color (color , colors .to_rgba ("none" ))
1134
- for color in self ._crosses .get_facecolors ()]
1183
+ for color in self ._checks .get_facecolors ()]
1135
1184
1136
1185
def on_clicked (self , func ):
1137
1186
"""
@@ -1173,7 +1222,7 @@ def rectangles(self):
1173
1222
def lines (self ):
1174
1223
if not hasattr (self , "_lines" ):
1175
1224
ys = np .linspace (1 , 0 , len (self .labels )+ 2 )[1 :- 1 ]
1176
- self ._crosses .set_visible (False )
1225
+ self ._checks .set_visible (False )
1177
1226
dy = 1. / (len (self .labels ) + 1 )
1178
1227
w , h = dy / 2 , dy / 2
1179
1228
self ._lines = []
@@ -1486,7 +1535,7 @@ class RadioButtons(AxesWidget):
1486
1535
"""
1487
1536
1488
1537
def __init__ (self , ax , labels , active = 0 , activecolor = 'blue' , * ,
1489
- useblit = True ):
1538
+ useblit = True , label_props = None , radio_props = None ):
1490
1539
"""
1491
1540
Add radio buttons to an `~.axes.Axes`.
1492
1541
@@ -1503,6 +1552,14 @@ def __init__(self, ax, labels, active=0, activecolor='blue', *,
1503
1552
useblit : bool, default: True
1504
1553
Use blitting for faster drawing if supported by the backend.
1505
1554
See the tutorial :doc:`/tutorials/advanced/blitting` for details.
1555
+ label_props : dict or list of dict, optional
1556
+ Dictionary of `.Text` properties to be used for the labels. May
1557
+ also be a list of dictionaries, one for each label.
1558
+ radio_props : dict, optional
1559
+ Dictionary of scatter `.Collection` properties to be used for the
1560
+ check button frame. Defaults to 'o' marker, (label font size /
1561
+ 2)**2 size, black edgecolor, and *activecolor* facecolor (when
1562
+ active).
1506
1563
"""
1507
1564
super ().__init__ (ax )
1508
1565
self .activecolor = activecolor
@@ -1513,19 +1570,41 @@ def __init__(self, ax, labels, active=0, activecolor='blue', *,
1513
1570
ax .set_navigate (False )
1514
1571
1515
1572
ys = np .linspace (1 , 0 , len (labels ) + 2 )[1 :- 1 ]
1516
- text_size = mpl .rcParams ["font.size" ] / 2
1517
1573
1518
1574
self ._useblit = useblit and self .canvas .supports_blit
1519
1575
self ._background = None
1520
1576
1577
+ if label_props is None :
1578
+ label_props = [{}] * len (labels )
1579
+ elif isinstance (label_props , dict ):
1580
+ label_props = [label_props ] * len (labels )
1521
1581
self .labels = [
1522
1582
ax .text (0.25 , y , label , transform = ax .transAxes ,
1523
- horizontalalignment = "left" , verticalalignment = "center" )
1524
- for y , label in zip (ys , labels )]
1525
- self ._buttons = ax .scatter (
1526
- [.15 ] * len (ys ), ys , transform = ax .transAxes , s = text_size ** 2 ,
1527
- c = [activecolor if i == active else "none" for i in range (len (ys ))],
1528
- edgecolor = "black" , animated = self ._useblit )
1583
+ horizontalalignment = "left" , verticalalignment = "center" ,
1584
+ ** props )
1585
+ for y , label , props in zip (ys , labels , label_props )]
1586
+ text_size = np .array ([text .get_fontsize () for text in self .labels ]) / 2
1587
+
1588
+ radio_props = {
1589
+ 'marker' : 'o' ,
1590
+ 's' : text_size ** 2 ,
1591
+ 'facecolor' : activecolor ,
1592
+ 'edgecolor' : 'black' ,
1593
+ ** (radio_props or {}),
1594
+ 'transform' : ax .transAxes ,
1595
+ 'animated' : self ._useblit ,
1596
+ }
1597
+ self ._buttons = ax .scatter ([.15 ] * len (ys ), ys , ** radio_props )
1598
+ # The user may have passed custom marker and colours in radio_props, so
1599
+ # we need to create the radios, and modify the visibility after getting
1600
+ # whatever the user set.
1601
+ self ._active_colors = self ._buttons .get_facecolor ()
1602
+ if len (self ._active_colors ) == 1 :
1603
+ self ._active_colors = np .repeat (self ._active_colors , len (labels ),
1604
+ axis = 0 )
1605
+ self ._buttons .set_facecolor (
1606
+ [activecolor if i == active else "none"
1607
+ for i , activecolor in enumerate (self ._active_colors )])
1529
1608
1530
1609
self .connect_event ('button_press_event' , self ._clicked )
1531
1610
if self ._useblit :
@@ -1576,7 +1655,7 @@ def set_active(self, index):
1576
1655
self .value_selected = self .labels [index ].get_text ()
1577
1656
button_facecolors = self ._buttons .get_facecolor ()
1578
1657
button_facecolors [:] = colors .to_rgba ("none" )
1579
- button_facecolors [index ] = colors .to_rgba (self .activecolor )
1658
+ button_facecolors [index ] = colors .to_rgba (self ._active_colors [ index ] )
1580
1659
self ._buttons .set_facecolor (button_facecolors )
1581
1660
if hasattr (self , "_circles" ): # Remove once circles is removed.
1582
1661
for i , p in enumerate (self ._circles ):
0 commit comments