Skip to content

Commit 2596815

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 b0ebaae commit 2596815

File tree

7 files changed

+247
-448
lines changed

7 files changed

+247
-448
lines changed
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.

doc/api/next_api_changes/2018-08-17-AL-deprecations.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ The following API elements are deprecated:
66
- ``get_py2exe_datafiles``, ``tk_window_focus``,
77
- ``backend_ps.PsBackendHelper``, ``backend_ps.ps_backend_helper``,
88
- ``cbook.iterable``,
9+
- ``cbook.get_label``, ``cbook.iterable``,
910
- ``font_manager.OSXInstalledFonts``,
1011
- ``mlab.demean``,

lib/matplotlib/__init__.py

Lines changed: 135 additions & 235 deletions
Large diffs are not rendered by default.

lib/matplotlib/axes/_axes.py

Lines changed: 31 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -42,46 +42,6 @@
4242
rcParams = matplotlib.rcParams
4343

4444

45-
def _has_item(data, name):
46-
"""Return whether *data* can be item-accessed with *name*.
47-
48-
This supports data with a dict-like interface (`in` checks item
49-
availability) and with numpy.arrays.
50-
"""
51-
try:
52-
return data.dtype.names is not None and name in data.dtype.names
53-
except AttributeError: # not a numpy array
54-
return name in data
55-
56-
57-
def _plot_args_replacer(args, data):
58-
if len(args) == 1:
59-
return ["y"]
60-
elif len(args) == 2:
61-
# this can be two cases: x,y or y,c
62-
if not _has_item(data, args[1]):
63-
return ["y", "c"]
64-
# it's data, but could be a color code like 'ro' or 'b--'
65-
# -> warn the user in that case...
66-
try:
67-
_process_plot_format(args[1])
68-
except ValueError:
69-
pass
70-
else:
71-
cbook._warn_external(
72-
"Second argument {!r} is ambiguous: could be a color spec but "
73-
"is in data; using as data. Either rename the entry in data "
74-
"or use three arguments to plot.".format(args[1]),
75-
RuntimeWarning)
76-
return ["x", "y"]
77-
elif len(args) == 3:
78-
return ["x", "y", "c"]
79-
else:
80-
raise ValueError("Using arbitrary long args with data is not "
81-
"supported due to ambiguity of arguments.\nUse "
82-
"multiple plotting calls instead.")
83-
84-
8545
def _make_inset_locator(bounds, trans, parent):
8646
"""
8747
Helper function to locate inset axes, used in
@@ -1153,8 +1113,7 @@ def vlines(self, x, ymin, ymax, colors='k', linestyles='solid',
11531113

11541114
@_preprocess_data(replace_names=["positions", "lineoffsets",
11551115
"linelengths", "linewidths",
1156-
"colors", "linestyles"],
1157-
label_namer=None)
1116+
"colors", "linestyles"])
11581117
@docstring.dedent_interpd
11591118
def eventplot(self, positions, orientation='horizontal', lineoffsets=1,
11601119
linelengths=1, linewidths=None, colors=None,
@@ -1370,10 +1329,8 @@ def eventplot(self, positions, orientation='horizontal', lineoffsets=1,
13701329

13711330
#### Basic plotting
13721331

1373-
# The label_naming happens in `matplotlib.axes._base._plot_args`
1374-
@_preprocess_data(replace_names=["x", "y"],
1375-
positional_parameter_names=_plot_args_replacer,
1376-
label_namer=None)
1332+
# Uses a custom implementation of data-kwarg handling in
1333+
# _process_plot_var_args.
13771334
@docstring.dedent_interpd
13781335
def plot(self, *args, scalex=True, scaley=True, **kwargs):
13791336
"""
@@ -1486,7 +1443,6 @@ def plot(self, *args, scalex=True, scaley=True, **kwargs):
14861443
You may suppress the warning by adding an empty format string
14871444
`plot('n', 'o', '', data=obj)`.
14881445
1489-
14901446
Other Parameters
14911447
----------------
14921448
scalex, scaley : bool, optional, default: True
@@ -1513,13 +1469,11 @@ def plot(self, *args, scalex=True, scaley=True, **kwargs):
15131469
lines
15141470
A list of `.Line2D` objects representing the plotted data.
15151471
1516-
15171472
See Also
15181473
--------
15191474
scatter : XY scatter plot with markers of varying size and/or color (
15201475
sometimes also called bubble chart).
15211476
1522-
15231477
Notes
15241478
-----
15251479
**Format Strings**
@@ -1988,7 +1942,7 @@ def xcorr(self, x, y, normed=True, detrend=mlab.detrend_none,
19881942

19891943
#### Specialized plotting
19901944

1991-
@_preprocess_data(replace_names=["x", "y"], label_namer="y")
1945+
# @_preprocess_data() # let 'plot' do the unpacking..
19921946
def step(self, x, y, *args, where='pre', **kwargs):
19931947
"""
19941948
Make a step plot.
@@ -2056,15 +2010,7 @@ def step(self, x, y, *args, where='pre', **kwargs):
20562010
kwargs['drawstyle'] = 'steps-' + where
20572011
return self.plot(x, y, *args, **kwargs)
20582012

2059-
@_preprocess_data(replace_names=["x", "left",
2060-
"height", "width",
2061-
"y", "bottom",
2062-
"color", "edgecolor", "linewidth",
2063-
"tick_label", "xerr", "yerr",
2064-
"ecolor"],
2065-
label_namer=None,
2066-
replace_all_args=True
2067-
)
2013+
@_preprocess_data()
20682014
@docstring.dedent_interpd
20692015
def bar(self, x, height, width=0.8, bottom=None, *, align="center",
20702016
**kwargs):
@@ -2456,7 +2402,7 @@ def barh(self, y, width, height=0.8, left=None, *, align="center",
24562402
align=align, **kwargs)
24572403
return patches
24582404

2459-
@_preprocess_data(label_namer=None)
2405+
@_preprocess_data()
24602406
@docstring.dedent_interpd
24612407
def broken_barh(self, xranges, yrange, **kwargs):
24622408
"""
@@ -2527,9 +2473,9 @@ def broken_barh(self, xranges, yrange, **kwargs):
25272473

25282474
return col
25292475

2530-
@_preprocess_data(replace_all_args=True, label_namer=None)
2531-
def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None,
2532-
bottom=0, label=None):
2476+
@_preprocess_data()
2477+
def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0,
2478+
label=None):
25332479
"""
25342480
Create a stem plot.
25352481
@@ -2687,8 +2633,7 @@ def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None,
26872633

26882634
return stem_container
26892635

2690-
@_preprocess_data(replace_names=["x", "explode", "labels", "colors"],
2691-
label_namer=None)
2636+
@_preprocess_data(replace_names=["x", "explode", "labels", "colors"])
26922637
def pie(self, x, explode=None, labels=None, colors=None,
26932638
autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1,
26942639
startangle=None, radius=None, counterclock=True,
@@ -3303,7 +3248,7 @@ def extract_err(err, data):
33033248

33043249
return errorbar_container # (l0, caplines, barcols)
33053250

3306-
@_preprocess_data(label_namer=None)
3251+
@_preprocess_data()
33073252
def boxplot(self, x, notch=None, sym=None, vert=None, whis=None,
33083253
positions=None, widths=None, patch_artist=None,
33093254
bootstrap=None, usermedians=None, conf_intervals=None,
@@ -4832,7 +4777,7 @@ def _quiver_units(self, args, kw):
48324777
return args
48334778

48344779
# args can by a combination if X, Y, U, V, C and all should be replaced
4835-
@_preprocess_data(replace_all_args=True, label_namer=None)
4780+
@_preprocess_data()
48364781
def quiver(self, *args, **kw):
48374782
# Make sure units are handled for x and y values
48384783
args = self._quiver_units(args, kw)
@@ -4845,13 +4790,12 @@ def quiver(self, *args, **kw):
48454790
quiver.__doc__ = mquiver.Quiver.quiver_doc
48464791

48474792
# args can by either Y or y1,y2,... and all should be replaced
4848-
@_preprocess_data(replace_all_args=True, label_namer=None)
4793+
@_preprocess_data()
48494794
def stackplot(self, x, *args, **kwargs):
48504795
return mstack.stackplot(self, x, *args, **kwargs)
48514796
stackplot.__doc__ = mstack.stackplot.__doc__
48524797

4853-
@_preprocess_data(replace_names=["x", "y", "u", "v", "start_points"],
4854-
label_namer=None)
4798+
@_preprocess_data(replace_names=["x", "y", "u", "v", "start_points"])
48554799
def streamplot(self, x, y, u, v, density=1, linewidth=None, color=None,
48564800
cmap=None, norm=None, arrowsize=1, arrowstyle='-|>',
48574801
minlength=0.1, transform=None, zorder=None,
@@ -4876,7 +4820,7 @@ def streamplot(self, x, y, u, v, density=1, linewidth=None, color=None,
48764820
streamplot.__doc__ = mstream.streamplot.__doc__
48774821

48784822
# args can be some combination of X, Y, U, V, C and all should be replaced
4879-
@_preprocess_data(replace_all_args=True, label_namer=None)
4823+
@_preprocess_data()
48804824
@docstring.dedent_interpd
48814825
def barbs(self, *args, **kw):
48824826
"""
@@ -4890,8 +4834,8 @@ def barbs(self, *args, **kw):
48904834
self.autoscale_view()
48914835
return b
48924836

4893-
@_preprocess_data(replace_names=["x", "y"], label_namer=None,
4894-
positional_parameter_names=["x", "y", "c"])
4837+
# Uses a custom implementation of data-kwarg handling in
4838+
# _process_plot_var_args.
48954839
def fill(self, *args, **kwargs):
48964840
"""
48974841
Plot filled polygons.
@@ -4938,8 +4882,7 @@ def fill(self, *args, **kwargs):
49384882
self.autoscale_view()
49394883
return patches
49404884

4941-
@_preprocess_data(replace_names=["x", "y1", "y2", "where"],
4942-
label_namer=None)
4885+
@_preprocess_data(replace_names=["x", "y1", "y2", "where"])
49434886
@docstring.dedent_interpd
49444887
def fill_between(self, x, y1, y2=0, where=None, interpolate=False,
49454888
step=None, **kwargs):
@@ -5121,8 +5064,7 @@ def get_interp_point(ind):
51215064
self.autoscale_view()
51225065
return collection
51235066

5124-
@_preprocess_data(replace_names=["y", "x1", "x2", "where"],
5125-
label_namer=None)
5067+
@_preprocess_data(replace_names=["y", "x1", "x2", "where"])
51265068
@docstring.dedent_interpd
51275069
def fill_betweenx(self, y, x1, x2=0, where=None,
51285070
step=None, interpolate=False, **kwargs):
@@ -5304,7 +5246,7 @@ def get_interp_point(ind):
53045246
return collection
53055247

53065248
#### plotting z(x,y): imshow, pcolor and relatives, contour
5307-
@_preprocess_data(label_namer=None)
5249+
@_preprocess_data()
53085250
def imshow(self, X, cmap=None, norm=None, aspect=None,
53095251
interpolation=None, alpha=None, vmin=None, vmax=None,
53105252
origin=None, extent=None, shape=None, filternorm=1,
@@ -5571,7 +5513,7 @@ def _pcolorargs(funcname, *args, allmatch=False):
55715513
C = cbook.safe_masked_invalid(C)
55725514
return X, Y, C
55735515

5574-
@_preprocess_data(label_namer=None)
5516+
@_preprocess_data()
55755517
@docstring.dedent_interpd
55765518
def pcolor(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
55775519
vmax=None, **kwargs):
@@ -5808,7 +5750,7 @@ def pcolor(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
58085750
self.autoscale_view()
58095751
return collection
58105752

5811-
@_preprocess_data(label_namer=None)
5753+
@_preprocess_data()
58125754
@docstring.dedent_interpd
58135755
def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
58145756
vmax=None, shading='flat', antialiased=False, **kwargs):
@@ -6021,7 +5963,7 @@ def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
60215963
self.autoscale_view()
60225964
return collection
60235965

6024-
@_preprocess_data(label_namer=None)
5966+
@_preprocess_data()
60255967
@docstring.dedent_interpd
60265968
def pcolorfast(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
60275969
vmax=None, **kwargs):
@@ -6785,7 +6727,7 @@ def hist(self, x, bins=None, range=None, density=None, weights=None,
67856727
else:
67866728
return tops, bins, cbook.silent_list('Lists of Patches', patches)
67876729

6788-
@_preprocess_data(replace_names=["x", "y", "weights"], label_namer=None)
6730+
@_preprocess_data(replace_names=["x", "y", "weights"])
67896731
def hist2d(self, x, y, bins=10, range=None, normed=False, weights=None,
67906732
cmin=None, cmax=None, **kwargs):
67916733
"""
@@ -6893,7 +6835,7 @@ def hist2d(self, x, y, bins=10, range=None, normed=False, weights=None,
68936835

68946836
return h, xedges, yedges, pc
68956837

6896-
@_preprocess_data(replace_names=["x"], label_namer=None)
6838+
@_preprocess_data(replace_names=["x"])
68976839
@docstring.dedent_interpd
68986840
def psd(self, x, NFFT=None, Fs=None, Fc=None, detrend=None,
68996841
window=None, noverlap=None, pad_to=None,
@@ -7128,7 +7070,7 @@ def csd(self, x, y, NFFT=None, Fs=None, Fc=None, detrend=None,
71287070
else:
71297071
return pxy, freqs, line
71307072

7131-
@_preprocess_data(replace_names=["x"], label_namer=None)
7073+
@_preprocess_data(replace_names=["x"])
71327074
@docstring.dedent_interpd
71337075
def magnitude_spectrum(self, x, Fs=None, Fc=None, window=None,
71347076
pad_to=None, sides=None, scale=None,
@@ -7231,7 +7173,7 @@ def magnitude_spectrum(self, x, Fs=None, Fc=None, window=None,
72317173

72327174
return spec, freqs, lines[0]
72337175

7234-
@_preprocess_data(replace_names=["x"], label_namer=None)
7176+
@_preprocess_data(replace_names=["x"])
72357177
@docstring.dedent_interpd
72367178
def angle_spectrum(self, x, Fs=None, Fc=None, window=None,
72377179
pad_to=None, sides=None, **kwargs):
@@ -7313,7 +7255,7 @@ def angle_spectrum(self, x, Fs=None, Fc=None, window=None,
73137255

73147256
return spec, freqs, lines[0]
73157257

7316-
@_preprocess_data(replace_names=["x"], label_namer=None)
7258+
@_preprocess_data(replace_names=["x"])
73177259
@docstring.dedent_interpd
73187260
def phase_spectrum(self, x, Fs=None, Fc=None, window=None,
73197261
pad_to=None, sides=None, **kwargs):
@@ -7394,7 +7336,7 @@ def phase_spectrum(self, x, Fs=None, Fc=None, window=None,
73947336

73957337
return spec, freqs, lines[0]
73967338

7397-
@_preprocess_data(replace_names=["x", "y"], label_namer=None)
7339+
@_preprocess_data(replace_names=["x", "y"])
73987340
@docstring.dedent_interpd
73997341
def cohere(self, x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none,
74007342
window=mlab.window_hanning, noverlap=0, pad_to=None,
@@ -7459,7 +7401,7 @@ def cohere(self, x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none,
74597401

74607402
return cxy, freqs
74617403

7462-
@_preprocess_data(replace_names=["x"], label_namer=None)
7404+
@_preprocess_data(replace_names=["x"])
74637405
@docstring.dedent_interpd
74647406
def specgram(self, x, NFFT=None, Fs=None, Fc=None, detrend=None,
74657407
window=None, noverlap=None,
@@ -7811,7 +7753,7 @@ def matshow(self, Z, **kwargs):
78117753
integer=True))
78127754
return im
78137755

7814-
@_preprocess_data(replace_names=["dataset"], label_namer=None)
7756+
@_preprocess_data(replace_names=["dataset"])
78157757
def violinplot(self, dataset, positions=None, vert=True, widths=0.5,
78167758
showmeans=False, showextrema=True, showmedians=False,
78177759
points=100, bw_method=None):

0 commit comments

Comments
 (0)