Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8747e87

Browse files
committed
Deprecate redundant log-scale transform classes.
1 parent cbd5de9 commit 8747e87

File tree

4 files changed

+73
-44
lines changed

4 files changed

+73
-44
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Deprecations
2+
````````````
3+
4+
- The ``LogTransformBase``, ``Log10Transform``, ``Log2Transform``,
5+
``NaturalLogTransformLog``, ``InvertedLogTransformBase``,
6+
``InvertedLog10Transform``, ``InvertedLog2Transform``, and
7+
``InvertedNaturalLogTransform`` classes (all defined in
8+
:mod:`matplotlib.scales`) are deprecated. As a replacement, use the general
9+
`LogTransform` and `InvertedLogTransform` classes, whose constructors take a
10+
*base* argument.

lib/matplotlib/scale.py

Lines changed: 61 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ def get_transform(self):
8282
return IdentityTransform()
8383

8484

85+
@cbook.deprecated("3.1", alternative="LogTransform")
8586
class LogTransformBase(Transform):
8687
input_dims = 1
8788
output_dims = 1
@@ -93,28 +94,14 @@ def __init__(self, nonpos='clip'):
9394
self._clip = {"clip": True, "mask": False}[nonpos]
9495

9596
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)
11298

11399
def __str__(self):
114100
return "{}({!r})".format(
115101
type(self).__name__, "clip" if self._clip else "mask")
116102

117103

104+
@cbook.deprecated("3.1", alternative="InvertedLogTransform")
118105
class InvertedLogTransformBase(Transform):
119106
input_dims = 1
120107
output_dims = 1
@@ -128,79 +115,118 @@ def __str__(self):
128115
return "{}()".format(type(self).__name__)
129116

130117

118+
@cbook.deprecated("3.1", alternative="LogTransform")
131119
class Log10Transform(LogTransformBase):
132120
base = 10.0
133121

134122
def inverted(self):
135123
return InvertedLog10Transform()
136124

137125

126+
@cbook.deprecated("3.1", alternative="InvertedLogTransform")
138127
class InvertedLog10Transform(InvertedLogTransformBase):
139128
base = 10.0
140129

141130
def inverted(self):
142131
return Log10Transform()
143132

144133

134+
@cbook.deprecated("3.1", alternative="LogTransform")
145135
class Log2Transform(LogTransformBase):
146136
base = 2.0
147137

148138
def inverted(self):
149139
return InvertedLog2Transform()
150140

151141

142+
@cbook.deprecated("3.1", alternative="InvertedLogTransform")
152143
class InvertedLog2Transform(InvertedLogTransformBase):
153144
base = 2.0
154145

155146
def inverted(self):
156147
return Log2Transform()
157148

158149

150+
@cbook.deprecated("3.1", alternative="LogTransform")
159151
class NaturalLogTransform(LogTransformBase):
160152
base = np.e
161153

162154
def inverted(self):
163155
return InvertedNaturalLogTransform()
164156

165157

158+
@cbook.deprecated("3.1", alternative="InvertedLogTransform")
166159
class InvertedNaturalLogTransform(InvertedLogTransformBase):
167160
base = np.e
168161

169162
def inverted(self):
170163
return NaturalLogTransform()
171164

172165

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+
174172
def __init__(self, base, nonpos='clip'):
175-
LogTransformBase.__init__(self, nonpos)
173+
Transform.__init__(self)
176174
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
177202

178203
def inverted(self):
179204
return InvertedLogTransform(self.base)
180205

181206

182207
class InvertedLogTransform(InvertedLogTransformBase):
208+
input_dims = 1
209+
output_dims = 1
210+
is_separable = True
211+
has_inverse = True
212+
183213
def __init__(self, base):
184-
InvertedLogTransformBase.__init__(self)
214+
Transform.__init__(self)
185215
self.base = base
186216

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+
187223
def inverted(self):
188224
return LogTransform(self.base)
189225

190226

191227
class LogScale(ScaleBase):
192228
"""
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.
204230
"""
205231
name = 'log'
206232

@@ -252,18 +278,13 @@ def __init__(self, axis, **kwargs):
252278
if base <= 0 or base == 1:
253279
raise ValueError('The log base cannot be <= 0 or == 1')
254280

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)
265282
self.subs = subs
266283

284+
@property
285+
def base(self):
286+
return self._transform.base
287+
267288
def set_default_locators_and_formatters(self, axis):
268289
"""
269290
Set the locators and formatters to specialized versions for

lib/matplotlib/tests/test_axes.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5209,8 +5209,7 @@ def test_title_location_roundtrip():
52095209

52105210

52115211
@image_comparison(baseline_images=["loglog"], remove_text=True,
5212-
extensions=['png'],
5213-
tol={'aarch64': 0.02}.get(platform.machine(), 0.0))
5212+
extensions=['png'], tol=0.02)
52145213
def test_loglog():
52155214
fig, ax = plt.subplots()
52165215
x = np.arange(1, 11)

lib/matplotlib/tests/test_scale.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,7 @@ def test_logscale_transform_repr():
9999

100100

101101
@image_comparison(baseline_images=['logscale_nonpos_values'], remove_text=True,
102-
tol={'aarch64': 0.02}.get(platform.machine(), 0.0),
103-
extensions=['png'], style='mpl20')
102+
extensions=['png'], tol=0.02, style='mpl20')
104103
def test_logscale_nonpos_values():
105104
np.random.seed(19680801)
106105
xs = np.random.normal(size=int(1e3))

0 commit comments

Comments
 (0)