@@ -267,9 +267,9 @@ def __init__(self, ax, orientation, closedmin, closedmax,
267267 self ._fmt .set_useOffset (False ) # No additive offset.
268268 self ._fmt .set_useMathText (True ) # x sign before multiplicative offset.
269269
270- ax .set_xticks ([])
271- ax .set_yticks ([])
270+ ax .set_axis_off ()
272271 ax .set_navigate (False )
272+
273273 self .connect_event ("button_press_event" , self ._update )
274274 self .connect_event ("button_release_event" , self ._update )
275275 if dragging :
@@ -329,7 +329,9 @@ class Slider(SliderBase):
329329 def __init__ (self , ax , label , valmin , valmax , valinit = 0.5 , valfmt = None ,
330330 closedmin = True , closedmax = True , slidermin = None ,
331331 slidermax = None , dragging = True , valstep = None ,
332- orientation = 'horizontal' , * , initcolor = 'r' , ** kwargs ):
332+ orientation = 'horizontal' , * , initcolor = 'r' ,
333+ track_color = 'lightgrey' , handle_facecolor = 'white' ,
334+ handle_edgecolor = '.75' , handle_size = 10 , ** kwargs ):
333335 """
334336 Parameters
335337 ----------
@@ -380,6 +382,19 @@ def __init__(self, ax, label, valmin, valmax, valinit=0.5, valfmt=None,
380382 The color of the line at the *valinit* position. Set to ``'none'``
381383 for no line.
382384
385+ track_color : color, default: 'lightgrey'
386+ The color of the background track. The track is accessible for
387+ further styling via the *track* attribute.
388+
389+ handle_facecolor : color, default: 'white'
390+ The facecolor of the circular slider handle.
391+
392+ handle_edgecolor : color, default: '.75'
393+ The edgecolor of the circle slider handle.
394+
395+ handle_size : int, default: 10
396+ The size of the circular slider handle in points.
397+
383398 Notes
384399 -----
385400 Additional kwargs are passed on to ``self.poly`` which is the
@@ -404,11 +419,33 @@ def __init__(self, ax, label, valmin, valmax, valinit=0.5, valfmt=None,
404419 self .val = valinit
405420 self .valinit = valinit
406421 if orientation == 'vertical' :
407- self .poly = ax .axhspan (valmin , valinit , 0 , 1 , ** kwargs )
408- self .hline = ax .axhline (valinit , 0 , 1 , color = initcolor , lw = 1 )
422+ self .track = Rectangle (
423+ (.25 , 0 ), .5 , 1 ,
424+ transform = ax .transAxes ,
425+ facecolor = track_color
426+ )
427+ ax .add_patch (self .track )
428+ self .poly = ax .axhspan (valmin , valinit , .25 , .75 , ** kwargs )
429+ self .hline = ax .axhline (valinit , .25 , .75 , color = initcolor , lw = 1 )
430+ handleXY = [[0.5 ], [valinit ]]
409431 else :
410- self .poly = ax .axvspan (valmin , valinit , 0 , 1 , ** kwargs )
411- self .vline = ax .axvline (valinit , 0 , 1 , color = initcolor , lw = 1 )
432+ self .track = Rectangle (
433+ (0 , .25 ), 1 , .5 ,
434+ transform = ax .transAxes ,
435+ facecolor = track_color
436+ )
437+ ax .add_patch (self .track )
438+ self .poly = ax .axvspan (valmin , valinit , .25 , .75 , ** kwargs )
439+ self .vline = ax .axvline (valinit , .25 , .75 , color = initcolor , lw = 1 )
440+ handleXY = [[valinit ], [0.5 ]]
441+ self ._handle , = ax .plot (
442+ * handleXY ,
443+ "o" ,
444+ markersize = handle_size ,
445+ markeredgecolor = handle_edgecolor ,
446+ markerfacecolor = handle_facecolor ,
447+ clip_on = False
448+ )
412449
413450 if orientation == 'vertical' :
414451 self .label = ax .text (0.5 , 1.02 , label , transform = ax .transAxes ,
@@ -499,11 +536,13 @@ def set_val(self, val):
499536 """
500537 xy = self .poly .xy
501538 if self .orientation == 'vertical' :
502- xy [1 ] = 0 , val
503- xy [2 ] = 1 , val
539+ xy [1 ] = .25 , val
540+ xy [2 ] = .75 , val
541+ self ._handle .set_ydata ([val ])
504542 else :
505- xy [2 ] = val , 1
506- xy [3 ] = val , 0
543+ xy [2 ] = val , .75
544+ xy [3 ] = val , .25
545+ self ._handle .set_xdata ([val ])
507546 self .poly .xy = xy
508547 self .valtext .set_text (self ._format (val ))
509548 if self .drawon :
@@ -558,6 +597,10 @@ def __init__(
558597 dragging = True ,
559598 valstep = None ,
560599 orientation = "horizontal" ,
600+ track_color = 'lightgrey' ,
601+ handle_facecolor = 'white' ,
602+ handle_edgecolor = '.75' ,
603+ handle_size = 10 ,
561604 ** kwargs ,
562605 ):
563606 """
@@ -598,6 +641,19 @@ def __init__(
598641 orientation : {'horizontal', 'vertical'}, default: 'horizontal'
599642 The orientation of the slider.
600643
644+ track_color : color, default: 'lightgrey'
645+ The color of the background track. The track is accessible for
646+ further styling via the *track* attribute.
647+
648+ handle_facecolor : color, default: 'white'
649+ The facecolor of the circular slider handle.
650+
651+ handle_edgecolor : color, default: '.75'
652+ The edgecolor of the circular slider handles.
653+
654+ handle_size : int, default: 10
655+ The size of the circular slider handles in points.
656+
601657 Notes
602658 -----
603659 Additional kwargs are passed on to ``self.poly`` which is the
@@ -620,9 +676,43 @@ def __init__(
620676 self .val = valinit
621677 self .valinit = valinit
622678 if orientation == "vertical" :
679+ self .track = Rectangle (
680+ (.25 , 0 ), .5 , 2 ,
681+ transform = ax .transAxes ,
682+ facecolor = track_color
683+ )
684+ ax .add_patch (self .track )
623685 self .poly = ax .axhspan (valinit [0 ], valinit [1 ], 0 , 1 , ** kwargs )
686+ handleXY_1 = [.5 , valinit [0 ]]
687+ handleXY_2 = [.5 , valinit [1 ]]
624688 else :
689+ self .track = Rectangle (
690+ (0 , .25 ), 1 , .5 ,
691+ transform = ax .transAxes ,
692+ facecolor = track_color
693+ )
694+ ax .add_patch (self .track )
625695 self .poly = ax .axvspan (valinit [0 ], valinit [1 ], 0 , 1 , ** kwargs )
696+ handleXY_1 = [valinit [0 ], .5 ]
697+ handleXY_2 = [valinit [1 ], .5 ]
698+ self ._handles = [
699+ ax .plot (
700+ * handleXY_1 ,
701+ "o" ,
702+ markersize = handle_size ,
703+ markeredgecolor = handle_edgecolor ,
704+ markerfacecolor = handle_facecolor ,
705+ clip_on = False
706+ )[0 ],
707+ ax .plot (
708+ * handleXY_2 ,
709+ "o" ,
710+ markersize = handle_size ,
711+ markeredgecolor = handle_edgecolor ,
712+ markerfacecolor = handle_facecolor ,
713+ clip_on = False
714+ )[0 ]
715+ ]
626716
627717 if orientation == "vertical" :
628718 self .label = ax .text (
@@ -661,6 +751,7 @@ def __init__(
661751 horizontalalignment = "left" ,
662752 )
663753
754+ self ._active_handle = None
664755 self .set_val (valinit )
665756
666757 def _min_in_bounds (self , min ):
@@ -698,6 +789,8 @@ def _update_val_from_pos(self, pos):
698789 else :
699790 val = self ._max_in_bounds (pos )
700791 self .set_max (val )
792+ if self ._active_handle :
793+ self ._active_handle .set_xdata ([val ])
701794
702795 def _update (self , event ):
703796 """Update the slider position."""
@@ -716,7 +809,20 @@ def _update(self, event):
716809 ):
717810 self .drag_active = False
718811 event .canvas .release_mouse (self .ax )
812+ self ._active_handle = None
719813 return
814+
815+ # determine which handle was grabbed
816+ handle = self ._handles [
817+ np .argmin (
818+ np .abs ([h .get_xdata ()[0 ] - event .xdata for h in self ._handles ])
819+ )
820+ ]
821+ # these checks ensure smooth behavior if the handles swap which one
822+ # has a higher value. i.e. if one is dragged over and past the other.
823+ if handle is not self ._active_handle :
824+ self ._active_handle = handle
825+
720826 if self .orientation == "vertical" :
721827 self ._update_val_from_pos (event .ydata )
722828 else :
@@ -773,17 +879,17 @@ def set_val(self, val):
773879 val [1 ] = self ._max_in_bounds (val [1 ])
774880 xy = self .poly .xy
775881 if self .orientation == "vertical" :
776- xy [0 ] = 0 , val [0 ]
777- xy [1 ] = 0 , val [1 ]
778- xy [2 ] = 1 , val [1 ]
779- xy [3 ] = 1 , val [0 ]
780- xy [4 ] = 0 , val [0 ]
882+ xy [0 ] = .25 , val [0 ]
883+ xy [1 ] = .25 , val [1 ]
884+ xy [2 ] = .75 , val [1 ]
885+ xy [3 ] = .75 , val [0 ]
886+ xy [4 ] = .25 , val [0 ]
781887 else :
782- xy [0 ] = val [0 ], 0
783- xy [1 ] = val [0 ], 1
784- xy [2 ] = val [1 ], 1
785- xy [3 ] = val [1 ], 0
786- xy [4 ] = val [0 ], 0
888+ xy [0 ] = val [0 ], .25
889+ xy [1 ] = val [0 ], .75
890+ xy [2 ] = val [1 ], .75
891+ xy [3 ] = val [1 ], .25
892+ xy [4 ] = val [0 ], .25
787893 self .poly .xy = xy
788894 self .valtext .set_text (self ._format (val ))
789895 if self .drawon :
0 commit comments