@@ -458,6 +458,75 @@ def get_transform(self):
458
458
return self ._transform
459
459
460
460
461
+
462
+ class AsinhScale (ScaleBase ):
463
+ name = 'asinh'
464
+
465
+ def __init__ (self , axis , * , a0 = 1.0 , ** kwargs ):
466
+ super ().__init__ (axis )
467
+ self .a0 = a0
468
+
469
+ def get_transform (self ):
470
+ return self .AsinhTransform (self .a0 )
471
+
472
+ def set_default_locators_and_formatters (self , axis ):
473
+ axis .set (major_locator = AsinhScale .AsinhLocator (self .a0 ), major_formatter = '{x:.3g}' )
474
+
475
+ class AsinhTransform (Transform ):
476
+ input_dims = output_dims = 1
477
+
478
+ def __init__ (self , a0 ):
479
+ matplotlib .transforms .Transform .__init__ (self )
480
+ self .a0 = a0
481
+
482
+ def transform_non_affine (self , a ):
483
+ return self .a0 * np .arcsinh (a / self .a0 )
484
+
485
+ def inverted (self ):
486
+ return AsinhScale .InvertedAsinhTransform (self .a0 )
487
+
488
+ class InvertedAsinhTransform (Transform ):
489
+ input_dims = output_dims = 1
490
+
491
+ def __init__ (self , a0 ):
492
+ matplotlib .transforms .Transform .__init__ (self )
493
+ self .a0 = a0
494
+
495
+ def transform_non_affine (self , a ):
496
+ return self .a0 * np .sinh (a / self .a0 )
497
+
498
+ def inverted (self ):
499
+ return AsinhScale .AsinhTransform (self .a0 )
500
+
501
+ class AsinhLocator (matplotlib .ticker .Locator ):
502
+ def __init__ (self , a0 ):
503
+ super ().__init__ ()
504
+ self .a0 = a0
505
+
506
+ def __call__ (self ):
507
+ dmin , dmax = self .axis .get_data_interval ()
508
+ return self .tick_values (dmin , dmax )
509
+
510
+ def tick_values (self , vmin , vmax ):
511
+
512
+ ymin , ymax = self .a0 * np .arcsinh (np .array ([vmin , vmax ]) / self .a0 )
513
+ ys = np .linspace (ymin , ymax , 12 )
514
+ if (ymin * ymax ) < 0 :
515
+ ys = np .hstack ([ ys , 0.0 ])
516
+
517
+ xs = self .a0 * np .sinh (ys / self .a0 )
518
+
519
+ decades = (
520
+ np .where (xs >= 0 , 1 , - 1 ) *
521
+ np .power (10 , np .where (xs == 0 , 1.0 ,
522
+ np .floor (np .log10 (np .abs (xs )))))
523
+ )
524
+ qs = decades * np .round (xs / decades )
525
+
526
+ return np .array (sorted (set (qs )))
527
+
528
+
529
+
461
530
class LogitTransform (Transform ):
462
531
input_dims = output_dims = 1
463
532
@@ -568,6 +637,7 @@ def limit_range_for_scale(self, vmin, vmax, minpos):
568
637
'linear' : LinearScale ,
569
638
'log' : LogScale ,
570
639
'symlog' : SymmetricalLogScale ,
640
+ 'asinh' : AsinhScale ,
571
641
'logit' : LogitScale ,
572
642
'function' : FuncScale ,
573
643
'functionlog' : FuncScaleLog ,
0 commit comments