@@ -317,51 +317,55 @@ class SymmetricalLogTransform(Transform):
317
317
output_dims = 1
318
318
is_separable = True
319
319
320
- def __init__ (self , base , linthresh ):
320
+ def __init__ (self , base , linthresh , linscale ):
321
321
Transform .__init__ (self )
322
322
self .base = base
323
323
self .linthresh = linthresh
324
+ self .linscale = linscale
325
+ self ._linscale_adj = (linscale / (1.0 - self .base ** - 1 ))
324
326
self ._log_base = np .log (base )
325
- self ._linadjust = (np .log (linthresh ) / self ._log_base ) / linthresh
326
327
327
328
def transform (self , a ):
328
329
sign = np .sign (a )
329
330
masked = ma .masked_inside (a , - self .linthresh , self .linthresh , copy = False )
330
- log = sign * self .linthresh * (1 + ma .log (np .abs (masked ) / self .linthresh ))
331
+ log = sign * self .linthresh * (
332
+ self ._linscale_adj +
333
+ ma .log (np .abs (masked ) / self .linthresh ) / self ._log_base )
331
334
if masked .mask .any ():
332
- return ma .where (masked .mask , a , log )
335
+ return ma .where (masked .mask , a * self . _linscale_adj , log )
333
336
else :
334
337
return log
335
338
336
339
def inverted (self ):
337
340
return SymmetricalLogScale .InvertedSymmetricalLogTransform (
338
- self .base , self .linthresh )
341
+ self .base , self .linthresh , self . linscale )
339
342
340
343
class InvertedSymmetricalLogTransform (Transform ):
341
344
input_dims = 1
342
345
output_dims = 1
343
346
is_separable = True
344
347
345
- def __init__ (self , base , linthresh ):
348
+ def __init__ (self , base , linthresh , linscale ):
346
349
Transform .__init__ (self )
347
350
self .base = base
348
351
self .linthresh = linthresh
349
- log_base = np .log (base )
350
- logb_linthresh = np .log (linthresh ) / log_base
351
- self ._linadjust = 1.0 - logb_linthresh
352
+ self .linscale = linscale
353
+ self ._linscale_adj = (linscale / (1.0 - self .base ** - 1 ))
352
354
353
355
def transform (self , a ):
354
356
sign = np .sign (a )
355
357
masked = ma .masked_inside (a , - self .linthresh , self .linthresh , copy = False )
356
- exp = sign * self .linthresh * ma .exp (sign * masked / self .linthresh - 1 )
358
+ exp = sign * self .linthresh * (
359
+ ma .power (self .base , sign * (masked / self .linthresh ))
360
+ - self ._linscale_adj )
357
361
if masked .mask .any ():
358
- return ma .where (masked .mask , a , exp )
362
+ return ma .where (masked .mask , a / self . _linscale_adj , exp )
359
363
else :
360
364
return exp
361
365
362
366
def inverted (self ):
363
367
return SymmetricalLogScale .SymmetricalLogTransform (
364
- self .base , self .linthresh )
368
+ self .base , self .linthresh , self . linscale )
365
369
366
370
def __init__ (self , axis , ** kwargs ):
367
371
"""
@@ -379,22 +383,36 @@ def __init__(self, axis, **kwargs):
379
383
380
384
will place 8 logarithmically spaced minor ticks between
381
385
each major tick.
386
+
387
+ *linscalex*/*linscaley*:
388
+ This allows the linear range (-*linthresh* to *linthresh*)
389
+ to be stretched relative to the logarithmic range. Its
390
+ value is the number of decades to use for each half of the
391
+ linear range. For example, when *linscale* == 1.0 (the
392
+ default), the space used for the positive and negative
393
+ halves of the linear range will be equal to one decade in
394
+ the logarithmic range.
382
395
"""
383
396
if axis .axis_name == 'x' :
384
397
base = kwargs .pop ('basex' , 10.0 )
385
398
linthresh = kwargs .pop ('linthreshx' , 2.0 )
386
399
subs = kwargs .pop ('subsx' , None )
400
+ linscale = kwargs .pop ('linscalex' , 1.0 )
387
401
else :
388
402
base = kwargs .pop ('basey' , 10.0 )
389
403
linthresh = kwargs .pop ('linthreshy' , 2.0 )
390
404
subs = kwargs .pop ('subsy' , None )
405
+ linscale = kwargs .pop ('linscaley' , 1.0 )
391
406
392
- self ._transform = self .SymmetricalLogTransform (base , linthresh )
393
-
394
- assert base > 0.0
407
+ assert base > 1.0
395
408
assert linthresh > 0.0
409
+ assert linscale >= 1.0
410
+
411
+ self ._transform = self .SymmetricalLogTransform (base , linthresh , linscale )
412
+
396
413
self .base = base
397
414
self .linthresh = linthresh
415
+ self .linscale = linscale
398
416
self .subs = subs
399
417
400
418
def set_default_locators_and_formatters (self , axis ):
0 commit comments