2222from matplotlib import _api , docstring
2323from matplotlib .ticker import (
2424 NullFormatter , ScalarFormatter , LogFormatterSciNotation , LogitFormatter ,
25- NullLocator , LogLocator , AutoLocator , AutoMinorLocator ,
25+ Locator , NullLocator , LogLocator , AutoLocator , AutoMinorLocator ,
2626 SymmetricalLogLocator , LogitLocator )
2727from matplotlib .transforms import Transform , IdentityTransform
2828
@@ -460,6 +460,21 @@ def get_transform(self):
460460
461461
462462class AsinhScale (ScaleBase ):
463+ """
464+ A quasi-logarithmic scale based on the inverse hyperbolic sin (asinh)
465+
466+ For values close to zero, this is essentially a linear scale,
467+ but for larger values (either positive or negative) is asymptotically
468+ logarithmic. The transition between these linear and logarithmic regimes
469+ is smooth, and has no discontinutities in the function gradient
470+ 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.
476+ """
477+
463478 name = 'asinh'
464479
465480 def __init__ (self , axis , * , a0 = 1.0 , ** kwargs ):
@@ -476,7 +491,7 @@ class AsinhTransform(Transform):
476491 input_dims = output_dims = 1
477492
478493 def __init__ (self , a0 ):
479- matplotlib . transforms . Transform . __init__ (self )
494+ super (). __init__ ()
480495 self .a0 = a0
481496
482497 def transform_non_affine (self , a ):
@@ -489,7 +504,7 @@ class InvertedAsinhTransform(Transform):
489504 input_dims = output_dims = 1
490505
491506 def __init__ (self , a0 ):
492- matplotlib . transforms . Transform . __init__ (self )
507+ super (). __init__ ()
493508 self .a0 = a0
494509
495510 def transform_non_affine (self , a ):
@@ -498,7 +513,7 @@ def transform_non_affine(self, a):
498513 def inverted (self ):
499514 return AsinhScale .AsinhTransform (self .a0 )
500515
501- class AsinhLocator (matplotlib . ticker . Locator ):
516+ class AsinhLocator (Locator ):
502517 def __init__ (self , a0 ):
503518 super ().__init__ ()
504519 self .a0 = a0
@@ -515,11 +530,12 @@ def tick_values(self, vmin, vmax):
515530 ys = np .hstack ([ ys , 0.0 ])
516531
517532 xs = self .a0 * np .sinh (ys / self .a0 )
533+ zero_xs = (xs == 0 )
518534
519535 decades = (
520536 np .where (xs >= 0 , 1 , - 1 ) *
521- np .power (10 , np .where (xs == 0 , 1.0 ,
522- np .floor (np .log10 (np .abs (xs )))))
537+ np .power (10 , np .where (zero_xs , 1.0 ,
538+ np .floor (np .log10 (np .abs (xs ) + zero_xs * 1e-6 ))))
523539 )
524540 qs = decades * np .round (xs / decades )
525541
0 commit comments