@@ -1404,41 +1404,25 @@ def __init__(self, ax, labels, active=0, activecolor='blue'):
1404
1404
"""
1405
1405
super ().__init__ (ax )
1406
1406
self .activecolor = activecolor
1407
- self .value_selected = None
1407
+ self .value_selected = labels [ active ]
1408
1408
1409
1409
ax .set_xticks ([])
1410
1410
ax .set_yticks ([])
1411
1411
ax .set_navigate (False )
1412
- dy = 1. / (len (labels ) + 1 )
1413
- ys = np .linspace (1 - dy , dy , len (labels ))
1414
- cnt = 0
1415
- axcolor = ax .get_facecolor ()
1416
1412
1417
- # scale the radius of the circle with the spacing between each one
1418
- circle_radius = dy / 2 - 0.01
1419
- # default to hard-coded value if the radius becomes too large
1420
- circle_radius = min (circle_radius , 0.05 )
1413
+ ys = np .linspace (1 , 0 , len (labels ) + 2 )[1 :- 1 ]
1414
+ text_size = mpl .rcParams ["font.size" ] / 2
1421
1415
1422
1416
self .labels = []
1423
- self .circles = []
1424
1417
for y , label in zip (ys , labels ):
1425
1418
t = ax .text (0.25 , y , label , transform = ax .transAxes ,
1426
1419
horizontalalignment = 'left' ,
1427
1420
verticalalignment = 'center' )
1428
-
1429
- if cnt == active :
1430
- self .value_selected = label
1431
- facecolor = activecolor
1432
- else :
1433
- facecolor = axcolor
1434
-
1435
- p = Circle (xy = (0.15 , y ), radius = circle_radius , edgecolor = 'black' ,
1436
- facecolor = facecolor , transform = ax .transAxes )
1437
-
1438
1421
self .labels .append (t )
1439
- self .circles .append (p )
1440
- ax .add_patch (p )
1441
- cnt += 1
1422
+ self ._buttons = ax .scatter (
1423
+ [.15 ] * len (ys ), ys , transform = ax .transAxes , s = text_size ** 2 ,
1424
+ c = [activecolor if i == active else "none" for i in range (len (ys ))],
1425
+ edgecolor = "black" )
1442
1426
1443
1427
self .connect_event ('button_press_event' , self ._clicked )
1444
1428
@@ -1448,11 +1432,20 @@ def _clicked(self, event):
1448
1432
if self .ignore (event ) or event .button != 1 or event .inaxes != self .ax :
1449
1433
return
1450
1434
pclicked = self .ax .transAxes .inverted ().transform ((event .x , event .y ))
1435
+ _ , inds = self ._buttons .contains (event )
1436
+ coords = self ._buttons .get_offset_transform ().transform (
1437
+ self ._buttons .get_offsets ())
1451
1438
distances = {}
1452
- for i , (p , t ) in enumerate (zip (self .circles , self .labels )):
1453
- if (t .get_window_extent ().contains (event .x , event .y )
1454
- or np .linalg .norm (pclicked - p .center ) < p .radius ):
1455
- distances [i ] = np .linalg .norm (pclicked - p .center )
1439
+ if hasattr (self , "_circles" ): # Remove once circles is removed.
1440
+ for i , (p , t ) in enumerate (zip (self ._circles , self .labels )):
1441
+ if (t .get_window_extent ().contains (event .x , event .y )
1442
+ or np .linalg .norm (pclicked - p .center ) < p .radius ):
1443
+ distances [i ] = np .linalg .norm (pclicked - p .center )
1444
+ else :
1445
+ for i , t in enumerate (self .labels ):
1446
+ if (i in inds ["ind" ]
1447
+ or t .get_window_extent ().contains (event .x , event .y )):
1448
+ distances [i ] = np .linalg .norm (pclicked - coords [i ])
1456
1449
if len (distances ) > 0 :
1457
1450
closest = min (distances , key = distances .get )
1458
1451
self .set_active (closest )
@@ -1465,19 +1458,14 @@ def set_active(self, index):
1465
1458
"""
1466
1459
if index not in range (len (self .labels )):
1467
1460
raise ValueError (f'Invalid RadioButton index: { index } ' )
1468
-
1469
1461
self .value_selected = self .labels [index ].get_text ()
1470
-
1471
- for i , p in enumerate (self .circles ):
1472
- if i == index :
1473
- color = self .activecolor
1474
- else :
1475
- color = self .ax .get_facecolor ()
1476
- p .set_facecolor (color )
1477
-
1462
+ self ._buttons .get_facecolor ()[:] = colors .to_rgba ("none" )
1463
+ self ._buttons .get_facecolor ()[index ] = colors .to_rgba (self .activecolor )
1464
+ if hasattr (self , "_circles" ): # Remove once circles is removed.
1465
+ for i , p in enumerate (self ._circles ):
1466
+ p .set_facecolor (self .activecolor if i == index else "none" )
1478
1467
if self .drawon :
1479
1468
self .ax .figure .canvas .draw ()
1480
-
1481
1469
if self .eventson :
1482
1470
self ._observers .process ('clicked' , self .labels [index ].get_text ())
1483
1471
@@ -1493,6 +1481,20 @@ def disconnect(self, cid):
1493
1481
"""Remove the observer with connection id *cid*."""
1494
1482
self ._observers .disconnect (cid )
1495
1483
1484
+ @_api .deprecated ("3.7" )
1485
+ @property
1486
+ def circles (self ):
1487
+ radius = min (.5 / (len (self .labels ) + 1 ) - .01 , .05 )
1488
+ circles = self ._circles = [
1489
+ Circle (xy = self ._buttons .get_offsets ()[i ], edgecolor = "black" ,
1490
+ facecolor = self ._buttons .get_facecolor ()[i ],
1491
+ radius = radius , transform = self .ax .transAxes )
1492
+ for i in range (len (self .labels )) ]
1493
+ self ._buttons .set_visible (False )
1494
+ for circle in self ._circles :
1495
+ self .ax .add_patch (circle )
1496
+ return circles
1497
+
1496
1498
1497
1499
class SubplotTool (Widget ):
1498
1500
"""
0 commit comments