Thanks to visit codestin.com
Credit goes to github.com

Skip to content

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

Merged
merged 1 commit into from
Jan 23, 2023
Merged

Conversation

jklymak
Copy link
Member

@jklymak jklymak commented Jan 16, 2023

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

  • Has pytest style unit tests (and pytest passes)
  • Documentation is sphinx and numpydoc compliant (the docs should build without error).
  • New plotting related features are documented with examples.

Release Notes

  • New features are marked with a .. versionadded:: directive in the docstring and documented in doc/users/next_whats_new/
  • API changes are marked with a .. versionchanged:: directive in the docstring and documented in doc/api/next_api_changes/
  • Release notes conform with instructions in next_whats_new/README.rst or next_api_changes/README.rst

Copy link
Member

@oscargus oscargus left a 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.

@jklymak jklymak force-pushed the doc-figure-explanation branch 3 times, most recently from 66cc840 to ced790c Compare January 16, 2023 16:08
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;
Copy link
Member

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

Copy link
Member Author

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.

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
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
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

Copy link
Member Author

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.

Copy link
Member

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

Copy link
Member Author

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

@jklymak jklymak force-pushed the doc-figure-explanation branch 2 times, most recently from af481d9 to 9f10385 Compare January 16, 2023 23:54
@jklymak jklymak added this to the v3.7.0 milestone Jan 17, 2023
@jklymak
Copy link
Member Author

jklymak commented Jan 17, 2023

This need not hold up 3.7, but could be easily backported....

: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
Copy link
Member

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.

Copy link
Member Author

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.

@tacaswell
Copy link
Member

Added some picky comments, but overall 👍!

@jklymak jklymak force-pushed the doc-figure-explanation branch from 9f10385 to c2ffe02 Compare January 17, 2023 21:46
================================================
Creating, viewing, and saving Matplotlib Figures
================================================

Copy link
Member

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.

Copy link
Member Author

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?

Copy link
Member

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.

Copy link
Member Author

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.

Comment on lines 11 to 14
fig = plt.figure(figsize=(2, 2), facecolor='0.8', layout='constrained')
ax = fig.add_subplot()
Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member Author

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....

Copy link
Member

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')

Copy link
Member Author

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.

Copy link
Member Author

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.

Copy link
Member

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')

grafik

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')

grafik

Readers are not starting with zero context here.

Copy link
Member Author

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.

Copy link
Member

@timhoffm timhoffm Jan 23, 2023

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.

Comment on lines 72 to 74
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``.
Copy link
Member

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:

Suggested change
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.

Copy link
Member Author

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`.

@jklymak jklymak force-pushed the doc-figure-explanation branch from a9307df to f9ecd2f Compare January 18, 2023 17:19
Comment on lines 190 to 191
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
Copy link
Member

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:

Suggested change
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

Copy link
Member

@tacaswell tacaswell left a 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.

@jklymak jklymak force-pushed the doc-figure-explanation branch 5 times, most recently from 84b6780 to 3860600 Compare January 19, 2023 15:23
Copy link
Member

@rcomer rcomer left a 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.

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
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Standalone scripts and interctive use
Standalone scripts and interactive use

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
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
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

Copy link
Member Author

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 ;-)

@jklymak jklymak force-pushed the doc-figure-explanation branch from 3860600 to 85752da Compare January 23, 2023 05:58
@jklymak jklymak force-pushed the doc-figure-explanation branch from 85752da to 13d170f Compare January 23, 2023 17:37
@ksunden ksunden merged commit f9de9a3 into matplotlib:main Jan 23, 2023
meeseeksmachine pushed a commit to meeseeksmachine/matplotlib that referenced this pull request Jan 23, 2023
QuLogic added a commit that referenced this pull request Jan 24, 2023
…999-on-v3.7.x

Backport PR #24999 on branch v3.7.x (DOC: figure explanation)
@ksunden ksunden mentioned this pull request Feb 20, 2023
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants