Skip to content
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

Idea: unite xlim and set_xlim to same function #15938

Open
kolibril13 opened this issue Dec 14, 2019 · 10 comments
Open

Idea: unite xlim and set_xlim to same function #15938

kolibril13 opened this issue Dec 14, 2019 · 10 comments
Labels
API: consistency keep Items to be ignored by the “Stale” Github Action topic: pyplot API

Comments

@kolibril13
Copy link
Contributor

I think it is confusing that the limits are normally set by xlim and in subplots by set_xlim.
Would it not be nice to use the same name ax.xlim(0,1) for subplots ?

import numpy as np
import matplotlib.pyplot as plt
plt.figure(1)
plt.xlim(0, 1)
plt.plot([1, 2])

fix, ax = plt.subplots()
ax.set_xlim(0, 1) ##  why not ax.xlim(0,1) ?
ax.plot([1, 2])
@anntzer
Copy link
Contributor

anntzer commented Dec 14, 2019

Even if we did this, we wouldn't be able to replace e.g. ax.set_title() by ax.title() (for similarity with plt.title() because ax.title already exists (that's the Text object)), so I don't think this is a good idea...

On the other hand, we could add all the set_foo synonyms to pyplot (plt.set_xlim(), plt.set_title(), ...) and encourage their use...

@kolibril13
Copy link
Contributor Author

Good point with ax.title().
One could rename ax.set_title to ax.ax_title.
But I would find it nice, when title is not touched at all.

My suggestion was more that it is possible to write ax.set_xlim as well as ax.xlim for valid options to adjust the range of the plot.
That would firstly conserve the way it is done today, and does not break old plots.
But it is easier to new learners, cause they dont need to learn two functions which do the same thing.

I find your idea of plt.set_xlim() not so pretty because it is more verbose.

Thanks for your answer!

@jklymak
Copy link
Member

jklymak commented Dec 14, 2019

ax.set_blah is the general way to set things in matplotlib. I'd be opposed to random shortcuts.

@anntzer
Copy link
Contributor

anntzer commented Dec 14, 2019

Changing/adding an alias for ax.set_title() to ax.ax_title() or from ax.set_xlim() to ax.xlim() is basically a nonstarter.
On the other hand, I have seen enough people confused by the name difference in plt.title/ax.set_title or plt.xlim/ax.set_xlim that I think we should consider having plt.set_title (even though it is a straight alias to plt.title) and plt.set_xlim / plt.get_xlim.

@timhoffm
Copy link
Member

timhoffm commented Dec 14, 2019

TL;DR In summary, this is a major decision which would need careful consideration.

As of now pyplot and the OO interface are different but consistent within themselves. pyplot follows the MATLAB style of having a single function working as getter/setter depending on given parameters. The objects follow a classical getter/setter function pattern using get_*/set_*. It's unfortunate that we have these multiple paradigms. But once you know the rule, you can translate between them.

We need to be extremely careful when adding new API and new patterns. In particular, I suspect that supporting plt.set_xlim just dillutes the structure and people will ask why there is plt.xlim and plt.set_xlim, and also why there is not ax.xlim.

For sure such changes should not be implemented on single functions. If we want to go that direction, it would have to be consistently all over the (pyplot) library. There's also the question if we should support properties in the OO interface (but not going into the details of the pro's and con's of that now).

What we can do right now
In the short term, it would really help to better document the similarities and differences between pyplot and OO style. The current docs are not quite instructive on that; and no matter what we could add immediately what we plan to do in the long term, these are public APIs and will therefore be around for a long time.

Additional thoughs
It may even be a good idea to have a complete separation on the API level, in the sense that there should be non-pyplot helper functions for figure/subplot creation (It might be that we still use the same figure management under the hood). That way, one can have two completely separate APIs. Emphasizing this may help to reduce confusion.

@kolibril13
Copy link
Contributor Author

As a less experienced matplotlib user I can don't have an clear idea of function-names in the pyplot and OO style.
To give an example:
A few month ago I would have read an example for annotating a plot.
There they use the lines:

fig, ax = plt.subplots()
line, = ax.plot(t, s, lw=2)
ax.annotate(... 

And I would not have known that it is possible to just write

plt.annotate(...

also, with the same logic as with xlim one could guess then the correct use would be:

ax.set_annotate(...
plt.annotate(...

Therefore I support the idea of the separation on the API level.
Is it maybe possible to have the whole API default to the pyplot style, but in every example a button that switches the example from pyplot to OO?

@anntzer
Copy link
Contributor

anntzer commented Dec 15, 2019

My proposal would allow you to mechanically translate

import numpy as np
import matplotlib.pyplot as plt

fig, ax = plt.subplots()

t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
line, = ax.plot(t, s, lw=2)

ax.annotate('local max', xy=(2, 1), xytext=(3, 1.5),
            arrowprops=dict(facecolor='black', shrink=0.05),
            )
ax.set_ylim(-2, 2)
plt.show()

to

import numpy as np
import matplotlib.pyplot as plt

# fig, ax = plt.subplots()  # remove this line

t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
line, = plt.plot(t, s, lw=2)

plt.annotate('local max', xy=(2, 1), xytext=(3, 1.5),
             arrowprops=dict(facecolor='black', shrink=0.05),
             )
plt.set_ylim(-2, 2)  # the only API change needed
plt.show()

@jklymak
Copy link
Member

jklymak commented Dec 15, 2019

The “set” prefix means you are settings a property to some value. Annotate is not a property it’s a new artist, therefore it doesn’t make sense to set it. You could argue that it should get a create_annotate or some such, but that grammar was not chosen a long time ago.

@github-actions
Copy link

github-actions bot commented Jul 3, 2023

This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!

@github-actions github-actions bot added the status: inactive Marked by the “Stale” Github Action label Jul 3, 2023
@tacaswell tacaswell added keep Items to be ignored by the “Stale” Github Action and removed status: inactive Marked by the “Stale” Github Action labels Jul 3, 2023
@tacaswell
Copy link
Member

This comes up in some form once a year or so.

My inclination is to close this with no action. From 2019 we have:

My pitch for evolving the pyplot (implicit) API towards the explicit API is #9111

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API: consistency keep Items to be ignored by the “Stale” Github Action topic: pyplot API
Projects
None yet
Development

No branches or pull requests

5 participants