Skip to content

Commit 411551c

Browse files
committed
Simplify _preprocess_data using Signature.bind.
Public API change: `step` no longer defaults to using `y` as label_namer. This is consistent with other functions that wrap `plot` (`plot` itself, `loglog`, etc.). (Alternatively, we could make all these functions use `y` as label_namer; I don't really care either way.) The plot-specific data kwarg logic was moved to `_process_plot_var_args`, dropping the need for general callable `positional_parameter_names`, `_plot_args_replacer`, and `positional_parameter_names`. `test_positional_parameter_names_as_function` and tests using `plot_func_varargs` were removed as a consequence. `replace_all_args` can be replaced by making `replace_names=None` trigger replacement of all args, even the "unknown" ones. There was no real use of "replace all known args but not unknown ones" (even if there was, this can easily be handled by explicitly listing the args in replace_names). `test_function_call_with_replace_all_args` was removed as a consequence. `replace_names` no longer complains if some argument names it is given are not present in the "explicit" signature, as long as the function accepts `**kwargs` -- because it may find the arguments in kwargs instead. label_namer no longer triggers if `data` is not passed (if the argument specified by label_namer was a string, then it is likely a categorical and shouldn't be considered as a label anyways). `test_label_problems_at_runtime` was renamed to `test_label_namer_only_if_data` and modified accordingly. Calling data-replaced functions used to trigger RuntimeError in some cases of mismatched arguments; they now trigger TypeError similarly to how normal functions do (`test_more_args_than_pos_parameters`).
1 parent 6b9ff90 commit 411551c

File tree

7 files changed

+224
-426
lines changed

7 files changed

+224
-426
lines changed

doc/api/next_api_changes/2018-02-15-AL-deprecations.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ The following classes, methods, functions, and attributes are deprecated:
1919
- ``backend_qt5.error_msg_qt``, ``backend_qt5.exception_handler``,
2020
- ``backend_wx.FigureCanvasWx.macros``,
2121
- ``cbook.GetRealpathAndStat``, ``cbook.Locked``,
22-
- ``cbook.is_numlike`` (use ``isinstance(..., numbers.Number)`` instead),
23-
``cbook.listFiles``, ``cbook.unicode_safe``,
22+
- ``cbook.get_label``, ``cbook.is_numlike`` (use
23+
``isinstance(..., numbers.Number)`` instead), ``cbook.listFiles``,
24+
``cbook.unicode_safe``,
2425
- ``container.Container.set_remove_method``,
2526
- ``contour.ContourLabeler.cl``, ``.cl_xy``, and ``.cl_cvalues``,
2627
- ``dates.DateFormatter.strftime_pre_1900``, ``dates.DateFormatter.strftime``,
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Axes methods now raise TypeError instead of RuntimeError on mismatched calls
2+
````````````````````````````````````````````````````````````````````````````
3+
4+
In certain cases, Axes methods (and pyplot functions) used to raise a
5+
RuntimeError if they were called with a ``data`` kwarg and otherwise mismatched
6+
arguments. They now raise a ``TypeError`` instead.

lib/matplotlib/__init__.py

Lines changed: 116 additions & 224 deletions
Large diffs are not rendered by default.

lib/matplotlib/axes/_axes.py

Lines changed: 31 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -44,40 +44,6 @@
4444
rcParams = matplotlib.rcParams
4545

4646

47-
def _plot_args_replacer(args, data):
48-
if len(args) == 1:
49-
return ["y"]
50-
elif len(args) == 2:
51-
# this can be two cases: x,y or y,c
52-
if (not args[1] in data and
53-
not (hasattr(data, 'dtype') and
54-
hasattr(data.dtype, 'names') and
55-
data.dtype.names is not None and
56-
args[1] in data.dtype.names)):
57-
# this is not in data, so just assume that it is something which
58-
# will not get replaced (color spec or array like).
59-
return ["y", "c"]
60-
# it's data, but could be a color code like 'ro' or 'b--'
61-
# -> warn the user in that case...
62-
try:
63-
_process_plot_format(args[1])
64-
except ValueError:
65-
pass
66-
else:
67-
cbook._warn_external(
68-
"Second argument {!r} is ambiguous: could be a color spec but "
69-
"is in data; using as data. Either rename the entry in data "
70-
"or use three arguments to plot.".format(args[1]),
71-
RuntimeWarning)
72-
return ["x", "y"]
73-
elif len(args) == 3:
74-
return ["x", "y", "c"]
75-
else:
76-
raise ValueError("Using arbitrary long args with data is not "
77-
"supported due to ambiguity of arguments.\nUse "
78-
"multiple plotting calls instead.")
79-
80-
8147
# The axes module contains all the wrappers to plotting functions.
8248
# All the other methods should go in the _AxesBase class.
8349

@@ -894,8 +860,7 @@ def vlines(self, x, ymin, ymax, colors='k', linestyles='solid',
894860

895861
@_preprocess_data(replace_names=["positions", "lineoffsets",
896862
"linelengths", "linewidths",
897-
"colors", "linestyles"],
898-
label_namer=None)
863+
"colors", "linestyles"])
899864
@docstring.dedent_interpd
900865
def eventplot(self, positions, orientation='horizontal', lineoffsets=1,
901866
linelengths=1, linewidths=None, colors=None,
@@ -1111,10 +1076,8 @@ def eventplot(self, positions, orientation='horizontal', lineoffsets=1,
11111076

11121077
#### Basic plotting
11131078

1114-
# The label_naming happens in `matplotlib.axes._base._plot_args`
1115-
@_preprocess_data(replace_names=["x", "y"],
1116-
positional_parameter_names=_plot_args_replacer,
1117-
label_namer=None)
1079+
# Uses a custom implementation of data-kwarg handling in
1080+
# _process_plot_var_args.
11181081
@docstring.dedent_interpd
11191082
def plot(self, *args, scalex=True, scaley=True, **kwargs):
11201083
"""
@@ -1227,7 +1190,6 @@ def plot(self, *args, scalex=True, scaley=True, **kwargs):
12271190
You may suppress the warning by adding an empty format string
12281191
`plot('n', 'o', '', data=obj)`.
12291192
1230-
12311193
Other Parameters
12321194
----------------
12331195
scalex, scaley : bool, optional, default: True
@@ -1254,13 +1216,11 @@ def plot(self, *args, scalex=True, scaley=True, **kwargs):
12541216
lines
12551217
A list of `.Line2D` objects representing the plotted data.
12561218
1257-
12581219
See Also
12591220
--------
12601221
scatter : XY scatter plot with markers of variing size and/or color (
12611222
sometimes also called bubble chart).
12621223
1263-
12641224
Notes
12651225
-----
12661226
**Format Strings**
@@ -1729,7 +1689,7 @@ def xcorr(self, x, y, normed=True, detrend=mlab.detrend_none,
17291689

17301690
#### Specialized plotting
17311691

1732-
@_preprocess_data(replace_names=["x", "y"], label_namer="y")
1692+
# @_preprocess_data() # let 'plot' do the unpacking..
17331693
def step(self, x, y, *args, where='pre', **kwargs):
17341694
"""
17351695
Make a step plot.
@@ -1798,15 +1758,7 @@ def step(self, x, y, *args, where='pre', **kwargs):
17981758

17991759
return self.plot(x, y, *args, **kwargs)
18001760

1801-
@_preprocess_data(replace_names=["x", "left",
1802-
"height", "width",
1803-
"y", "bottom",
1804-
"color", "edgecolor", "linewidth",
1805-
"tick_label", "xerr", "yerr",
1806-
"ecolor"],
1807-
label_namer=None,
1808-
replace_all_args=True
1809-
)
1761+
@_preprocess_data()
18101762
@docstring.dedent_interpd
18111763
def bar(self, x, height, width=0.8, bottom=None, *, align="center",
18121764
**kwargs):
@@ -2198,7 +2150,7 @@ def barh(self, y, width, height=0.8, left=None, *, align="center",
21982150
align=align, **kwargs)
21992151
return patches
22002152

2201-
@_preprocess_data(label_namer=None)
2153+
@_preprocess_data()
22022154
@docstring.dedent_interpd
22032155
def broken_barh(self, xranges, yrange, **kwargs):
22042156
"""
@@ -2269,9 +2221,9 @@ def broken_barh(self, xranges, yrange, **kwargs):
22692221

22702222
return col
22712223

2272-
@_preprocess_data(replace_all_args=True, label_namer=None)
2273-
def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None,
2274-
bottom=0, label=None):
2224+
@_preprocess_data()
2225+
def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0,
2226+
label=None):
22752227
"""
22762228
Create a stem plot.
22772229
@@ -2429,8 +2381,7 @@ def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None,
24292381

24302382
return stem_container
24312383

2432-
@_preprocess_data(replace_names=["x", "explode", "labels", "colors"],
2433-
label_namer=None)
2384+
@_preprocess_data(replace_names=["x", "explode", "labels", "colors"])
24342385
def pie(self, x, explode=None, labels=None, colors=None,
24352386
autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1,
24362387
startangle=None, radius=None, counterclock=True,
@@ -3045,7 +2996,7 @@ def extract_err(err, data):
30452996

30462997
return errorbar_container # (l0, caplines, barcols)
30472998

3048-
@_preprocess_data(label_namer=None)
2999+
@_preprocess_data()
30493000
def boxplot(self, x, notch=None, sym=None, vert=None, whis=None,
30503001
positions=None, widths=None, patch_artist=None,
30513002
bootstrap=None, usermedians=None, conf_intervals=None,
@@ -4519,7 +4470,7 @@ def _quiver_units(self, args, kw):
45194470
return args
45204471

45214472
# args can by a combination if X, Y, U, V, C and all should be replaced
4522-
@_preprocess_data(replace_all_args=True, label_namer=None)
4473+
@_preprocess_data()
45234474
def quiver(self, *args, **kw):
45244475
# Make sure units are handled for x and y values
45254476
args = self._quiver_units(args, kw)
@@ -4532,13 +4483,12 @@ def quiver(self, *args, **kw):
45324483
quiver.__doc__ = mquiver.Quiver.quiver_doc
45334484

45344485
# args can by either Y or y1,y2,... and all should be replaced
4535-
@_preprocess_data(replace_all_args=True, label_namer=None)
4486+
@_preprocess_data()
45364487
def stackplot(self, x, *args, **kwargs):
45374488
return mstack.stackplot(self, x, *args, **kwargs)
45384489
stackplot.__doc__ = mstack.stackplot.__doc__
45394490

4540-
@_preprocess_data(replace_names=["x", "y", "u", "v", "start_points"],
4541-
label_namer=None)
4491+
@_preprocess_data(replace_names=["x", "y", "u", "v", "start_points"])
45424492
def streamplot(self, x, y, u, v, density=1, linewidth=None, color=None,
45434493
cmap=None, norm=None, arrowsize=1, arrowstyle='-|>',
45444494
minlength=0.1, transform=None, zorder=None,
@@ -4563,7 +4513,7 @@ def streamplot(self, x, y, u, v, density=1, linewidth=None, color=None,
45634513
streamplot.__doc__ = mstream.streamplot.__doc__
45644514

45654515
# args can be some combination of X, Y, U, V, C and all should be replaced
4566-
@_preprocess_data(replace_all_args=True, label_namer=None)
4516+
@_preprocess_data()
45674517
@docstring.dedent_interpd
45684518
def barbs(self, *args, **kw):
45694519
"""
@@ -4577,8 +4527,8 @@ def barbs(self, *args, **kw):
45774527
self.autoscale_view()
45784528
return b
45794529

4580-
@_preprocess_data(replace_names=["x", "y"], label_namer=None,
4581-
positional_parameter_names=["x", "y", "c"])
4530+
# Uses a custom implementation of data-kwarg handling in
4531+
# _process_plot_var_args.
45824532
def fill(self, *args, **kwargs):
45834533
"""
45844534
Plot filled polygons.
@@ -4625,8 +4575,7 @@ def fill(self, *args, **kwargs):
46254575
self.autoscale_view()
46264576
return patches
46274577

4628-
@_preprocess_data(replace_names=["x", "y1", "y2", "where"],
4629-
label_namer=None)
4578+
@_preprocess_data(replace_names=["x", "y1", "y2", "where"])
46304579
@docstring.dedent_interpd
46314580
def fill_between(self, x, y1, y2=0, where=None, interpolate=False,
46324581
step=None, **kwargs):
@@ -4808,8 +4757,7 @@ def get_interp_point(ind):
48084757
self.autoscale_view()
48094758
return collection
48104759

4811-
@_preprocess_data(replace_names=["y", "x1", "x2", "where"],
4812-
label_namer=None)
4760+
@_preprocess_data(replace_names=["y", "x1", "x2", "where"])
48134761
@docstring.dedent_interpd
48144762
def fill_betweenx(self, y, x1, x2=0, where=None,
48154763
step=None, interpolate=False, **kwargs):
@@ -4991,7 +4939,7 @@ def get_interp_point(ind):
49914939
return collection
49924940

49934941
#### plotting z(x,y): imshow, pcolor and relatives, contour
4994-
@_preprocess_data(label_namer=None)
4942+
@_preprocess_data()
49954943
def imshow(self, X, cmap=None, norm=None, aspect=None,
49964944
interpolation=None, alpha=None, vmin=None, vmax=None,
49974945
origin=None, extent=None, shape=None, filternorm=1,
@@ -5256,7 +5204,7 @@ def _pcolorargs(funcname, *args, allmatch=False):
52565204
C = cbook.safe_masked_invalid(C)
52575205
return X, Y, C
52585206

5259-
@_preprocess_data(label_namer=None)
5207+
@_preprocess_data()
52605208
@docstring.dedent_interpd
52615209
def pcolor(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
52625210
vmax=None, **kwargs):
@@ -5493,7 +5441,7 @@ def pcolor(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
54935441
self.autoscale_view()
54945442
return collection
54955443

5496-
@_preprocess_data(label_namer=None)
5444+
@_preprocess_data()
54975445
@docstring.dedent_interpd
54985446
def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
54995447
vmax=None, shading='flat', antialiased=False, **kwargs):
@@ -5706,7 +5654,7 @@ def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
57065654
self.autoscale_view()
57075655
return collection
57085656

5709-
@_preprocess_data(label_namer=None)
5657+
@_preprocess_data()
57105658
@docstring.dedent_interpd
57115659
def pcolorfast(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
57125660
vmax=None, **kwargs):
@@ -6465,7 +6413,7 @@ def hist(self, x, bins=None, range=None, density=None, weights=None,
64656413
else:
64666414
return tops, bins, cbook.silent_list('Lists of Patches', patches)
64676415

6468-
@_preprocess_data(replace_names=["x", "y", "weights"], label_namer=None)
6416+
@_preprocess_data(replace_names=["x", "y", "weights"])
64696417
def hist2d(self, x, y, bins=10, range=None, normed=False, weights=None,
64706418
cmin=None, cmax=None, **kwargs):
64716419
"""
@@ -6573,7 +6521,7 @@ def hist2d(self, x, y, bins=10, range=None, normed=False, weights=None,
65736521

65746522
return h, xedges, yedges, pc
65756523

6576-
@_preprocess_data(replace_names=["x"], label_namer=None)
6524+
@_preprocess_data(replace_names=["x"])
65776525
@docstring.dedent_interpd
65786526
def psd(self, x, NFFT=None, Fs=None, Fc=None, detrend=None,
65796527
window=None, noverlap=None, pad_to=None,
@@ -6808,7 +6756,7 @@ def csd(self, x, y, NFFT=None, Fs=None, Fc=None, detrend=None,
68086756
else:
68096757
return pxy, freqs, line
68106758

6811-
@_preprocess_data(replace_names=["x"], label_namer=None)
6759+
@_preprocess_data(replace_names=["x"])
68126760
@docstring.dedent_interpd
68136761
def magnitude_spectrum(self, x, Fs=None, Fc=None, window=None,
68146762
pad_to=None, sides=None, scale=None,
@@ -6911,7 +6859,7 @@ def magnitude_spectrum(self, x, Fs=None, Fc=None, window=None,
69116859

69126860
return spec, freqs, lines[0]
69136861

6914-
@_preprocess_data(replace_names=["x"], label_namer=None)
6862+
@_preprocess_data(replace_names=["x"])
69156863
@docstring.dedent_interpd
69166864
def angle_spectrum(self, x, Fs=None, Fc=None, window=None,
69176865
pad_to=None, sides=None, **kwargs):
@@ -6993,7 +6941,7 @@ def angle_spectrum(self, x, Fs=None, Fc=None, window=None,
69936941

69946942
return spec, freqs, lines[0]
69956943

6996-
@_preprocess_data(replace_names=["x"], label_namer=None)
6944+
@_preprocess_data(replace_names=["x"])
69976945
@docstring.dedent_interpd
69986946
def phase_spectrum(self, x, Fs=None, Fc=None, window=None,
69996947
pad_to=None, sides=None, **kwargs):
@@ -7074,7 +7022,7 @@ def phase_spectrum(self, x, Fs=None, Fc=None, window=None,
70747022

70757023
return spec, freqs, lines[0]
70767024

7077-
@_preprocess_data(replace_names=["x", "y"], label_namer=None)
7025+
@_preprocess_data(replace_names=["x", "y"])
70787026
@docstring.dedent_interpd
70797027
def cohere(self, x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none,
70807028
window=mlab.window_hanning, noverlap=0, pad_to=None,
@@ -7139,7 +7087,7 @@ def cohere(self, x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none,
71397087

71407088
return cxy, freqs
71417089

7142-
@_preprocess_data(replace_names=["x"], label_namer=None)
7090+
@_preprocess_data(replace_names=["x"])
71437091
@docstring.dedent_interpd
71447092
def specgram(self, x, NFFT=None, Fs=None, Fc=None, detrend=None,
71457093
window=None, noverlap=None,
@@ -7488,7 +7436,7 @@ def matshow(self, Z, **kwargs):
74887436
integer=True))
74897437
return im
74907438

7491-
@_preprocess_data(replace_names=["dataset"], label_namer=None)
7439+
@_preprocess_data(replace_names=["dataset"])
74927440
def violinplot(self, dataset, positions=None, vert=True, widths=0.5,
74937441
showmeans=False, showextrema=True, showmedians=False,
74947442
points=100, bw_method=None):

0 commit comments

Comments
 (0)