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

Skip to content

Commit acd0e2f

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 d511ab8 commit acd0e2f

File tree

9 files changed

+85
-99
lines changed

9 files changed

+85
-99
lines changed

doc/api/next_api_changes/2019-07-24-AL.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,11 @@ Passing unsupported keyword arguments to `.ScaleBase` and its subclasses
66

77
If extra kwargs are pased to `.LogScale`, `TypeError` will now be
88
raised instead of `ValueError`.
9+
10+
These classes used to take keyword arguments that depends on the axis
11+
orientation ("basex" vs "basey", "nonposx" vs "nonposy"); these parameter
12+
names are now deprecated in favor of "base", "nonpos", etc. This deprecation
13+
also affects e.g. ``ax.set_yscale("log", basey=...)`` which must now be
14+
spelled ``ax.set_yscale("log", base=...)``. The only place where "basex", etc.
15+
remain in use is in the helper functions `~.Axes.loglog`, `~.Axes.semilogx`,
16+
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
@@ -1767,16 +1767,13 @@ def loglog(self, *args, **kwargs):
17671767
**kwargs
17681768
All parameters supported by `.plot`.
17691769
"""
1770-
dx = {k: kwargs.pop(k) for k in ['basex', 'subsx', 'nonposx']
1770+
dx = {k[:-1]: kwargs.pop(k) for k in ['basex', 'subsx', 'nonposx']
17711771
if k in kwargs}
1772-
dy = {k: kwargs.pop(k) for k in ['basey', 'subsy', 'nonposy']
1773-
if k in kwargs}
1774-
17751772
self.set_xscale('log', **dx)
1773+
dy = {k[:-1]: kwargs.pop(k) for k in ['basey', 'subsy', 'nonposy']
1774+
if k in kwargs}
17761775
self.set_yscale('log', **dy)
1777-
1778-
l = self.plot(*args, **kwargs)
1779-
return l
1776+
return self.plot(*args, **kwargs)
17801777

17811778
# @_preprocess_data() # let 'plot' do the unpacking..
17821779
@docstring.dedent_interpd
@@ -1820,12 +1817,10 @@ def semilogx(self, *args, **kwargs):
18201817
**kwargs
18211818
All parameters supported by `.plot`.
18221819
"""
1823-
d = {k: kwargs.pop(k) for k in ['basex', 'subsx', 'nonposx']
1820+
d = {k[:-1]: kwargs.pop(k) for k in ['basex', 'subsx', 'nonposx']
18241821
if k in kwargs}
1825-
18261822
self.set_xscale('log', **d)
1827-
l = self.plot(*args, **kwargs)
1828-
return l
1823+
return self.plot(*args, **kwargs)
18291824

18301825
# @_preprocess_data() # let 'plot' do the unpacking..
18311826
@docstring.dedent_interpd
@@ -1869,12 +1864,10 @@ def semilogy(self, *args, **kwargs):
18691864
**kwargs
18701865
All parameters supported by `.plot`.
18711866
"""
1872-
d = {k: kwargs.pop(k) for k in ['basey', 'subsy', 'nonposy']
1867+
d = {k[:-1]: kwargs.pop(k) for k in ['basey', 'subsy', 'nonposy']
18731868
if k in kwargs}
18741869
self.set_yscale('log', **d)
1875-
l = self.plot(*args, **kwargs)
1876-
1877-
return l
1870+
return self.plot(*args, **kwargs)
18781871

18791872
@_preprocess_data(replace_names=["x"], label_namer="x")
18801873
def acorr(self, x, **kwargs):
@@ -2323,11 +2316,11 @@ def bar(self, x, height, width=0.8, bottom=None, *, align="center",
23232316
if orientation == 'vertical':
23242317
self._process_unit_info(xdata=x, ydata=height, kwargs=kwargs)
23252318
if log:
2326-
self.set_yscale('log', nonposy='clip')
2319+
self.set_yscale('log', nonpos='clip')
23272320
elif orientation == 'horizontal':
23282321
self._process_unit_info(xdata=width, ydata=y, kwargs=kwargs)
23292322
if log:
2330-
self.set_xscale('log', nonposx='clip')
2323+
self.set_xscale('log', nonpos='clip')
23312324

23322325
# lets do some conversions now since some types cannot be
23332326
# subtracted uniformly
@@ -6746,10 +6739,10 @@ def hist(self, x, bins=None, range=None, density=False, weights=None,
67466739

67476740
if log:
67486741
if orientation == 'horizontal':
6749-
self.set_xscale('log', nonposx='clip')
6742+
self.set_xscale('log', nonpos='clip')
67506743
logbase = self.xaxis._scale.base
67516744
else: # orientation == 'vertical'
6752-
self.set_yscale('log', nonposy='clip')
6745+
self.set_yscale('log', nonpos='clip')
67536746
logbase = self.yaxis._scale.base
67546747

67556748
# Setting a minimum of 0 results in problems for log plots

lib/matplotlib/scale.py

Lines changed: 49 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -292,8 +292,11 @@ class LogTransform(Transform):
292292

293293
def __init__(self, base, nonpos='clip'):
294294
Transform.__init__(self)
295+
if base <= 0 or base == 1:
296+
raise ValueError('The log base cannot be <= 0 or == 1')
295297
self.base = base
296-
self._clip = {"clip": True, "mask": False}[nonpos]
298+
self._clip = cbook._check_getitem(
299+
{"clip": True, "mask": False}, nonpos=nonpos)
297300

298301
def __str__(self):
299302
return "{}(base={}, nonpos={!r})".format(
@@ -368,41 +371,27 @@ def __init__(self, axis, **kwargs):
368371
----------
369372
axis : `~matplotlib.axis.Axis`
370373
The axis for the scale.
371-
basex, basey : float, default: 10
374+
base : float, default: 10
372375
The base of the logarithm.
373-
nonposx, nonposy : {'clip', 'mask'}, default: 'clip'
376+
nonpos : {'clip', 'mask'}, default: 'clip'
374377
Determines the behavior for non-positive values. They can either
375378
be masked as invalid, or clipped to a very small positive number.
376-
subsx, subsy : sequence of int, default: None
377-
Where to place the subticks between each major tick.
378-
For example, in a log10 scale: ``[2, 3, 4, 5, 6, 7, 8, 9]``
379-
will place 8 logarithmically spaced minor ticks between
380-
each major tick.
379+
subs : sequence of int, default: None
380+
Where to place the subticks between each major tick. For example,
381+
in a log10 scale, ``[2, 3, 4, 5, 6, 7, 8, 9]`` will place 8
382+
logarithmically spaced minor ticks between each major tick.
381383
"""
382-
if axis.axis_name == 'x':
383-
base = kwargs.pop('basex', 10.0)
384-
subs = kwargs.pop('subsx', None)
385-
nonpos = kwargs.pop('nonposx', 'clip')
386-
cbook._check_in_list(['mask', 'clip'], nonposx=nonpos)
387-
else:
388-
base = kwargs.pop('basey', 10.0)
389-
subs = kwargs.pop('subsy', None)
390-
nonpos = kwargs.pop('nonposy', 'clip')
391-
cbook._check_in_list(['mask', 'clip'], nonposy=nonpos)
392-
393-
if kwargs:
394-
raise TypeError(f"LogScale got an unexpected keyword "
395-
f"argument {next(iter(kwargs))!r}")
396-
397-
if base <= 0 or base == 1:
398-
raise ValueError('The log base cannot be <= 0 or == 1')
384+
@cbook._rename_parameter("3.2", f"base{axis.axis_name}", "base")
385+
@cbook._rename_parameter("3.2", f"subs{axis.axis_name}", "subs")
386+
@cbook._rename_parameter("3.2", f"nonpos{axis.axis_name}", "nonpos")
387+
def __init__(*, base=10, subs=None, nonpos='clip'):
388+
return base, subs, nonpos
399389

390+
base, subs, nonpos = __init__(**kwargs)
400391
self._transform = LogTransform(base, nonpos)
401392
self.subs = subs
402393

403-
@property
404-
def base(self):
405-
return self._transform.base
394+
base = property(lambda self: self._transform.base)
406395

407396
def set_default_locators_and_formatters(self, axis):
408397
# docstring inherited
@@ -473,6 +462,12 @@ class SymmetricalLogTransform(Transform):
473462

474463
def __init__(self, base, linthresh, linscale):
475464
Transform.__init__(self)
465+
if base <= 1.0:
466+
raise ValueError("'base' must be larger than 1")
467+
if linthresh <= 0.0:
468+
raise ValueError("'linthresh' must be positive")
469+
if linscale <= 0.0:
470+
raise ValueError("'linscale' must be positive")
476471
self.base = base
477472
self.linthresh = linthresh
478473
self.linscale = linscale
@@ -536,19 +531,19 @@ class SymmetricalLogScale(ScaleBase):
536531
537532
Parameters
538533
----------
539-
basex, basey : float
534+
base : float
540535
The base of the logarithm. Defaults to 10.
541536
542-
linthreshx, linthreshy : float
537+
linthresh : float
543538
Defines the range ``(-x, x)``, within which the plot is linear.
544539
This avoids having the plot go to infinity around zero. Defaults to 2.
545540
546-
subsx, subsy : sequence of int
541+
subs : sequence of int
547542
Where to place the subticks between each major tick.
548543
For example, in a log10 scale: ``[2, 3, 4, 5, 6, 7, 8, 9]`` will place
549544
8 logarithmically spaced minor ticks between each major tick.
550545
551-
linscalex, linscaley : float, optional
546+
linscale : float, optional
552547
This allows the linear range ``(-linthresh, linthresh)`` to be
553548
stretched relative to the logarithmic range. Its value is the number of
554549
decades to use for each half of the linear range. For example, when
@@ -562,40 +557,31 @@ class SymmetricalLogScale(ScaleBase):
562557
InvertedSymmetricalLogTransform = InvertedSymmetricalLogTransform
563558

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

581+
base = property(lambda self: self._transform.base)
582+
linthresh = property(lambda self: self._transform.linthresh)
583+
linscale = property(lambda self: self._transform.linscale)
584+
599585
def set_default_locators_and_formatters(self, axis):
600586
# docstring inherited
601587
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
@@ -1077,9 +1077,9 @@ def test_symlog2():
10771077
x = np.arange(-50, 50, 0.001)
10781078

10791079
fig, axs = plt.subplots(5, 1)
1080-
for ax, linthreshx in zip(axs, [20., 2., 1., 0.1, 0.01]):
1080+
for ax, linthresh in zip(axs, [20., 2., 1., 0.1, 0.01]):
10811081
ax.plot(x, x)
1082-
ax.set_xscale('symlog', linthreshx=linthreshx)
1082+
ax.set_xscale('symlog', linthresh=linthresh)
10831083
ax.grid(True)
10841084
axs[-1].set_ylim(-0.1, 0.1)
10851085

@@ -2139,9 +2139,9 @@ def test_log_scales():
21392139
fig = plt.figure()
21402140
ax = fig.add_subplot(1, 1, 1)
21412141
ax.plot(np.log(np.linspace(0.1, 100)))
2142-
ax.set_yscale('log', basey=5.5)
2142+
ax.set_yscale('log', base=5.5)
21432143
ax.invert_yaxis()
2144-
ax.set_xscale('log', basex=9.0)
2144+
ax.set_xscale('log', base=9.0)
21452145

21462146

21472147
def test_log_scales_invalid():

lib/matplotlib/tests/test_scale.py

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

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

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

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

116115
with pytest.raises(TypeError):
117-
ax.set_yscale('log', nonpos='mask')
116+
ax.set_yscale('log', foo='mask')
118117

119-
# with pytest.raises(TypeError):
120118
with pytest.warns(MatplotlibDeprecationWarning):
121-
ax.set_yscale('symlog', nonpos='mask')
119+
ax.set_yscale('symlog', foo='mask')
122120

123121

124122
def test_logscale_invert_transform():
@@ -151,7 +149,7 @@ def test_logscale_nonpos_values():
151149
ax1.hist(xs, range=(-5, 5), bins=10)
152150
ax1.set_yscale('log')
153151
ax2.hist(xs, range=(-5, 5), bins=10)
154-
ax2.set_yscale('log', nonposy='mask')
152+
ax2.set_yscale('log', nonpos='mask')
155153

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

tutorials/introductory/pyplot.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ def f(t):
453453
# symmetric log
454454
plt.subplot(223)
455455
plt.plot(x, y - y.mean())
456-
plt.yscale('symlog', linthreshy=0.01)
456+
plt.yscale('symlog', linthresh=0.01)
457457
plt.title('symlog')
458458
plt.grid(True)
459459

0 commit comments

Comments
 (0)