Skip to content

Commit af80c90

Browse files
authored
Merge pull request #27767 from rcomer/plot-single-legend
Update handling of sequence labels for plot
2 parents 30d7e5a + ffc7ab0 commit af80c90

File tree

4 files changed

+39
-7
lines changed

4 files changed

+39
-7
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Legend labels for ``plot``
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
Previously if a sequence was passed to the *label* parameter of `~.Axes.plot` when
5+
plotting a single dataset, the sequence was automatically cast to string for the legend
6+
label. Now, if the sequence has only one element, that element will be the legend
7+
label. To keep the old behavior, cast the sequence to string before passing.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Legend labels for ``plot``
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
Previously if a sequence was passed to the *label* parameter of `~.Axes.plot` when
5+
plotting a single dataset, the sequence was automatically cast to string for the legend
6+
label. This behavior is now deprecated and in future will error if the sequence length
7+
is not one (consistent with multi-dataset behavior, where the number of elements must
8+
match the number of datasets). To keep the old behavior, cast the sequence to string
9+
before passing.

lib/matplotlib/axes/_base.py

+14-6
Original file line numberDiff line numberDiff line change
@@ -513,14 +513,22 @@ def _plot_args(self, axes, tup, kwargs, *,
513513

514514
label = kwargs.get('label')
515515
n_datasets = max(ncx, ncy)
516-
if n_datasets > 1 and not cbook.is_scalar_or_string(label):
517-
if len(label) != n_datasets:
518-
raise ValueError(f"label must be scalar or have the same "
519-
f"length as the input data, but found "
520-
f"{len(label)} for {n_datasets} datasets.")
516+
517+
if cbook.is_scalar_or_string(label):
518+
labels = [label] * n_datasets
519+
elif len(label) == n_datasets:
521520
labels = label
521+
elif n_datasets == 1:
522+
msg = (f'Passing label as a length {len(label)} sequence when '
523+
'plotting a single dataset is deprecated in Matplotlib 3.9 '
524+
'and will error in 3.11. To keep the current behavior, '
525+
'cast the sequence to string before passing.')
526+
_api.warn_deprecated('3.9', message=msg)
527+
labels = [label]
522528
else:
523-
labels = [label] * n_datasets
529+
raise ValueError(
530+
f"label must be scalar or have the same length as the input "
531+
f"data, but found {len(label)} for {n_datasets} datasets.")
524532

525533
result = (make_artist(axes, x[:, j % ncx], y[:, j % ncy], kw,
526534
{**kwargs, 'label': label})

lib/matplotlib/tests/test_legend.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -1197,12 +1197,20 @@ def test_plot_single_input_multiple_label(label_array):
11971197
x = [1, 2, 3]
11981198
y = [2, 5, 6]
11991199
fig, ax = plt.subplots()
1200-
ax.plot(x, y, label=label_array)
1200+
with pytest.warns(mpl.MatplotlibDeprecationWarning,
1201+
match='Passing label as a length 2 sequence'):
1202+
ax.plot(x, y, label=label_array)
12011203
leg = ax.legend()
12021204
assert len(leg.get_texts()) == 1
12031205
assert leg.get_texts()[0].get_text() == str(label_array)
12041206

12051207

1208+
def test_plot_single_input_list_label():
1209+
fig, ax = plt.subplots()
1210+
line, = ax.plot([[0], [1]], label=['A'])
1211+
assert line.get_label() == 'A'
1212+
1213+
12061214
def test_plot_multiple_label_incorrect_length_exception():
12071215
# check that exception is raised if multiple labels
12081216
# are given, but number of on labels != number of lines

0 commit comments

Comments
 (0)