@@ -1404,41 +1404,25 @@ def __init__(self, ax, labels, active=0, activecolor='blue'):
14041404 """
14051405 super ().__init__ (ax )
14061406 self .activecolor = activecolor
1407- self .value_selected = None
1407+ self .value_selected = labels [ active ]
14081408
14091409 ax .set_xticks ([])
14101410 ax .set_yticks ([])
14111411 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 ()
14161412
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
14211415
14221416 self .labels = []
1423- self .circles = []
14241417 for y , label in zip (ys , labels ):
14251418 t = ax .text (0.25 , y , label , transform = ax .transAxes ,
14261419 horizontalalignment = 'left' ,
14271420 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-
14381421 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" )
14421426
14431427 self .connect_event ('button_press_event' , self ._clicked )
14441428
@@ -1448,11 +1432,20 @@ def _clicked(self, event):
14481432 if self .ignore (event ) or event .button != 1 or event .inaxes != self .ax :
14491433 return
14501434 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 ())
14511438 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 ])
14561449 if len (distances ) > 0 :
14571450 closest = min (distances , key = distances .get )
14581451 self .set_active (closest )
@@ -1465,19 +1458,14 @@ def set_active(self, index):
14651458 """
14661459 if index not in range (len (self .labels )):
14671460 raise ValueError (f'Invalid RadioButton index: { index } ' )
1468-
14691461 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" )
14781467 if self .drawon :
14791468 self .ax .figure .canvas .draw ()
1480-
14811469 if self .eventson :
14821470 self ._observers .process ('clicked' , self .labels [index ].get_text ())
14831471
@@ -1493,6 +1481,20 @@ def disconnect(self, cid):
14931481 """Remove the observer with connection id *cid*."""
14941482 self ._observers .disconnect (cid )
14951483
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+
14961498
14971499class SubplotTool (Widget ):
14981500 """
0 commit comments