Skip to content

Commit 58dc06c

Browse files
committed
Warn on redundant definition of plot properties
`plt.plot(x, y, fmt)` allows to specify marker, linestyle and color via `fmt`. Warn if there are additionally keyword arguments that specify the same properties. Closes #19275.
1 parent acdfe3f commit 58dc06c

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

lib/matplotlib/axes/_base.py

+21-2
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ def __call__(self, ax, renderer):
117117
self._transform - ax.figure.transSubfigure)
118118

119119

120+
_FORMAT_UNSET = 'None'
121+
120122
def _process_plot_format(fmt):
121123
"""
122124
Convert a MATLAB style color/line style format string to a (*linestyle*,
@@ -129,6 +131,10 @@ def _process_plot_format(fmt):
129131
* 'r--': red dashed lines
130132
* 'C2--': the third color in the color cycle, dashed lines
131133
134+
The format is absolute in the sense that if a linestyle or marker is not
135+
defined in *fmt*, there is no line or marker. This is expressed by
136+
returning _FORMAT_UNSET for the respective quantity.
137+
132138
See Also
133139
--------
134140
matplotlib.Line2D.lineStyles, matplotlib.colors.cnames
@@ -196,9 +202,9 @@ def _process_plot_format(fmt):
196202
if linestyle is None and marker is None:
197203
linestyle = mpl.rcParams['lines.linestyle']
198204
if linestyle is None:
199-
linestyle = 'None'
205+
linestyle = _FORMAT_UNSET
200206
if marker is None:
201-
marker = 'None'
207+
marker = _FORMAT_UNSET
202208

203209
return linestyle, marker, color
204210

@@ -461,6 +467,19 @@ def _plot_args(self, tup, kwargs, return_kwargs=False):
461467
for prop_name, val in zip(('linestyle', 'marker', 'color'),
462468
(linestyle, marker, color)):
463469
if val is not None:
470+
# check for conflicts between fmt and kwargs
471+
if prop_name in kwargs and val != _FORMAT_UNSET:
472+
# Technically ``plot(x, y, 'o', ls='--')`` is a conflict
473+
# because 'o' implicitly unsets the linestyle
474+
# (linestyle=_FORMAT_UNSET).
475+
# We'll gracefully not warn in this case because an
476+
# explicit set via kwargs can be seen as intention to
477+
# override an implicit unset.
478+
_api.warn_external(
479+
f"{prop_name} is redundantly defined by the "
480+
f"'{prop_name}' keyword argument and the fmt string "
481+
f'"{fmt}" (-> {prop_name}={val!r}). The keyword '
482+
f"argument will take precedence.")
464483
kw[prop_name] = val
465484

466485
if len(xy) == 2:

lib/matplotlib/tests/test_axes.py

+10
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,16 @@ def test_fill_units():
624624
fig.autofmt_xdate()
625625

626626

627+
@pytest.mark.xfail('Warning not yet activated.')
628+
def test_plot_format_kwarg_redundant():
629+
with pytest.warns(UserWarning, match="marker .* redundantly defined"):
630+
plt.plot([0], [0], 'o', marker='x')
631+
with pytest.warns(UserWarning, match="linestyle .* redundantly defined"):
632+
plt.plot([0], [0], '-', linestyle='--')
633+
with pytest.warns(UserWarning, match="color .* redundantly defined"):
634+
plt.plot([0], [0], 'r', color='blue')
635+
636+
627637
@image_comparison(['single_point', 'single_point'])
628638
def test_single_point():
629639
# Issue #1796: don't let lines.marker affect the grid

0 commit comments

Comments
 (0)