@@ -2238,6 +2238,10 @@ def on_select(min: float, max: float) -> Any
22382238 If `True`, the event triggered outside the span selector will be
22392239 ignored.
22402240
2241+ snap_values : 1D array-like, default: None
2242+ Snap the extents of the selector to the values defined in
2243+ ``snap_values``.
2244+
22412245 Examples
22422246 --------
22432247 >>> import matplotlib.pyplot as plt
@@ -2259,7 +2263,7 @@ def __init__(self, ax, onselect, direction, minspan=0, useblit=False,
22592263 props = None , onmove_callback = None , interactive = False ,
22602264 button = None , handle_props = None , grab_range = 10 ,
22612265 state_modifier_keys = None , drag_from_anywhere = False ,
2262- ignore_event_outside = False ):
2266+ ignore_event_outside = False , snap_values = None ):
22632267
22642268 if state_modifier_keys is None :
22652269 state_modifier_keys = dict (clear = 'escape' ,
@@ -2278,6 +2282,7 @@ def __init__(self, ax, onselect, direction, minspan=0, useblit=False,
22782282
22792283 self .visible = True
22802284 self ._extents_on_press = None
2285+ self .snap_values = snap_values
22812286
22822287 # self._pressv is deprecated and we don't use it internally anymore
22832288 # but we maintain it until it is removed
@@ -2577,6 +2582,16 @@ def _contains(self, event):
25772582 """Return True if event is within the patch."""
25782583 return self ._selection_artist .contains (event , radius = 0 )[0 ]
25792584
2585+ @staticmethod
2586+ def _snap (values , snap_values ):
2587+ """Snap values to a given array values (snap_values)."""
2588+ indices = np .empty_like (values , dtype = "uint" )
2589+ # take into account machine precision
2590+ eps = np .min (np .abs (np .diff (snap_values ))) * 1e-12
2591+ for i , v in enumerate (values ):
2592+ indices [i ] = np .abs (snap_values - v + np .sign (v ) * eps ).argmin ()
2593+ return snap_values [indices ]
2594+
25802595 @property
25812596 def extents (self ):
25822597 """Return extents of the span selector."""
@@ -2591,6 +2606,8 @@ def extents(self):
25912606 @extents .setter
25922607 def extents (self , extents ):
25932608 # Update displayed shape
2609+ if self .snap_values is not None :
2610+ extents = tuple (self ._snap (extents , self .snap_values ))
25942611 self ._draw_shape (* extents )
25952612 if self ._interactive :
25962613 # Update displayed handles
@@ -2857,6 +2874,7 @@ def onselect(eclick: MouseEvent, erelease: MouseEvent)
28572874 use_data_coordinates : bool, default: False
28582875 If `True`, the "square" shape of the selector is defined in
28592876 data coordinates instead of display coordinates.
2877+
28602878 """
28612879
28622880
0 commit comments