-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
DOC: Tutorial on API shortcuts #30952
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
base: main
Are you sure you want to change the base?
Conversation
86f6b00 to
a02dbfb
Compare
6e76aa7 to
ed817a0
Compare
rcomer
left a comment
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.
Most of my thoughts were addressed as I kept reading 🙂
| # You can go even further by tapping into the pyplot logic and use `.pyplot.axes` to | ||
| # create the axes: | ||
|
|
||
| ax = plt.axes(xlabel="day", ylabel="daylight hours", title="London") |
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.
Is there a reason to use plt.axes here rather than plt.subplot? plt.subplot would seem more consistent with subplots/add_subplot in the rest of the tutorial.
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 is indeed a debatable aspect plt.axes() and plt.subplot() are equivalent.
I think the options are more or less:
flowchart LR
A["A: fig, ax = plt.subplots()"]
A --> B["B: ax = plt.figure().subplots()"]
A --> C["C: ax = plt.figure().add_subplot()"]
B --> D["D: ax = plt.axes()"]
C --> D
B --> E["E: ax = plt.subplot()"]
C --> E
I have chosen A -> C because that's what @anntzer uses and add_subplot() accept Axes properties as kwags, which subplots() does not. Ideally there would be plt.figure().add_axes() or plt.figure().axes() but we are not in that place right now and this PR is scoped to use existing API.
Favoring D over E is based on my dislike for subplot(). IMHO creating a single subplot at a time is awkward, because you have implicit state - a set subplot() calls is only meaningful if they are aligned. That doesn't matter for creating a single 111 subplot, but I don't want to advertise that function in general. Also, plt.subplots() / fig.subplots(), plt.subplot() look very much alike but they have subtly different semantics. YMMV, but I find somewhat more distinct names better in this case. I also like the similarity ax = plt.axes(). Eventually, plt.axes() is shorter than plt.subplot(); and brevity is the point of this tutorial 😄.
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.
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.
Plt.axes is pretty ambiguous as to whether it is treated as a subplot, and hence placed using subplot_params or not. I looked at the source and it is created with add_subplot (unless you use a four-tuple) so thats probably fine, but the ambiguity is a bit confusing.
On the other hand the number of times I've mistyped subplot when I meant subplots is an argument against subplot!
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.
Oh I see. Figure.add_axes requires at least one parameter so is not equivalent to plt.axes 👀😬
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.
Exactly, one could discuss whether supporting argument-less fig.add_axes() is reasonable, but that'd be a much heavier lift than describing existing API.
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.
Plt.axes is pretty ambiguous as to whether it is treated as a subplot, and hence placed using subplot_params or not. I looked at the source and it is created with add_subplot (unless you use a four-tuple) so thats probably fine, but the ambiguity is a bit confusing.
tl;dr: I consider this rather a feature because it creates less mental overhead for the average user
I consider this rather a feature. The distinction between Axes and Subplot is an unnecessary burden for the average Matplotlib user (#18222). To clarify for those who are not into the topic (not sure if this is 100% exact, but the definition is good enough for here): A Subplot is an Axes that is created based on a GridSpec, determing the rough part of the figure this is plotted into, and SubplotParams, determining borders and margins of the Axes grid.
In former times this difference was more visible through the Subplot class, which we luckily got rid of #23573. Unfortunately, the name subplot must be kept around because plt.subplots() is our most-prominent function. To alleviate this, I consider and teach subplot as in informal concept - i.e. multiple figures arranged in a grid - as in "the figure consists of two (sub)plots side-by-side". One subplot being the limiting case is a just plausible enough explanation for fig, ax = plt.subplots(). It's called "subplots" because it supports creating one or more Axes.
I'd argue that for creating a single full-figure Axes, the distinction between a 111 subplot and a manually places Axes is irrelevant for most users. The only difference is whether you can control its position via subplot_params. But most users won't do manual adjustment, and the need is thankfully significantly reduced through constrained_layout.
In that spirit:
plt.subplots()as the general solution is here to stay. We cannot do anything about it and justify it's naming because it can create multiple (sub)plots.fig.add_subplot()is the mildly odd one for creating just one full-sized Axes.fig.subplots()works, but I don't want to recommend it here because it cannot directly accept Axes properties (which is justified in that it creates both figure and Axes). I would use and argument-lessfig.add_axes()if that was there, but is not right now.plt.axes()is better thanplt.subplot(), because the informal subplot notion is awkward for one full-size (sub)plot.
Some of the arguments above are a bit of a stretch, but this is my best solution to tell a comprehensible story on a historically complex and at times suboptimal API.
I'd just name it shortcuts since that's what you named the PR and put the note about these being shorter calls in the preamble if it's not already there. |
What shortcuts exactly?
For now I stay with "Shorter call patterns", which seems the most understandable to me. |
eedfe13 to
2a9c9d4
Compare
|
"Coding shortcuts"? |
2a9c9d4 to
bec52d0
Compare
|
I like "Coding shortcuts". "Coding" has the right informal pragmatism that applies to this tutorial. |
Closes #30941.