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