-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
DOC: figure explanation #24999
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
DOC: figure explanation #24999
Conversation
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.
Good idea! (I shouldn't say that I have detailed knowledge of the available documents, but this one is good and I trust you in that others are missing.)
Some minor comments for what it is worth.
66cc840
to
ced790c
Compare
doc/users/explain/figures.rst
Outdated
for ax_name in axs: | ||
axs[ax_name].text(0.5, 0.5, ax_name, ha='center', va='center') | ||
|
||
We can also have subfigures inside figures (or other subfigures; |
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 this might be a good place to restate the conceptual difference between a figure and an axes to help folks sort if they want to add more subplots to a figure or create a subfigure w/ a batch of subplots
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.
Added an example, which if we are going into why to use subfigures, seems the easiest way to explain it.
doc/users/explain/figures.rst
Outdated
There are a few options available when creating figures. The Figure size on | ||
the screen is set by *figsize* and *dpi*. *figsize* is the ``(width, height)`` | ||
of the Figure in inches (or, if prefered, units of 72 typographic points). *dpi* | ||
are how many pixels per inch the figure will be rendered at. To make you Figures |
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.
are how many pixels per inch the figure will be rendered at. To make you Figures | |
To make you Figures |
I think something got garbled here
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 an explanation as to what dpi means.
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 sorry didn't mean to delete, just meant to flag that "to make you figures" was probably a misprint
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.
Yep caught that one I think
af481d9
to
9f10385
Compare
This need not hold up 3.7, but could be easily backported.... |
doc/users/explain/figures.rst
Outdated
:doc:`pyplot </tutorials/introductory/pyplot>` interface. As noted in | ||
:ref:`api_interfaces`, the pyplot interface serves two purposes. One is to spin | ||
up the Backend and keep track of GUI windows. The other is a global state for | ||
Axes and Artists that allow a short form API to plotting methods. In the |
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 this is misleading, the tracking is automatic and can not be opted out of.
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.
It can be opted out of when you don't use pyplot, can't it? I'm not quite following your concern here.
Added some picky comments, but overall 👍! |
9f10385
to
c2ffe02
Compare
================================================ | ||
Creating, viewing, and saving Matplotlib Figures | ||
================================================ | ||
|
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.
We should define what a figure is. Maybe something like
In matplotlib, a
~.Figure
is the logical container for all visual elements. Think of it like a blank sheet of paper.
To add content, you'll add visual elements (called.Artist
\s) to the figure though specific functions.
This is somewhat informal, but should give a rough mental model.
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 thats what the first two sentences below the example were meant to do?
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.
When looking at Matplotlib visualization, you are almost always looking at
Artists placed on a~.Figure
.
Has too little emphasis on Figure. Matplotlib visualization and Artists are mentioned first and are the syntactic objects in the sentence. Figure is only mentioned as the context of Artists. I would like a sentence that has Figure as the subject, like "A Figure is...". Also, I think this should come before any plot to set the scope/expectation. The plot code already has a lot of details and the user does not know what the relevance of the plot/shown code is.
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.
As below, readers are unlikely to hit this page with no context. They will have seen matplotlib visualizations, even if only on the landing page. And the title clearly indicates that this is about Figures. We need to put a figure in context of what they have seen before so I prefer to mention that first.
doc/users/explain/figures.rst
Outdated
fig = plt.figure(figsize=(2, 2), facecolor='0.8', layout='constrained') | ||
ax = fig.add_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.
Maybe add first
fig = plt.figure(figsize=(2, 2), facecolor='0.8')
fig.text(0.1, 0.5, "This is a figure")
to illustrate the basic conecpt of adding content with out the need to already dive into the Axes
/ subplot complexity.
And then follow up with the Axes discussion.
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'm not in favour of adding a relatively obscure artist to the first example - an Axes is what 99.99% of visualizations start with. I personally wasn't even aware that Figure has a text method, so it's pretty obscure.
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.
Though this inspires a new section below on adding artists....
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'm trying to make a minimal illustration of a figure. Maybe even
plt.figure(facecolor='lightblue')
is enough.
Side-remark: Please don't use the somewhat obscure '0.8' greyscale notation in a basic example. That is unnecessarily confusing.
If the empty figure is too little, you could use suptitle()
, which is simpler than text()
:
plt.figure(facecolor='lightblue')
plt.suptitle('This is a figure')
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 want a minimal typical example of a figure in the context of what the reader has likely seen before, not an artificial example with nothing on it. Readers are not starting with zero context here.
I can easily change the background colour.
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.
Updated to change the color and added some annotation on the 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.
I want a minimal typical example of a figure in the context of what the reader has likely seen before, not an artificial example with nothing on it.
I would agree for a tutorial. In explanations however, I think we should clearly isolate the figure. Both visually, and from the code complexity
fig = plt.figure(facecolor='lightblue')
fig.suptitle('This is a figure')
is much clearer than
fig = plt.figure(figsize=(2, 2), facecolor='lightskyblue',
layout='constrained')
fig.suptitle('Figure')
ax = fig.add_subplot()
ax.set_title('Axes', loc='left', fontstyle='oblique', fontsize='medium')
Readers are not starting with zero context here.
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.
Again, I think this initial example is more effective in the context of something the viewer would have seen - 99.9999% of figures have an Axes. The complexity is all in separating the two objects in code so that the reader can understand how Matplotlib differentiates them internally. I don't feel that an empty figure is a good use of space or the reader's time.
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 beg to differ.
in the context of something the viewer would have seen - 99.9999% of figures have an Axes.
Note also that plt.figure(); fig.add_subplot()
is rarely used (plt.subplots()
being far more common and IMHO recommended). There is value in using the figure() call here explicitly and I'm not suggesting to change, but this fact weakens the familiarity argument. The generated figure is familiar, but the associated code is not.
I have the feeling that the current approach is neither fish nor fowl. Maybe, if you wan't to start with the familiar, really do subplots() and then explain that this does the two statements under the hood.
I really appreciate your work on the docs, and I'd like to make sure they are of maximal use for a diverse audience. I would like to encourage to carefully consider how the descriptions work for users with different backgrounds. We as authors have a very good understanding, but throwing in variations (add_subplot vs subplots) or concepts (In the text Artists are mentioned without explanation or a link for context) can be obstacles for some readers.
Unfortunately, I don't have much time currently. So I will withdraw from the PR and the discussion.
doc/users/explain/figures.rst
Outdated
Axes and Artists that allow a short-form API to plotting methods. In the | ||
example above, we only use pyplot for the first purpose, to create the Figure | ||
object, ``fig``. |
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.
Continuing the discussion from #24999 (comment)
we only use pyplot for the first purpose, ...
That reads to me like "In the above example we are not adding the figures to the global registry". Maybe something like:
Axes and Artists that allow a short-form API to plotting methods. In the | |
example above, we only use pyplot for the first purpose, to create the Figure | |
object, ``fig``. | |
Axes and Artists that allow a short-form API to plotting methods. In the | |
example above, we only want the first purpose, to create the Figure | |
object, ``fig``, but it is still added to the global registry to support the | |
second. |
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.
OK, I understand now. If we digress like this, I made it a bit more wordy:
By far the most common way to create a figure is using the
:doc:`pyplot </tutorials/introductory/pyplot>` interface. As noted in
:ref:`api_interfaces`, the pyplot interface serves two purposes. One is to spin
up the Backend and keep track of GUI windows. The other is a global state for
Axes and Artists that allow a short-form API to plotting methods. In the
example above, we use pyplot for the first purpose, and create the Figure object,
``fig``. As a side effect ``fig`` is also added to pyplot's global state, and
can be accessed via `~.pyplot.gcf`.
a9307df
to
f9ecd2f
Compare
doc/users/explain/figures.rst
Outdated
the most common use is ``bbox_inches='tight'``. This option trims, or expands, the | ||
size of the figure so that it is tight around all the artists in a figure, with a |
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.
Super picky word choice preference, feel free to disregard:
the most common use is ``bbox_inches='tight'``. This option trims, or expands, the | |
size of the figure so that it is tight around all the artists in a figure, with a | |
the most common use is ``bbox_inches='tight'``. This option "shrink wraps, | |
trimming or expanding as needed, the size of the figure so that it is tight | |
around all the artists in a figure, with a |
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'm more than happy for this to go in as-is and iterate from there. While I think all of this information is available someplace in our docs, having it all in one place like this is major improvement.
84b6780
to
3860600
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.
I spotted a couple of typos. I also learned a few things so thanks for doing this.
doc/users/explain/figures.rst
Outdated
by default trim or expand the figure size to have a tight box around Artists | ||
added to the Figure (see :ref:`saving_figures`, below). | ||
|
||
Standalone scripts and interctive use |
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.
Standalone scripts and interctive use | |
Standalone scripts and interactive use |
doc/users/explain/figures.rst
Outdated
a new GUI window, and usually will have a toolbar with Zoom, Pan, and other tools | ||
for interacting with the Figure. By default, ``plt.show()`` blocks | ||
further interaction from the script or shell until the Figure window is closed, | ||
though that can be toggled off for some pusposes. For more details, please see |
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.
though that can be toggled off for some pusposes. For more details, please see | |
though that can be toggled off for some purposes. For more details, please see |
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.
Thanks, for some reason I had my spellchecker off, but now its on again ;-)
3860600
to
85752da
Compare
85752da
to
13d170f
Compare
…999-on-v3.7.x Backport PR #24999 on branch v3.7.x (DOC: figure explanation)
PR Summary
New short intro on Figures in Matplotlib. I don't think this info exists except in snippets of the getting-stated guide. Could use some more cross-references.
PR Checklist
Documentation and Tests
pytest
passes)Release Notes
.. versionadded::
directive in the docstring and documented indoc/users/next_whats_new/
.. versionchanged::
directive in the docstring and documented indoc/api/next_api_changes/
next_whats_new/README.rst
ornext_api_changes/README.rst