@@ -94,6 +94,7 @@ def get_transform(self):
94
94
return IdentityTransform ()
95
95
96
96
97
+ @cbook .deprecated ("3.1" , alternative = "LogTransform" )
97
98
class LogTransformBase (Transform ):
98
99
input_dims = 1
99
100
output_dims = 1
@@ -105,28 +106,14 @@ def __init__(self, nonpos='clip'):
105
106
self ._clip = {"clip" : True , "mask" : False }[nonpos ]
106
107
107
108
def transform_non_affine (self , a ):
108
- # Ignore invalid values due to nans being passed to the transform
109
- with np .errstate (divide = "ignore" , invalid = "ignore" ):
110
- out = np .log (a )
111
- out /= np .log (self .base )
112
- if self ._clip :
113
- # SVG spec says that conforming viewers must support values up
114
- # to 3.4e38 (C float); however experiments suggest that
115
- # Inkscape (which uses cairo for rendering) runs into cairo's
116
- # 24-bit limit (which is apparently shared by Agg).
117
- # Ghostscript (used for pdf rendering appears to overflow even
118
- # earlier, with the max value around 2 ** 15 for the tests to
119
- # pass. On the other hand, in practice, we want to clip beyond
120
- # np.log10(np.nextafter(0, 1)) ~ -323
121
- # so 1000 seems safe.
122
- out [a <= 0 ] = - 1000
123
- return out
109
+ return LogTransform .transform_non_affine (self , a )
124
110
125
111
def __str__ (self ):
126
112
return "{}({!r})" .format (
127
113
type (self ).__name__ , "clip" if self ._clip else "mask" )
128
114
129
115
116
+ @cbook .deprecated ("3.1" , alternative = "InvertedLogTransform" )
130
117
class InvertedLogTransformBase (Transform ):
131
118
input_dims = 1
132
119
output_dims = 1
@@ -140,79 +127,118 @@ def __str__(self):
140
127
return "{}()" .format (type (self ).__name__ )
141
128
142
129
130
+ @cbook .deprecated ("3.1" , alternative = "LogTransform" )
143
131
class Log10Transform (LogTransformBase ):
144
132
base = 10.0
145
133
146
134
def inverted (self ):
147
135
return InvertedLog10Transform ()
148
136
149
137
138
+ @cbook .deprecated ("3.1" , alternative = "InvertedLogTransform" )
150
139
class InvertedLog10Transform (InvertedLogTransformBase ):
151
140
base = 10.0
152
141
153
142
def inverted (self ):
154
143
return Log10Transform ()
155
144
156
145
146
+ @cbook .deprecated ("3.1" , alternative = "LogTransform" )
157
147
class Log2Transform (LogTransformBase ):
158
148
base = 2.0
159
149
160
150
def inverted (self ):
161
151
return InvertedLog2Transform ()
162
152
163
153
154
+ @cbook .deprecated ("3.1" , alternative = "InvertedLogTransform" )
164
155
class InvertedLog2Transform (InvertedLogTransformBase ):
165
156
base = 2.0
166
157
167
158
def inverted (self ):
168
159
return Log2Transform ()
169
160
170
161
162
+ @cbook .deprecated ("3.1" , alternative = "LogTransform" )
171
163
class NaturalLogTransform (LogTransformBase ):
172
164
base = np .e
173
165
174
166
def inverted (self ):
175
167
return InvertedNaturalLogTransform ()
176
168
177
169
170
+ @cbook .deprecated ("3.1" , alternative = "InvertedLogTransform" )
178
171
class InvertedNaturalLogTransform (InvertedLogTransformBase ):
179
172
base = np .e
180
173
181
174
def inverted (self ):
182
175
return NaturalLogTransform ()
183
176
184
177
185
- class LogTransform (LogTransformBase ):
178
+ class LogTransform (Transform ):
179
+ input_dims = 1
180
+ output_dims = 1
181
+ is_separable = True
182
+ has_inverse = True
183
+
186
184
def __init__ (self , base , nonpos = 'clip' ):
187
- LogTransformBase .__init__ (self , nonpos )
185
+ Transform .__init__ (self )
188
186
self .base = base
187
+ self ._clip = {"clip" : True , "mask" : False }[nonpos ]
188
+
189
+ def __str__ (self ):
190
+ return "{}(base={}, nonpos={!r})" .format (
191
+ type (self ).__name__ , self .base , "clip" if self ._clip else "mask" )
192
+
193
+ def transform_non_affine (self , a ):
194
+ # Ignore invalid values due to nans being passed to the transform.
195
+ with np .errstate (divide = "ignore" , invalid = "ignore" ):
196
+ log = {np .e : np .log , 2 : np .log2 , 10 : np .log10 }.get (self .base )
197
+ if log : # If possible, do everything in a single call to Numpy.
198
+ out = log (a )
199
+ else :
200
+ out = np .log (a )
201
+ out /= np .log (self .base )
202
+ if self ._clip :
203
+ # SVG spec says that conforming viewers must support values up
204
+ # to 3.4e38 (C float); however experiments suggest that
205
+ # Inkscape (which uses cairo for rendering) runs into cairo's
206
+ # 24-bit limit (which is apparently shared by Agg).
207
+ # Ghostscript (used for pdf rendering appears to overflow even
208
+ # earlier, with the max value around 2 ** 15 for the tests to
209
+ # pass. On the other hand, in practice, we want to clip beyond
210
+ # np.log10(np.nextafter(0, 1)) ~ -323
211
+ # so 1000 seems safe.
212
+ out [a <= 0 ] = - 1000
213
+ return out
189
214
190
215
def inverted (self ):
191
216
return InvertedLogTransform (self .base )
192
217
193
218
194
- class InvertedLogTransform (InvertedLogTransformBase ):
219
+ class InvertedLogTransform (Transform ):
220
+ input_dims = 1
221
+ output_dims = 1
222
+ is_separable = True
223
+ has_inverse = True
224
+
195
225
def __init__ (self , base ):
196
- InvertedLogTransformBase .__init__ (self )
226
+ Transform .__init__ (self )
197
227
self .base = base
198
228
229
+ def __str__ (self ):
230
+ return "{}(base={})" .format (type (self ).__name__ , self .base )
231
+
232
+ def transform_non_affine (self , a ):
233
+ return ma .power (self .base , a )
234
+
199
235
def inverted (self ):
200
236
return LogTransform (self .base )
201
237
202
238
203
239
class LogScale (ScaleBase ):
204
240
"""
205
- A standard logarithmic scale. Care is taken so non-positive
206
- values are not plotted.
207
-
208
- For computational efficiency (to push as much as possible to Numpy
209
- C code in the common cases), this scale provides different
210
- transforms depending on the base of the logarithm:
211
-
212
- - base 10 (:class:`Log10Transform`)
213
- - base 2 (:class:`Log2Transform`)
214
- - base e (:class:`NaturalLogTransform`)
215
- - arbitrary base (:class:`LogTransform`)
241
+ A standard logarithmic scale. Care is taken to only plot positive values.
216
242
"""
217
243
name = 'log'
218
244
@@ -264,18 +290,13 @@ def __init__(self, axis, **kwargs):
264
290
if base <= 0 or base == 1 :
265
291
raise ValueError ('The log base cannot be <= 0 or == 1' )
266
292
267
- if base == 10.0 :
268
- self ._transform = self .Log10Transform (nonpos )
269
- elif base == 2.0 :
270
- self ._transform = self .Log2Transform (nonpos )
271
- elif base == np .e :
272
- self ._transform = self .NaturalLogTransform (nonpos )
273
- else :
274
- self ._transform = self .LogTransform (base , nonpos )
275
-
276
- self .base = base
293
+ self ._transform = self .LogTransform (base , nonpos )
277
294
self .subs = subs
278
295
296
+ @property
297
+ def base (self ):
298
+ return self ._transform .base
299
+
279
300
def set_default_locators_and_formatters (self , axis ):
280
301
"""
281
302
Set the locators and formatters to specialized versions for
0 commit comments