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
@@ -116,21 +120,20 @@ class LogTransformBase(Transform):
116
120
output_dims = 1
117
121
is_separable = True
118
122
has_inverse = True
119
-
123
+
120
124
def __init__ (self , nonpos ):
121
125
Transform .__init__ (self )
122
126
if nonpos == 'mask' :
123
127
self ._handle_nonpos = _mask_non_positives
124
128
else :
125
129
self ._handle_nonpos = _clip_non_positives
126
130
127
-
128
131
class Log10Transform (LogTransformBase ):
129
132
base = 10.0
130
133
131
- def transform (self , a ):
134
+ def transform_non_affine (self , a ):
132
135
a = self ._handle_nonpos (a * 10.0 )
133
- if isinstance (a , MaskedArray ):
136
+ if isinstance (a , ma . MaskedArray ):
134
137
return ma .log10 (a )
135
138
return np .log10 (a )
136
139
@@ -141,9 +144,10 @@ class InvertedLog10Transform(Transform):
141
144
input_dims = 1
142
145
output_dims = 1
143
146
is_separable = True
147
+ has_inverse = True
144
148
base = 10.0
145
149
146
- def transform (self , a ):
150
+ def transform_non_affine (self , a ):
147
151
return ma .power (10.0 , a ) / 10.0
148
152
149
153
def inverted (self ):
@@ -152,9 +156,9 @@ def inverted(self):
152
156
class Log2Transform (LogTransformBase ):
153
157
base = 2.0
154
158
155
- def transform (self , a ):
159
+ def transform_non_affine (self , a ):
156
160
a = self ._handle_nonpos (a * 2.0 )
157
- if isinstance (a , MaskedArray ):
161
+ if isinstance (a , ma . MaskedArray ):
158
162
return ma .log (a ) / np .log (2 )
159
163
return np .log2 (a )
160
164
@@ -165,9 +169,10 @@ class InvertedLog2Transform(Transform):
165
169
input_dims = 1
166
170
output_dims = 1
167
171
is_separable = True
172
+ has_inverse = True
168
173
base = 2.0
169
174
170
- def transform (self , a ):
175
+ def transform_non_affine (self , a ):
171
176
return ma .power (2.0 , a ) / 2.0
172
177
173
178
def inverted (self ):
@@ -176,9 +181,9 @@ def inverted(self):
176
181
class NaturalLogTransform (LogTransformBase ):
177
182
base = np .e
178
183
179
- def transform (self , a ):
184
+ def transform_non_affine (self , a ):
180
185
a = self ._handle_nonpos (a * np .e )
181
- if isinstance (a , MaskedArray ):
186
+ if isinstance (a , ma . MaskedArray ):
182
187
return ma .log (a )
183
188
return np .log (a )
184
189
@@ -189,9 +194,10 @@ class InvertedNaturalLogTransform(Transform):
189
194
input_dims = 1
190
195
output_dims = 1
191
196
is_separable = True
197
+ has_inverse = True
192
198
base = np .e
193
199
194
- def transform (self , a ):
200
+ def transform_non_affine (self , a ):
195
201
return ma .power (np .e , a ) / np .e
196
202
197
203
def inverted (self ):
@@ -201,7 +207,8 @@ class LogTransform(Transform):
201
207
input_dims = 1
202
208
output_dims = 1
203
209
is_separable = True
204
-
210
+ has_inverse = True
211
+
205
212
def __init__ (self , base , nonpos ):
206
213
Transform .__init__ (self )
207
214
self .base = base
@@ -210,9 +217,9 @@ def __init__(self, base, nonpos):
210
217
else :
211
218
self ._handle_nonpos = _clip_non_positives
212
219
213
- def transform (self , a ):
220
+ def transform_non_affine (self , a ):
214
221
a = self ._handle_nonpos (a * self .base )
215
- if isinstance (a , MaskedArray ):
222
+ if isinstance (a , ma . MaskedArray ):
216
223
return ma .log (a ) / np .log (self .base )
217
224
return np .log (a ) / np .log (self .base )
218
225
@@ -223,18 +230,18 @@ class InvertedLogTransform(Transform):
223
230
input_dims = 1
224
231
output_dims = 1
225
232
is_separable = True
226
-
233
+ has_inverse = True
234
+
227
235
def __init__ (self , base ):
228
236
Transform .__init__ (self )
229
237
self .base = base
230
238
231
- def transform (self , a ):
239
+ def transform_non_affine (self , a ):
232
240
return ma .power (self .base , a ) / self .base
233
241
234
242
def inverted (self ):
235
243
return LogScale .LogTransform (self .base )
236
-
237
-
244
+
238
245
def __init__ (self , axis , ** kwargs ):
239
246
"""
240
247
*basex*/*basey*:
@@ -318,7 +325,7 @@ class SymmetricalLogTransform(Transform):
318
325
output_dims = 1
319
326
is_separable = True
320
327
has_inverse = True
321
-
328
+
322
329
def __init__ (self , base , linthresh , linscale ):
323
330
Transform .__init__ (self )
324
331
self .base = base
@@ -327,7 +334,7 @@ def __init__(self, base, linthresh, linscale):
327
334
self ._linscale_adj = (linscale / (1.0 - self .base ** - 1 ))
328
335
self ._log_base = np .log (base )
329
336
330
- def transform (self , a ):
337
+ def transform_non_affine (self , a ):
331
338
sign = np .sign (a )
332
339
masked = ma .masked_inside (a , - self .linthresh , self .linthresh , copy = False )
333
340
log = sign * self .linthresh * (
@@ -346,7 +353,8 @@ class InvertedSymmetricalLogTransform(Transform):
346
353
input_dims = 1
347
354
output_dims = 1
348
355
is_separable = True
349
-
356
+ has_inverse = True
357
+
350
358
def __init__ (self , base , linthresh , linscale ):
351
359
Transform .__init__ (self )
352
360
symlog = SymmetricalLogScale .SymmetricalLogTransform (base , linthresh , linscale )
@@ -356,7 +364,7 @@ def __init__(self, base, linthresh, linscale):
356
364
self .linscale = linscale
357
365
self ._linscale_adj = (linscale / (1.0 - self .base ** - 1 ))
358
366
359
- def transform (self , a ):
367
+ def transform_non_affine (self , a ):
360
368
sign = np .sign (a )
361
369
masked = ma .masked_inside (a , - self .invlinthresh , self .invlinthresh , copy = False )
362
370
exp = sign * self .linthresh * (
@@ -436,17 +444,19 @@ def get_transform(self):
436
444
return self ._transform
437
445
438
446
439
-
440
447
_scale_mapping = {
441
448
'linear' : LinearScale ,
442
449
'log' : LogScale ,
443
450
'symlog' : SymmetricalLogScale
444
451
}
452
+
453
+
445
454
def get_scale_names ():
446
455
names = _scale_mapping .keys ()
447
456
names .sort ()
448
457
return names
449
458
459
+
450
460
def scale_factory (scale , axis , ** kwargs ):
451
461
"""
452
462
Return a scale class by name.
@@ -464,6 +474,7 @@ def scale_factory(scale, axis, **kwargs):
464
474
scale_factory .__doc__ = dedent (scale_factory .__doc__ ) % \
465
475
{'names' : " | " .join (get_scale_names ())}
466
476
477
+
467
478
def register_scale (scale_class ):
468
479
"""
469
480
Register a new kind of scale.
@@ -472,6 +483,7 @@ def register_scale(scale_class):
472
483
"""
473
484
_scale_mapping [scale_class .name ] = scale_class
474
485
486
+
475
487
def get_scale_docs ():
476
488
"""
477
489
Helper function for generating docstrings related to scales.
@@ -488,6 +500,7 @@ def get_scale_docs():
488
500
docs .append ("" )
489
501
return "\n " .join (docs )
490
502
503
+
491
504
docstring .interpd .update (
492
505
scale = ' | ' .join ([repr (x ) for x in get_scale_names ()]),
493
506
scale_docs = get_scale_docs ().strip (),
0 commit comments