@@ -267,9 +267,9 @@ def __init__(self, ax, orientation, closedmin, closedmax,
267
267
self ._fmt .set_useOffset (False ) # No additive offset.
268
268
self ._fmt .set_useMathText (True ) # x sign before multiplicative offset.
269
269
270
- ax .set_xticks ([])
271
- ax .set_yticks ([])
270
+ ax .set_axis_off ()
272
271
ax .set_navigate (False )
272
+
273
273
self .connect_event ("button_press_event" , self ._update )
274
274
self .connect_event ("button_release_event" , self ._update )
275
275
if dragging :
@@ -329,7 +329,9 @@ class Slider(SliderBase):
329
329
def __init__ (self , ax , label , valmin , valmax , valinit = 0.5 , valfmt = None ,
330
330
closedmin = True , closedmax = True , slidermin = None ,
331
331
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 ):
333
335
"""
334
336
Parameters
335
337
----------
@@ -380,6 +382,19 @@ def __init__(self, ax, label, valmin, valmax, valinit=0.5, valfmt=None,
380
382
The color of the line at the *valinit* position. Set to ``'none'``
381
383
for no line.
382
384
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
+
383
398
Notes
384
399
-----
385
400
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,
404
419
self .val = valinit
405
420
self .valinit = valinit
406
421
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 ]]
409
431
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
+ )
412
449
413
450
if orientation == 'vertical' :
414
451
self .label = ax .text (0.5 , 1.02 , label , transform = ax .transAxes ,
@@ -499,11 +536,13 @@ def set_val(self, val):
499
536
"""
500
537
xy = self .poly .xy
501
538
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 ])
504
542
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 ])
507
546
self .poly .xy = xy
508
547
self .valtext .set_text (self ._format (val ))
509
548
if self .drawon :
@@ -558,6 +597,10 @@ def __init__(
558
597
dragging = True ,
559
598
valstep = None ,
560
599
orientation = "horizontal" ,
600
+ track_color = 'lightgrey' ,
601
+ handle_facecolor = 'white' ,
602
+ handle_edgecolor = '.75' ,
603
+ handle_size = 10 ,
561
604
** kwargs ,
562
605
):
563
606
"""
@@ -598,6 +641,19 @@ def __init__(
598
641
orientation : {'horizontal', 'vertical'}, default: 'horizontal'
599
642
The orientation of the slider.
600
643
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
+
601
657
Notes
602
658
-----
603
659
Additional kwargs are passed on to ``self.poly`` which is the
@@ -619,9 +675,43 @@ def __init__(
619
675
self .val = valinit
620
676
self .valinit = valinit
621
677
if orientation == "vertical" :
678
+ self .track = Rectangle (
679
+ (.25 , 0 ), .5 , 2 ,
680
+ transform = ax .transAxes ,
681
+ facecolor = track_color
682
+ )
683
+ ax .add_patch (self .track )
622
684
self .poly = ax .axhspan (valinit [0 ], valinit [1 ], 0 , 1 , ** kwargs )
685
+ handleXY_1 = [.5 , valinit [0 ]]
686
+ handleXY_2 = [.5 , valinit [1 ]]
623
687
else :
688
+ self .track = Rectangle (
689
+ (0 , .25 ), 1 , .5 ,
690
+ transform = ax .transAxes ,
691
+ facecolor = track_color
692
+ )
693
+ ax .add_patch (self .track )
624
694
self .poly = ax .axvspan (valinit [0 ], valinit [1 ], 0 , 1 , ** kwargs )
695
+ handleXY_1 = [valinit [0 ], .5 ]
696
+ handleXY_2 = [valinit [1 ], .5 ]
697
+ self ._handles = [
698
+ ax .plot (
699
+ * handleXY_1 ,
700
+ "o" ,
701
+ markersize = handle_size ,
702
+ markeredgecolor = handle_edgecolor ,
703
+ markerfacecolor = handle_facecolor ,
704
+ clip_on = False
705
+ )[0 ],
706
+ ax .plot (
707
+ * handleXY_2 ,
708
+ "o" ,
709
+ markersize = handle_size ,
710
+ markeredgecolor = handle_edgecolor ,
711
+ markerfacecolor = handle_facecolor ,
712
+ clip_on = False
713
+ )[0 ]
714
+ ]
625
715
626
716
if orientation == "vertical" :
627
717
self .label = ax .text (
@@ -660,6 +750,7 @@ def __init__(
660
750
horizontalalignment = "left" ,
661
751
)
662
752
753
+ self ._active_handle = None
663
754
self .set_val (valinit )
664
755
665
756
def _min_in_bounds (self , min ):
@@ -696,6 +787,8 @@ def _update_val_from_pos(self, pos):
696
787
else :
697
788
val = self ._max_in_bounds (pos )
698
789
self .set_max (val )
790
+ if self ._active_handle :
791
+ self ._active_handle .set_xdata ([val ])
699
792
700
793
def _update (self , event ):
701
794
"""Update the slider position."""
@@ -714,7 +807,20 @@ def _update(self, event):
714
807
):
715
808
self .drag_active = False
716
809
event .canvas .release_mouse (self .ax )
810
+ self ._active_handle = None
717
811
return
812
+
813
+ # determine which handle was grabbed
814
+ handle = self ._handles [
815
+ np .argmin (
816
+ np .abs ([h .get_xdata ()[0 ] - event .xdata for h in self ._handles ])
817
+ )
818
+ ]
819
+ # these checks ensure smooth behavior if the handles swap which one
820
+ # has a higher value. i.e. if one is dragged over and past the other.
821
+ if handle is not self ._active_handle :
822
+ self ._active_handle = handle
823
+
718
824
if self .orientation == "vertical" :
719
825
self ._update_val_from_pos (event .ydata )
720
826
else :
@@ -771,17 +877,17 @@ def set_val(self, val):
771
877
val [1 ] = self ._max_in_bounds (val [1 ])
772
878
xy = self .poly .xy
773
879
if self .orientation == "vertical" :
774
- xy [0 ] = 0 , val [0 ]
775
- xy [1 ] = 0 , val [1 ]
776
- xy [2 ] = 1 , val [1 ]
777
- xy [3 ] = 1 , val [0 ]
778
- xy [4 ] = 0 , val [0 ]
880
+ xy [0 ] = .25 , val [0 ]
881
+ xy [1 ] = .25 , val [1 ]
882
+ xy [2 ] = .75 , val [1 ]
883
+ xy [3 ] = .75 , val [0 ]
884
+ xy [4 ] = .25 , val [0 ]
779
885
else :
780
- xy [0 ] = val [0 ], 0
781
- xy [1 ] = val [0 ], 1
782
- xy [2 ] = val [1 ], 1
783
- xy [3 ] = val [1 ], 0
784
- xy [4 ] = val [0 ], 0
886
+ xy [0 ] = val [0 ], .25
887
+ xy [1 ] = val [0 ], .75
888
+ xy [2 ] = val [1 ], .75
889
+ xy [3 ] = val [1 ], .25
890
+ xy [4 ] = val [0 ], .25
785
891
self .poly .xy = xy
786
892
self .valtext .set_text (self ._format (val ))
787
893
if self .drawon :
0 commit comments