10000 Check parameter type for legend(labels) by timhoffm · Pull Request #16864 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

Check parameter type for legend(labels) #16864

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/text_labels_and_annotations/custom_legends.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@

fig, ax = plt.subplots()
lines = ax.plot(data)
ax.legend(lines)
Copy link
Member Author
@timhoffm timhoffm Mar 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check caught this wrong usage in an example. 🤓

Fixed to do what is claimed to be done above (" If you simply plot the lines
want a legend item to show up for each one. If you simply plot the lines
and call ax.legend(), you will get the following:").

Overall the example is only semi-instructive. I will keep a rewrite for a separate PR. I just made the minimal change here to make it correct and consistent.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't call it wrong per se. If you remove the argument, no legend will be there at all - which is not what the example wants to convey. It should also trigger a warning like "No handles with labels found" or similar?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe not technically wrong, but carelessly written and misleading. See my comment below.

ax.legend()

##############################################################################
# Note that one legend item per line was created.
# Note that no legend entries were created.
# In this case, we can compose a legend using Matplotlib objects that aren't
# explicitly tied to the data that was plotted. For example:

Expand Down
4 changes: 4 additions & 0 deletions lib/matplotlib/legend.py
Original file line number Diff line number Diff line change
Expand Up @@ -1162,6 +1162,10 @@ def _parse_legend_args(axs, *args, handles=None, labels=None, **kwargs):
# One argument. User defined labels - automatic handle detection.
elif len(args) == 1:
labels, = args
if any(isinstance(l, Artist) for l in labels):
raise TypeError("A single argument passed to legend() must be a "
"list of labels, but found an Artist in there.")

# Get as many handles as there are labels.
handles = [handle for handle, label
in zip(_get_legend_handles(axs, handlers), labels)]
Expand Down
7 changes: 7 additions & 0 deletions lib/matplotlib/tests/test_legend.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,13 @@ def test_legend_handle_label(self):
plt.legend(lines, ['hello world'])
Legend.assert_called_with(plt.gca(), lines, ['hello world'])

def test_legend_handles_only(self):
lines = plt.plot(range(10))
with pytest.raises(TypeError, match='but found an Artist'):
# a single arg is interpreted as labels
# it's a common error to just pass handles
plt.legend(lines)

def test_legend_no_args(self):
lines = plt.plot(range(10), label='hello world')
with mock.patch('matplotlib.legend.Legend') as Legend:
Expand Down
0