@@ -92,15 +92,24 @@ class LogTransformBase(Transform):
9292
9393 def __init__ (self , nonpos ):
9494 Transform .__init__ (self )
95- if nonpos == 'mask' :
96- self ._fill_value = np .nan
97- else :
98- self ._fill_value = 1e-300
95+ self ._clip = {"clip" : True , "mask" : False }[nonpos ]
9996
10097 def transform_non_affine (self , a ):
101- with np .errstate (invalid = "ignore" ):
102- a = np .where (a <= 0 , self ._fill_value , a )
103- return np .divide (np .log (a , out = a ), np .log (self .base ), out = a )
98+ with np .errstate (divide = "ignore" , invalid = "ignore" ):
99+ out = np .log (a )
100+ out /= np .log (self .base )
101+ if self ._clip :
102+ # SVG spec says that conforming viewers must support values up
103+ # to 3.4e38 (C float); however experiments suggest that Inkscape
104+ # (which uses cairo for rendering) runs into cairo's 24-bit limit
105+ # (which is apparently shared by Agg).
106+ # Ghostscript (used for pdf rendering appears to overflow even
107+ # earlier, with the max value around 2 ** 15 for the tests to pass.
108+ # On the other hand, in practice, we want to clip beyond
109+ # np.log10(np.nextafter(0, 1)) ~ -323
110+ # so 1000 seems safe.
111+ out [a <= 0 ] = - 1000
112+ return out
104113
105114
106115class InvertedLogTransformBase (Transform ):
@@ -220,11 +229,17 @@ def __init__(self, axis, **kwargs):
220229 if axis .axis_name == 'x' :
221230 base = kwargs .pop ('basex' , 10.0 )
222231 subs = kwargs .pop ('subsx' , None )
223- nonpos = kwargs .pop ('nonposx' , 'mask ' )
232+ nonpos = kwargs .pop ('nonposx' , 'clip ' )
224233 else :
225234 base = kwargs .pop ('basey' , 10.0 )
226235 subs = kwargs .pop ('subsy' , None )
227- nonpos = kwargs .pop ('nonposy' , 'mask' )
236+ nonpos = kwargs .pop ('nonposy' , 'clip' )
237+
238+ if len (kwargs ):
239+ raise ValueError (("provided too many kwargs, can only pass "
240+ "{'basex', 'subsx', nonposx'} or "
241+ "{'basey', 'subsy', nonposy'}. You passed " ) +
242+ "{!r}" .format (kwargs ))
228243
229244 if nonpos not in ['mask' , 'clip' ]:
230245 raise ValueError ("nonposx, nonposy kwarg must be 'mask' or 'clip'" )
@@ -432,18 +447,17 @@ class LogitTransform(Transform):
432447
433448 def __init__ (self , nonpos ):
434449 Transform .__init__ (self )
435- if nonpos == 'mask' :
436- self ._fill_value = np .nan
437- else :
438- self ._fill_value = 1e-300
439450 self ._nonpos = nonpos
451+ self ._clip = {"clip" : True , "mask" : False }[nonpos ]
440452
441453 def transform_non_affine (self , a ):
442454 """logit transform (base 10), masked or clipped"""
443- with np .errstate (invalid = "ignore" ):
444- a = np .select (
445- [a <= 0 , a >= 1 ], [self ._fill_value , 1 - self ._fill_value ], a )
446- return np .log10 (a / (1 - a ))
455+ with np .errstate (divide = "ignore" , invalid = "ignore" ):
456+ out = np .log10 (a / (1 - a ))
457+ if self ._clip : # See LogTransform for choice of clip value.
458+ out [a <= 0 ] = - 1000
459+ out [1 <= a ] = 1000
460+ return out
447461
448462 def inverted (self ):
449463 return LogisticTransform (self ._nonpos )
0 commit comments