-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Add multiple label support for Axes.plot() #16178
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
Add multiple label support for Axes.plot() #16178
Conversation
I don't like the fact that plot() supports that to start with, but given that it does (and that that's unlikely to get deprecated), I guess the feature makes sense. |
I'm -0.75 on this. What about all the other things associated with labels=['one', 'two', 'three']
for i in range(3):
plt.plot(x, y[i,:], label=labels[i])
plt.legend() |
I agree that |
I think some more vectorized input options to many of the plotting functions would be great; but I do see the problem of maintainability of those organically grown functions.
works fine already now. |
If one has multiple labelled datasets, using a structured data structure like
|
I'm +/- 0 on this.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was the source of a long discussion on this weeks phone call: https://hackmd.io/hELmT6nMToSPhpP8-0mUZA?both#16178-labels-to-all-lines-plotted-in-plot
The very short summary:
- we like the idea, it should go in
- only work for a single x, y pair of inputs (like we do with the
data
kwarg) - needs a whats_new entry
Please rebase to fix the conflicts. |
I don't think you rebased quite correctly; there should not be so many commits here. |
b71d144
to
f33a30e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commits should be squashed before/when merging.
@tacaswell you are blocking on this... |
Looking at the tests: the first and last look good, but the middle two indicate that the intended behavior is to allow mismatches between the number of lines and the number of labels, and that labels don't even have to be strings. I don't think this is a good idea. Instead of bending over backwards to accept almost any user input, I think we should leave the user with some responsibility to provide inputs that make sense. Am I misinterpreting something? |
@efiring in the current implementation labels don't have to be strings. So this is just backwards-compatible. Whether we want strings-only should be discussed separately because it's an API change. |
This seems reasonable, but it looks like it is not checking if we are getting the multiple-x-y-pairs and either failing: plt.plot([1, 2], [[3, 4], [10, 11]], [5, 6], [7, 8], label=['a', 'b']);
plt.legend() This probably also needs an API change note. The signature on |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue of allowing this with plt.plot(x, y, x1, y1, labels=[...])
should either be addressed or intentionally dismissed.
Anyone can clear this review.
2c5cab0
to
6a979fb
Compare
Co-authored-by: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com>
e3fd5fc
to
24325da
Compare
@tacaswell's comment #16178 (review) is not addressed (can be checked by the example above the linked comment. I'd be ok with the current state. I.e. multiple labels only supporting the case |
I'm still not a fan of this just because import matplotlib.pyplot as plt
import numpy as np
x = np.array([1, 2, 3])
y = np.array([[1, 2, 3], [4, 5, 6]]).T
x1 = np.array([1, 2, 3, 4]) * 2
y1 = np.array([[1, 2, 3, 5], [4, 5, 6, 7]]).T
fig, ax = plt.subplots()
ax.plot(x, y, x1, y1, label=[['one', 'two'], ['three', 'four']])
ax.legend()
plt.show() I get If I instead do:
We get an error:
I am not convinced that it is a good idea to add a feature that only half works with the existing API. This is all in addition to my knee-jerk reaction that if we add this, then we will need to accept tuples for other properties, and we really don't want to go down that road. I think our API should make basic things easy, but as soon as you want to get fancy, the user is just going to have to do a bit of work, i.e. doing the above as for yy, lab in zip(y, ['first', 'second']):
ax.plot(x, yy, label=lab)
for yy, lab in zip(y1, ['third', 'fourth']):
ax.plot(x1, yy, label=lab) is just as clear, and allows the user to specify other things in the for-loop, and/or keep the handles to the lines. |
@jklymak I appreciate your skepticism, and have shared it in the beginning. But #16178 (review) changed my mind that this is actually worth adding for the case I don't care too much about the Concerning "accept tuples for other properties": Labels are special in that compared to other properties they cannot be automatically generated/cycled. Due to this an extension of just |
Fair enough - but if we go down this road, I'm afraid we need a better error message: if I pass in 4 data sets and it tells me I only passed in two, it is relatively confusing. |
Agreed. I suspect that the proper place to check is before matplotlib/lib/matplotlib/axes/_base.py Line 300 in 3798e5f
with something like
|
I agree with @jklymak and @timhoffm here. The behavior in #16178 (comment) is definitely "wrong". If we start out raising now we will not break anything that used to work (as this is a new feature) and if someone comes with a compelling reason to support multiple labels (either through nested broadcasting or the raveled version) we can always add that in the future in a backwards compatible way. @yozhikoff Sorry this has taken almost a year to get through. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should raise in the mulitple sets of input case because it is not clear what the broadcasting rules should be.
Thanks @yozhikoff ! Congratulations on what (I think) is your first merged Matplotlib PR 🎉 Hopefully we will hear from you agian! |
@tacaswell Hopefully yes! I am a huge fan of Matplotlib, would love to work on improving it. |
PR Summary
Since plt.plot() supports multidimensional input it would be reasonable to support multiple labels.
It was mentioned on SO here.
It works with all iterable types, with string instances and non-iterables the behavior is just the same as before.
PR Checklist