@@ -461,31 +461,33 @@ def get_transform(self):
461461
462462class AsinhScale (ScaleBase ):
463463 """
464- A quasi-logarithmic scale based on the inverse hyperbolic sin (asinh)
464+ A quasi-logarithmic scale based on the inverse hyperbolic sine (asinh)
465465
466466 For values close to zero, this is essentially a linear scale,
467- but for larger values (either positive or negative) is asymptotically
467+ but for larger values (either positive or negative) it is asymptotically
468468 logarithmic. The transition between these linear and logarithmic regimes
469469 is smooth, and has no discontinutities in the function gradient
470470 in contrast to the "symlog" scale.
471-
472- Parameters
473- ----------
474- a0 : float, default: 1
475- The scale parameter defining the extent of the quasi-linear region.
476471 """
477472
478473 name = 'asinh'
479474
480475 def __init__ (self , axis , * , a0 = 1.0 , ** kwargs ):
476+ """
477+ Parameters
478+ ----------
479+ a0 : float, default: 1
480+ The scale parameter defining the extent of the quasi-linear region.
481+ """
481482 super ().__init__ (axis )
482483 self .a0 = a0
483484
484485 def get_transform (self ):
485486 return self .AsinhTransform (self .a0 )
486487
487488 def set_default_locators_and_formatters (self , axis ):
488- axis .set (major_locator = AsinhScale .AsinhLocator (self .a0 ), major_formatter = '{x:.3g}' )
489+ axis .set (major_locator = AsinhScale .AsinhLocator (self .a0 ),
490+ major_formatter = '{x:.3g}' )
489491
490492 class AsinhTransform (Transform ):
491493 input_dims = output_dims = 1
@@ -514,24 +516,41 @@ def inverted(self):
514516 return AsinhScale .AsinhTransform (self .a0 )
515517
516518 class AsinhLocator (Locator ):
517- def __init__ (self , a0 ):
519+ """
520+ An axis tick locator specialized for the arcsinh scale
521+
522+ This is very unlikely to have any use beyond the AsinhScale class.
523+ """
524+ def __init__ (self , a0 , apx_tick_count = 12 ):
525+ """
526+ Parameters
527+ ----------
528+ a0 : float
529+ The scale parameter defining the extent of the quasi-linear region.
530+ apx_tick_count : int, default: 12
531+ The approximate number of major ticks that will fit along the entire axis
532+ """
518533 super ().__init__ ()
519534 self .a0 = a0
535+ self .apx_tick_count = apx_tick_count
520536
521537 def __call__ (self ):
522538 dmin , dmax = self .axis .get_data_interval ()
523539 return self .tick_values (dmin , dmax )
524540
525541 def tick_values (self , vmin , vmax ):
526-
542+ # Construct a set of "on-screen" locations that are uniformly spaced:
527543 ymin , ymax = self .a0 * np .arcsinh (np .array ([vmin , vmax ]) / self .a0 )
528- ys = np .linspace (ymin , ymax , 12 )
544+ ys = np .linspace (ymin , ymax , self . apx_tick_count )
529545 if (ymin * ymax ) < 0 :
546+ # Ensure that zero tick-mark is included if the axis stradles zero
530547 ys = np .hstack ([ ys , 0.0 ])
531548
549+ # Transform the "on-screen" grid to the data space:
532550 xs = self .a0 * np .sinh (ys / self .a0 )
533551 zero_xs = (xs == 0 )
534552
553+ # Round the data-space values to be intuitive decimal numbers:
535554 decades = (
536555 np .where (xs >= 0 , 1 , - 1 ) *
537556 np .power (10 , np .where (zero_xs , 1.0 ,
0 commit comments