1
1
from __future__ import print_function
2
- import textwrap
2
+
3
3
import numpy as np
4
4
from numpy import ma
5
- MaskedArray = ma .MaskedArray
6
5
7
- from cbook import dedent
8
- from ticker import NullFormatter , ScalarFormatter , LogFormatterMathtext , Formatter
9
- from ticker import NullLocator , LogLocator , AutoLocator , SymmetricalLogLocator , FixedLocator
10
- from ticker import is_decade
11
- from transforms import Transform , IdentityTransform
6
+ from matplotlib .cbook import dedent
7
+ from matplotlib .ticker import (NullFormatter , ScalarFormatter ,
8
+ LogFormatterMathtext )
9
+ from matplotlib .ticker import (NullLocator , LogLocator , AutoLocator ,
10
+ SymmetricalLogLocator )
11
+ from matplotlib .transforms import Transform , IdentityTransform
12
12
from matplotlib import docstring
13
13
14
+
14
15
class ScaleBase (object ):
15
16
"""
16
17
The base class for all scales.
@@ -31,15 +32,15 @@ def get_transform(self):
31
32
Return the :class:`~matplotlib.transforms.Transform` object
32
33
associated with this scale.
33
34
"""
34
- raise NotImplementedError
35
+ raise NotImplementedError ()
35
36
36
37
def set_default_locators_and_formatters (self , axis ):
37
38
"""
38
39
Set the :class:`~matplotlib.ticker.Locator` and
39
40
:class:`~matplotlib.ticker.Formatter` objects on the given
40
41
axis to match this scale.
41
42
"""
42
- raise NotImplementedError
43
+ raise NotImplementedError ()
43
44
44
45
def limit_range_for_scale (self , vmin , vmax , minpos ):
45
46
"""
@@ -51,6 +52,7 @@ def limit_range_for_scale(self, vmin, vmax, minpos):
51
52
"""
52
53
return vmin , vmax
53
54
55
+
54
56
class LinearScale (ScaleBase ):
55
57
"""
56
58
The default linear scale.
@@ -90,10 +92,12 @@ def _mask_non_positives(a):
90
92
return ma .MaskedArray (a , mask = mask )
91
93
return a
92
94
95
+
93
96
def _clip_non_positives (a ):
94
97
a [a <= 0.0 ] = 1e-300
95
98
return a
96
99
100
+
97
101
class LogScale (ScaleBase ):
98
102
"""
99
103
A standard logarithmic scale. Care is taken so non-positive
@@ -115,21 +119,21 @@ class LogTransformBase(Transform):
115
119
input_dims = 1
116
120
output_dims = 1
117
121
is_separable = True
118
-
122
+ has_inverse = True
123
+
119
124
def __init__ (self , nonpos ):
120
125
Transform .__init__ (self )
121
126
if nonpos == 'mask' :
122
127
self ._handle_nonpos = _mask_non_positives
123
128
else :
124
129
self ._handle_nonpos = _clip_non_positives
125
130
126
-
127
131
class Log10Transform (LogTransformBase ):
128
132
base = 10.0
129
133
130
- def transform (self , a ):
134
+ def transform_non_affine (self , a ):
131
135
a = self ._handle_nonpos (a * 10.0 )
132
- if isinstance (a , MaskedArray ):
136
+ if isinstance (a , ma . MaskedArray ):
133
137
return ma .log10 (a )
134
138
return np .log10 (a )
135
139
@@ -140,9 +144,10 @@ class InvertedLog10Transform(Transform):
140
144
input_dims = 1
141
145
output_dims = 1
142
146
is_separable = True
147
+ has_inverse = True
143
148
base = 10.0
144
149
145
- def transform (self , a ):
150
+ def transform_non_affine (self , a ):
146
151
return ma .power (10.0 , a ) / 10.0
147
152
148
153
def inverted (self ):
@@ -151,9 +156,9 @@ def inverted(self):
151
156
class Log2Transform (LogTransformBase ):
152
157
base = 2.0
153
158
154
- def transform (self , a ):
159
+ def transform_non_affine (self , a ):
155
160
a = self ._handle_nonpos (a * 2.0 )
156
- if isinstance (a , MaskedArray ):
161
+ if isinstance (a , ma . MaskedArray ):
157
162
return ma .log (a ) / np .log (2 )
158
163
return np .log2 (a )
159
164
@@ -164,9 +169,10 @@ class InvertedLog2Transform(Transform):
164
169
input_dims = 1
165
170
output_dims = 1
166
171
is_separable = True
172
+ has_inverse = True
167
173
base = 2.0
168
174
169
- def transform (self , a ):
175
+ def transform_non_affine (self , a ):
170
176
return ma .power (2.0 , a ) / 2.0
171
177
172
178
def inverted (self ):
@@ -175,9 +181,9 @@ def inverted(self):
175
181
class NaturalLogTransform (LogTransformBase ):
176
182
base = np .e
177
183
178
- def transform (self , a ):
184
+ def transform_non_affine (self , a ):
179
185
a = self ._handle_nonpos (a * np .e )
180
- if isinstance (a , MaskedArray ):
186
+ if isinstance (a , ma . MaskedArray ):
181
187
return ma .log (a )
182
188
return np .log (a )
183
189
@@ -188,9 +194,10 @@ class InvertedNaturalLogTransform(Transform):
188
194
input_dims = 1
189
195
output_dims = 1
190
196
is_separable = True
197
+ has_inverse = True
191
198
base = np .e
192
199
193
- def transform (self , a ):
200
+ def transform_non_affine (self , a ):
194
201
return ma .power (np .e , a ) / np .e
195
202
196
203
def inverted (self ):
@@ -200,7 +207,8 @@ class LogTransform(Transform):
200
207
input_dims = 1
201
208
output_dims = 1
202
209
is_separable = True
203
-
210
+ has_inverse = True
211
+
204
212
def __init__ (self , base , nonpos ):
205
213
Transform .__init__ (self )
206
214
self .base = base
@@ -209,9 +217,9 @@ def __init__(self, base, nonpos):
209
217
else :
210
218
self ._handle_nonpos = _clip_non_positives
211
219
212
- def transform (self , a ):
220
+ def transform_non_affine (self , a ):
213
221
a = self ._handle_nonpos (a * self .base )
214
- if isinstance (a , MaskedArray ):
222
+ if isinstance (a , ma . MaskedArray ):
215
223
return ma .log (a ) / np .log (self .base )
216
224
return np .log (a ) / np .log (self .base )
217
225
@@ -222,18 +230,18 @@ class InvertedLogTransform(Transform):
222
230
input_dims = 1
223
231
output_dims = 1
224
232
is_separable = True
225
-
233
+ has_inverse = True
234
+
226
235
def __init__ (self , base ):
227
236
Transform .__init__ (self )
228
237
self .base = base
229
238
230
- def transform (self , a ):
239
+ def transform_non_affine (self , a ):
231
240
return ma .power (self .base , a ) / self .base
232
241
233
242
def inverted (self ):
234
243
return LogScale .LogTransform (self .base )
235
-
236
-
244
+
237
245
def __init__ (self , axis , ** kwargs ):
238
246
"""
239
247
*basex*/*basey*:
@@ -316,7 +324,8 @@ class SymmetricalLogTransform(Transform):
316
324
input_dims = 1
317
325
output_dims = 1
318
326
is_separable = True
319
-
327
+ has_inverse = True
328
+
320
329
def __init__ (self , base , linthresh , linscale ):
321
330
Transform .__init__ (self )
322
331
self .base = base
@@ -325,7 +334,7 @@ def __init__(self, base, linthresh, linscale):
325
334
self ._linscale_adj = (linscale / (1.0 - self .base ** - 1 ))
326
335
self ._log_base = np .log (base )
327
336
328
- def transform (self , a ):
337
+ def transform_non_affine (self , a ):
329
338
sign = np .sign (a )
330
339
masked = ma .masked_inside (a , - self .linthresh , self .linthresh , copy = False )
331
340
log = sign * self .linthresh * (
@@ -344,7 +353,8 @@ class InvertedSymmetricalLogTransform(Transform):
344
353
input_dims = 1
345
354
output_dims = 1
346
355
is_separable = True
347
-
356
+ has_inverse = True
357
+
348
358
def __init__ (self , base , linthresh , linscale ):
349
359
Transform .__init__ (self )
350
360
symlog = SymmetricalLogScale .SymmetricalLogTransform (base , linthresh , linscale )
@@ -354,7 +364,7 @@ def __init__(self, base, linthresh, linscale):
354
364
self .linscale = linscale
355
365
self ._linscale_adj = (linscale / (1.0 - self .base ** - 1 ))
356
366
357
- def transform (self , a ):
367
+ def transform_non_affine (self , a ):
358
368
sign = np .sign (a )
359
369
masked = ma .masked_inside (a , - self .invlinthresh , self .invlinthresh , copy = False )
360
370
exp = sign * self .linthresh * (
@@ -434,17 +444,19 @@ def get_transform(self):
434
444
return self ._transform
435
445
436
446
437
-
438
447
_scale_mapping = {
439
448
'linear' : LinearScale ,
440
449
'log' : LogScale ,
441
450
'symlog' : SymmetricalLogScale
442
451
}
452
+
453
+
443
454
def get_scale_names ():
444
455
names = _scale_mapping .keys ()
445
456
names .sort ()
446
457
return names
447
458
459
+
448
460
def scale_factory (scale , axis , ** kwargs ):
449
461
"""
450
462
Return a scale class by name.
@@ -462,6 +474,7 @@ def scale_factory(scale, axis, **kwargs):
462
474
scale_factory .__doc__ = dedent (scale_factory .__doc__ ) % \
463
475
{'names' : " | " .join (get_scale_names ())}
464
476
477
+
465
478
def register_scale (scale_class ):
466
479
"""
467
480
Register a new kind of scale.
@@ -470,6 +483,7 @@ def register_scale(scale_class):
470
483
"""
471
484
_scale_mapping [scale_class .name ] = scale_class
472
485
486
+
473
487
def get_scale_docs ():
474
488
"""
475
489
Helper function for generating docstrings related to scales.
@@ -486,6 +500,7 @@ def get_scale_docs():
486
500
docs .append ("" )
487
501
return "\n " .join (docs )
488
502
503
+
489
504
docstring .interpd .update (
490
505
scale = ' | ' .join ([repr (x ) for x in get_scale_names ()]),
491
506
scale_docs = get_scale_docs ().strip (),
0 commit comments