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

Skip to content

Commit eb37584

Browse files
committed
Make kwargs names in scale.py not include the axis direction.
- Make names of kwargs to Scale subclasses independent of whether the underlying axis is x or y (so that after the deprecation period, one can just have a normal signature -- `def __init__(self, *, base=10, ...)`. We could possibly also change semilogx and semilogy to use the unsuffixed names (with deprecation), leaving only loglog with the suffixed names, or even also make loglog use unsuffixed names, in which case it would become impossible to set separate x and y bases directly in loglog -- one should then do `gca().set_xscale("log", base=...)` which doesn't seem too onerous. (loglog is the only case where the suffixed names has *some* utility.) In general, note that having kwargs that depend on the axis direction doesn't really scale -- for example, if we were to finally add log-scale support to mplot3d, should scale.py know about it and add `basez`? Should we have `baser` for log-scale polar plots? (at least in the radial direction, they make sense) - Move argument validation up the the Transform subclasses. - Make SymmetricalLogScale.{base,linthresh,linscale} properties mapping to the underlying transform so that they can't go out of sync.
1 parent f2b3051 commit eb37584

File tree

9 files changed

+93
-100
lines changed

9 files changed

+93
-100
lines changed

doc/api/next_api_changes/deprecations.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,13 @@ variables is deprecated. Additional fonts may be registered using
173173
``matplotlib.compat``
174174
~~~~~~~~~~~~~~~~~~~~~
175175
This module is deprecated.
176+
177+
Signature of `.LogScale` and `.SymmetricalLogScale`
178+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
179+
These classes used to take keyword arguments that depends on the axis
180+
orientation ("basex" vs "basey", "nonposx" vs "nonposy"); these parameter
181+
names are now deprecated in favor of "base", "nonpos", etc. This deprecation
182+
also affects e.g. ``ax.set_yscale("log", basey=...)`` which must now be
183+
spelled ``ax.set_yscale("log", base=...)``. The only place where "basex", etc.
184+
remain in use is in the helper functions `~.Axes.loglog`, `~.Axes.semilogx`,
185+
and `~.Axes.semilogy` (because `~.Axes.loglog` takes both "basex" and "basey").

examples/scales/log_demo.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
ax2.grid()
2727

2828
# log x and y axis
29-
ax3.loglog(t, 20 * np.exp(-t / 10.0), basex=2)
29+
ax3.loglog(t, 20 * np.exp(-t / 10.0))
30+
ax3.set_xscale('log', base=2)
3031
ax3.set(title='loglog base 2 on x')
3132
ax3.grid()
3233

@@ -35,8 +36,8 @@
3536
x = 10.0**np.linspace(0.0, 2.0, 20)
3637
y = x**2.0
3738

38-
ax4.set_xscale("log", nonposx='clip')
39-
ax4.set_yscale("log", nonposy='clip')
39+
ax4.set_xscale("log", nonpos='clip')
40+
ax4.set_yscale("log", nonpos='clip')
4041
ax4.set(title='Errorbars go negative')
4142
ax4.errorbar(x, y, xerr=0.1 * x, yerr=5.0 + 0.75 * y)
4243
# ylim must be set after errorbar to allow errorbar to autoscale limits

examples/scales/scales.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
# symmetric log
4646
ax = axs[1, 1]
4747
ax.plot(x, y - y.mean())
48-
ax.set_yscale('symlog', linthreshy=0.02)
48+
ax.set_yscale('symlog', linthresh=0.02)
4949
ax.set_title('symlog')
5050
ax.grid(True)
5151

examples/scales/symlog_demo.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
plt.subplot(313)
2828
plt.plot(x, np.sin(x / 3.0))
2929
plt.xscale('symlog')
30-
plt.yscale('symlog', linthreshy=0.015)
30+
plt.yscale('symlog', linthresh=0.015)
3131
plt.grid(True)
3232
plt.ylabel('symlog both')
3333

lib/matplotlib/axes/_axes.py

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1795,16 +1795,13 @@ def loglog(self, *args, **kwargs):
17951795
**kwargs
17961796
All parameters supported by `.plot`.
17971797
"""
1798-
dx = {k: kwargs.pop(k) for k in ['basex', 'subsx', 'nonposx']
1798+
dx = {k[:-1]: kwargs.pop(k) for k in ['basex', 'subsx', 'nonposx']
17991799
if k in kwargs}
1800-
dy = {k: kwargs.pop(k) for k in ['basey', 'subsy', 'nonposy']
1801-
if k in kwargs}
1802-
18031800
self.set_xscale('log', **dx)
1801+
dy = {k[:-1]: kwargs.pop(k) for k in ['basey', 'subsy', 'nonposy']
1802+
if k in kwargs}
18041803
self.set_yscale('log', **dy)
1805-
1806-
l = self.plot(*args, **kwargs)
1807-
return l
1804+
return self.plot(*args, **kwargs)
18081805

18091806
# @_preprocess_data() # let 'plot' do the unpacking..
18101807
@docstring.dedent_interpd
@@ -1848,12 +1845,10 @@ def semilogx(self, *args, **kwargs):
18481845
**kwargs
18491846
All parameters supported by `.plot`.
18501847
"""
1851-
d = {k: kwargs.pop(k) for k in ['basex', 'subsx', 'nonposx']
1848+
d = {k[:-1]: kwargs.pop(k) for k in ['basex', 'subsx', 'nonposx']
18521849
if k in kwargs}
1853-
18541850
self.set_xscale('log', **d)
1855-
l = self.plot(*args, **kwargs)
1856-
return l
1851+
return self.plot(*args, **kwargs)
18571852

18581853
# @_preprocess_data() # let 'plot' do the unpacking..
18591854
@docstring.dedent_interpd
@@ -1897,12 +1892,10 @@ def semilogy(self, *args, **kwargs):
18971892
**kwargs
18981893
All parameters supported by `.plot`.
18991894
"""
1900-
d = {k: kwargs.pop(k) for k in ['basey', 'subsy', 'nonposy']
1895+
d = {k[:-1]: kwargs.pop(k) for k in ['basey', 'subsy', 'nonposy']
19011896
if k in kwargs}
19021897
self.set_yscale('log', **d)
1903-
l = self.plot(*args, **kwargs)
1904-
1905-
return l
1898+
return self.plot(*args, **kwargs)
19061899

19071900
@_preprocess_data(replace_names=["x"], label_namer="x")
19081901
def acorr(self, x, **kwargs):
@@ -2343,11 +2336,11 @@ def bar(self, x, height, width=0.8, bottom=None, *, align="center",
23432336
if orientation == 'vertical':
23442337
self._process_unit_info(xdata=x, ydata=height, kwargs=kwargs)
23452338
if log:
2346-
self.set_yscale('log', nonposy='clip')
2339+
self.set_yscale('log', nonpos='clip')
23472340
elif orientation == 'horizontal':
23482341
self._process_unit_info(xdata=width, ydata=y, kwargs=kwargs)
23492342
if log:
2350-
self.set_xscale('log', nonposx='clip')
2343+
self.set_xscale('log', nonpos='clip')
23512344

23522345
# lets do some conversions now since some types cannot be
23532346
# subtracted uniformly
@@ -6715,9 +6708,9 @@ def hist(self, x, bins=None, range=None, density=False, weights=None,
67156708

67166709
if log:
67176710
if orientation == 'horizontal':
6718-
self.set_xscale('log', nonposx='clip')
6711+
self.set_xscale('log', nonpos='clip')
67196712
else: # orientation == 'vertical'
6720-
self.set_yscale('log', nonposy='clip')
6713+
self.set_yscale('log', nonpos='clip')
67216714

67226715
if align == 'left':
67236716
x -= 0.5*(bins[1]-bins[0])

lib/matplotlib/scale.py

Lines changed: 55 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,11 @@ class LogTransform(Transform):
280280

281281
def __init__(self, base, nonpos='clip'):
282282
Transform.__init__(self)
283+
if base <= 0 or base == 1:
284+
raise ValueError('The log base cannot be <= 0 or == 1')
283285
self.base = base
284-
self._clip = {"clip": True, "mask": False}[nonpos]
286+
self._clip = cbook._check_getitem(
287+
{"clip": True, "mask": False}, nonpos=nonpos)
285288

286289
def __str__(self):
287290
return "{}(base={}, nonpos={!r})".format(
@@ -361,41 +364,32 @@ def __init__(self, axis, **kwargs):
361364
----------
362365
axis : `~matplotlib.axis.Axis`
363366
The axis for the scale.
364-
basex, basey : float, default: 10
367+
base : float, default: 10
365368
The base of the logarithm.
366-
nonposx, nonposy : {'clip', 'mask'}, default: 'clip'
369+
nonpos : {'clip', 'mask'}, default: 'clip'
367370
Determines the behavior for non-positive values. They can either
368371
be masked as invalid, or clipped to a very small positive number.
369-
subsx, subsy : sequence of int, default: None
370-
Where to place the subticks between each major tick.
371-
For example, in a log10 scale: ``[2, 3, 4, 5, 6, 7, 8, 9]``
372-
will place 8 logarithmically spaced minor ticks between
373-
each major tick.
372+
subs : sequence of int, default: None
373+
Where to place the subticks between each major tick. For example,
374+
in a log10 scale, ``[2, 3, 4, 5, 6, 7, 8, 9]`` will place 8
375+
logarithmically spaced minor ticks between each major tick.
374376
"""
375-
if axis.axis_name == 'x':
376-
base = kwargs.pop('basex', 10.0)
377-
subs = kwargs.pop('subsx', None)
378-
nonpos = kwargs.pop('nonposx', 'clip')
379-
cbook._check_in_list(['mask', 'clip'], nonposx=nonpos)
380-
else:
381-
base = kwargs.pop('basey', 10.0)
382-
subs = kwargs.pop('subsy', None)
383-
nonpos = kwargs.pop('nonposy', 'clip')
384-
cbook._check_in_list(['mask', 'clip'], nonposy=nonpos)
385-
386-
if kwargs:
387-
raise TypeError(f"LogScale got an unexpected keyword "
388-
f"argument {next(iter(kwargs))!r}")
389-
390-
if base <= 0 or base == 1:
391-
raise ValueError('The log base cannot be <= 0 or == 1')
392-
377+
# After the deprecation, the whole (outer) __init__ can be replaced by
378+
# def __init__(self, axis, *, base=10, subs=None, nonpos="clip"): ...
379+
# The following is to emit the right warnings depending on the axis
380+
# used, as the *old* kwarg names depended on the axis.
381+
axis_name = getattr(axis, "axis_name", "x")
382+
@cbook._rename_parameter("3.3", f"base{axis_name}", "base")
383+
@cbook._rename_parameter("3.3", f"subs{axis_name}", "subs")
384+
@cbook._rename_parameter("3.3", f"nonpos{axis_name}", "nonpos")
385+
def __init__(*, base=10, subs=None, nonpos="clip"):
386+
return base, subs, nonpos
387+
388+
base, subs, nonpos = __init__(**kwargs)
393389
self._transform = LogTransform(base, nonpos)
394390
self.subs = subs
395391

396-
@property
397-
def base(self):
398-
return self._transform.base
392+
base = property(lambda self: self._transform.base)
399393

400394
def set_default_locators_and_formatters(self, axis):
401395
# docstring inherited
@@ -462,6 +456,12 @@ class SymmetricalLogTransform(Transform):
462456

463457
def __init__(self, base, linthresh, linscale):
464458
Transform.__init__(self)
459+
if base <= 1.0:
460+
raise ValueError("'base' must be larger than 1")
461+
if linthresh <= 0.0:
462+
raise ValueError("'linthresh' must be positive")
463+
if linscale <= 0.0:
464+
raise ValueError("'linscale' must be positive")
465465
self.base = base
466466
self.linthresh = linthresh
467467
self.linscale = linscale
@@ -522,19 +522,19 @@ class SymmetricalLogScale(ScaleBase):
522522
523523
Parameters
524524
----------
525-
basex, basey : float, default: 10
525+
base : float, default: 10
526526
The base of the logarithm.
527527
528-
linthreshx, linthreshy : float, default: 2
528+
linthresh : float, default: 2
529529
Defines the range ``(-x, x)``, within which the plot is linear.
530530
This avoids having the plot go to infinity around zero.
531531
532-
subsx, subsy : sequence of int
532+
subs : sequence of int
533533
Where to place the subticks between each major tick.
534534
For example, in a log10 scale: ``[2, 3, 4, 5, 6, 7, 8, 9]`` will place
535535
8 logarithmically spaced minor ticks between each major tick.
536536
537-
linscalex, linscaley : float, optional
537+
linscale : float, optional
538538
This allows the linear range ``(-linthresh, linthresh)`` to be
539539
stretched relative to the logarithmic range. Its value is the number of
540540
decades to use for each half of the linear range. For example, when
@@ -556,40 +556,31 @@ def InvertedSymmetricalLogTransform(self):
556556
return InvertedSymmetricalLogTransform
557557

558558
def __init__(self, axis, **kwargs):
559-
if axis.axis_name == 'x':
560-
base = kwargs.pop('basex', 10.0)
561-
linthresh = kwargs.pop('linthreshx', 2.0)
562-
subs = kwargs.pop('subsx', None)
563-
linscale = kwargs.pop('linscalex', 1.0)
564-
else:
565-
base = kwargs.pop('basey', 10.0)
566-
linthresh = kwargs.pop('linthreshy', 2.0)
567-
subs = kwargs.pop('subsy', None)
568-
linscale = kwargs.pop('linscaley', 1.0)
569-
if kwargs:
570-
warn_deprecated(
571-
'3.2.0',
572-
message=(
573-
f"SymmetricalLogScale got an unexpected keyword "
574-
f"argument {next(iter(kwargs))!r}. "
575-
'In the future this will raise TypeError')
576-
)
577-
# raise TypeError(f"SymmetricalLogScale got an unexpected keyword "
578-
# f"argument {next(iter(kwargs))!r}")
579-
580-
if base <= 1.0:
581-
raise ValueError("'basex/basey' must be larger than 1")
582-
if linthresh <= 0.0:
583-
raise ValueError("'linthreshx/linthreshy' must be positive")
584-
if linscale <= 0.0:
585-
raise ValueError("'linscalex/linthreshy' must be positive")
586-
559+
axis_name = getattr(axis, "axis_name", "x")
560+
# See explanation in LogScale.__init__.
561+
@cbook._rename_parameter("3.3", f"base{axis_name}", "base")
562+
@cbook._rename_parameter("3.3", f"linthresh{axis_name}", "linthresh")
563+
@cbook._rename_parameter("3.3", f"subs{axis_name}", "subs")
564+
@cbook._rename_parameter("3.3", f"linscale{axis_name}", "linscale")
565+
def __init__(*, base=10, linthresh=2, subs=None, linscale=1, **kwargs):
566+
if kwargs:
567+
warn_deprecated(
568+
"3.2.0",
569+
message=(
570+
f"SymmetricalLogScale got an unexpected keyword "
571+
f"argument {next(iter(kwargs))!r}; in the future, "
572+
f"this will raise a TypeError")
573+
)
574+
return base, linthresh, subs, linscale
575+
576+
base, linthresh, subs, linscale = __init__(**kwargs)
587577
self._transform = SymmetricalLogTransform(base, linthresh, linscale)
588-
self.base = base
589-
self.linthresh = linthresh
590-
self.linscale = linscale
591578
self.subs = subs
592579

580+
base = property(lambda self: self._transform.base)
581+
linthresh = property(lambda self: self._transform.linthresh)
582+
linscale = property(lambda self: self._transform.linscale)
583+
593584
def set_default_locators_and_formatters(self, axis):
594585
# docstring inherited
595586
axis.set_major_locator(SymmetricalLogLocator(self.get_transform()))

lib/matplotlib/tests/test_axes.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,9 +1145,9 @@ def test_symlog2():
11451145
x = np.arange(-50, 50, 0.001)
11461146

11471147
fig, axs = plt.subplots(5, 1)
1148-
for ax, linthreshx in zip(axs, [20., 2., 1., 0.1, 0.01]):
1148+
for ax, linthresh in zip(axs, [20., 2., 1., 0.1, 0.01]):
11491149
ax.plot(x, x)
1150-
ax.set_xscale('symlog', linthreshx=linthreshx)
1150+
ax.set_xscale('symlog', linthresh=linthresh)
11511151
ax.grid(True)
11521152
axs[-1].set_ylim(-0.1, 0.1)
11531153

@@ -2236,9 +2236,9 @@ def test_log_scales():
22362236
fig = plt.figure()
22372237
ax = fig.add_subplot(1, 1, 1)
22382238
ax.plot(np.log(np.linspace(0.1, 100)))
2239-
ax.set_yscale('log', basey=5.5)
2239+
ax.set_yscale('log', base=5.5)
22402240
ax.invert_yaxis()
2241-
ax.set_xscale('log', basex=9.0)
2241+
ax.set_xscale('log', base=9.0)
22422242

22432243

22442244
def test_log_scales_no_data():

lib/matplotlib/tests/test_scale.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def test_log_scatter():
8888

8989
def test_logscale_subs():
9090
fig, ax = plt.subplots()
91-
ax.set_yscale('log', subsy=np.array([2, 3, 4]))
91+
ax.set_yscale('log', subs=np.array([2, 3, 4]))
9292
# force draw
9393
fig.canvas.draw()
9494

@@ -108,16 +108,14 @@ def test_logscale_mask():
108108
def test_extra_kwargs_raise_or_warn():
109109
fig, ax = plt.subplots()
110110

111-
# with pytest.raises(TypeError):
112111
with pytest.warns(MatplotlibDeprecationWarning):
113-
ax.set_yscale('linear', nonpos='mask')
112+
ax.set_yscale('linear', foo='mask')
114113

115114
with pytest.raises(TypeError):
116-
ax.set_yscale('log', nonpos='mask')
115+
ax.set_yscale('log', foo='mask')
117116

118-
# with pytest.raises(TypeError):
119117
with pytest.warns(MatplotlibDeprecationWarning):
120-
ax.set_yscale('symlog', nonpos='mask')
118+
ax.set_yscale('symlog', foo='mask')
121119

122120

123121
def test_logscale_invert_transform():
@@ -150,7 +148,7 @@ def test_logscale_nonpos_values():
150148
ax1.hist(xs, range=(-5, 5), bins=10)
151149
ax1.set_yscale('log')
152150
ax2.hist(xs, range=(-5, 5), bins=10)
153-
ax2.set_yscale('log', nonposy='mask')
151+
ax2.set_yscale('log', nonpos='mask')
154152

155153
xdata = np.arange(0, 10, 0.01)
156154
ydata = np.exp(-xdata)

tutorials/introductory/pyplot.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ def f(t):
443443
# symmetric log
444444
plt.subplot(223)
445445
plt.plot(x, y - y.mean())
446-
plt.yscale('symlog', linthreshy=0.01)
446+
plt.yscale('symlog', linthresh=0.01)
447447
plt.title('symlog')
448448
plt.grid(True)
449449

0 commit comments

Comments
 (0)