Skip to content

Removed idiomatic constructs from interactive figures docs #17471

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 6 commits into from
Jun 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions doc/devel/documenting_mpl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ it, use
.. code-block:: sh

make SPHINXOPTS= html

On Windows the arguments must be at the end of the statement:

.. code-block:: bat

make html SPHINXOPTS=

You can use the ``O`` variable to set additional options:

Expand All @@ -121,8 +127,12 @@ You can use the ``O`` variable to set additional options:
Multiple options can be combined using e.g. ``make O='-j4 -Dplot_gallery=0'
html``.

On Windows, options needs to be set as environment variables, e.g. ``set O=-W
--keep-going -j4 & make html``.
On Windows, either use the format shown above or set options as environment variables, e.g.:

.. code-block:: bat

set O=-W --keep-going -j4
make html

.. _writing-rest-pages:

Expand Down
161 changes: 76 additions & 85 deletions doc/users/interactive.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,21 @@
.. toctree::


When working with data it is often invaluable to be able to interact
with your plots. In many cases the built in pan/zoom and mouse-location
tools are sufficient, but you can also use the Matplotlib event system
to build customized data exploration tools.
When working with data, interactivity can be invaluable. The pan/zoom and
mouse-location tools built into the Matplotlib GUI windows are often sufficient, but
you can also use the event system to build customized data exploration tools.

Matplotlib ships with :ref:`backends <what-is-a-backend>` binding to
several GUI toolkits (Qt, Tk, Wx, GTK, macOS, JavaScript) and third party
packages provide bindings to `kivy
<https://github.com/kivy-garden/garden.matplotlib>`__ and `Jupyter Lab
<https://github.com/matplotlib/ipympl>`__. For the figures to be
"live" the GUI event loop will need to be integrated with your prompt. The
simplest way is to use IPython (see :ref:`below <ipython-pylab>`).
<https://github.com/matplotlib/ipympl>`__. For the figures to be responsive to
mouse, keyboard, and paint events, the GUI event loop needs to be integrated
with an interactive prompt. We recommend using IPython (see :ref:`below <ipython-pylab>`).

The `.pyplot` module provides functions for explicitly creating
Figures that include interactive tools, a toolbar, a tool-tip, and
:ref:`key bindings <key-event-handling>` ready to go:
The `.pyplot` module provides functions for explicitly creating figures
that include interactive tools, a toolbar, a tool-tip, and
:ref:`key bindings <key-event-handling>`:

`.pyplot.figure`
Creates a new empty `.figure.Figure` or selects an existing figure
Expand All @@ -36,13 +35,15 @@ Figures that include interactive tools, a toolbar, a tool-tip, and
through `.pyplot.gcf` and a notion of "The Current Axes" accessed
through `.pyplot.gca`. Almost all of the functions in `.pyplot` pass
through the current `.Figure` / `.axes.Axes` (or create one) as
appropriate. Matplotlib keeps a reference to all of the open figures
created this way so they will not be garbage collected. You can close
and deregister `.Figure`\s from `.pyplot` individually via
`.pyplot.close` or close all open figures via ``plt.close('all')``.
appropriate.

For discussion of how the integration of the event loops and Matplotlib's event
system work under the hood see:
Matplotlib keeps a reference to all of the open figures
created via `pyplot.figure` or `pyplot.subplots` so that the figures will not be garbage
collected. `.Figure`\s can be closed and deregistered from `.pyplot` individually via
`.pyplot.close`; all open `.Figure`\s can be closed via ``plt.close('all')``.


For more discussion of Matplotlib's event system and integrated event loops, please read:

.. toctree::
:maxdepth: 1
Expand All @@ -57,64 +58,58 @@ IPython integration
===================

We recommend using IPython for an interactive shell. In addition to
all of its features (improved tab-completion, magics,
multiline editing, etc), it also ensures that the GUI toolkit event
loop is properly integrated with the command line (see
:ref:`cp_integration`). To configure the integration and enable
:ref:`interactive mode <controlling-interactive>` use the
``%matplotlib`` magic
all of its features (improved tab-completion, magics, multiline editing, etc),
it also ensures that the GUI toolkit event loop is properly integrated
with the command line (see :ref:`cp_integration`).

In this example, we create and modify a figure via an IPython prompt.
The figure displays in a Qt5Agg GUI window. To configure the integration
and enable :ref:`interactive mode <controlling-interactive>` use the
``%matplotlib`` magic:

.. highlight:: ipython

::

user@machine:~ $ ipython
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 it is helpful to identify that we are in an IPython session, we should not assume that our readers well recognize the prompt as IPython from the style.

Copy link
Member Author

Choose a reason for hiding this comment

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

We say that it's IPython in the narrative, but I'm fine putting this line back in. I just don't want them getting tripped up on all the details of your particular Ipython install

Python 3.8.2 (default, Apr 8 2020, 14:31:25)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.13.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: %matplotlib
Using matplotlib backend: Qt5Agg

In [2]: import matplotlib.pyplot as plt

Calling
Create a new figure window:

::

In [3]: fig, ax = plt.subplots()

will pop open a window for you and

Add a line plot of the data to the window:

::

In [4]: ln, = ax.plot(range(5))

will show your data in the window. If you change something about the
line, for example the color
Change the color of the line from blue to orange:

::

In [5]: ln.set_color('orange')

it will be reflected immediately. If you wish to disable this behavior
use
If you wish to disable automatic redrawing of the plot:

::

In [6]: plt.ioff()

and
If you wish to re-enable automatic redrawing of the plot:

::

In [7]: plt.ion()

re-enable it.

With recent versions of ``Matplotlib`` and ``IPython`` it is
sufficient to import `matplotlib.pyplot` and call `.pyplot.ion`, but
using the magic is guaranteed to work regardless of versions.
In recent versions of ``Matplotlib`` and ``IPython``, it is
sufficient to import `matplotlib.pyplot` and call `.pyplot.ion`.
Using the ``%`` magic is guaranteed to work in all versions of Matplotlib and IPython.


.. highlight:: python
Expand Down Expand Up @@ -146,45 +141,43 @@ Interactive mode controls:

- whether created figures are automatically shown
- whether changes to artists automatically trigger re-drawing existing figures
- whether `.pyplot.show` returns immediately or after all of the
figures have been closed when given no arguments

- when `.pyplot.show()` returns if given no arguments: immediately, or after all of the figures have been closed

If in interactive mode, then:
If in interactive mode:

- newly created figures will be shown immediately
- figures will automatically redraw on change
- pyplot.show will return immediately by default
- newly created figures will be displayed immediately
- figures will automatically redraw when elements are changed
- `pyplot.show()` displays the figures and immediately returns

If not in interactive mode then:

- newly created figures and changes to figures will
not be reflected until explicitly asked to be
- pyplot.show runs the GUI event loop and does not return until all of
the plot windows are closed
If not in interactive mode:

- newly created figures and changes to figures are not displayed until
* `.pyplot.show()` is called
* `.pyplot.pause()` is called
* `.FigureCanvasBase.flush_events()` is called
- `pyplot.show()` runs the GUI event loop and does not return until all the plot windows are closed

If you are in non-interactive mode (or created figures while in
non-interactive mode) you may need to explicitly call `.pyplot.show`
to bring the windows onto your screen. If you only want to run the
GUI event loop for a fixed amount of time you can use `.pyplot.pause`.
This will both block the progress of your code (as if you had called
`time.sleep`), ensure the current window is shown and if needed
re-drawn, and run the GUI event loop (so the windows are "live" for
interaction) for the specified period of time.

Being in "interactive mode" is orthogonal to the GUI event loop being
integrated with your command prompt. If you use `pyplot.ion`, but
have not arranged for the event loop integration, your figures will
appear but will not be "live" while the prompt is waiting for input.
to display the windows on your screen. If you only want to run the
GUI event loop for a fixed amount of time, you can use `.pyplot.pause`.
This will block the progress of your code as if you had called
`time.sleep`, ensure the current window is shown and re-drawn if needed,
and run the GUI event loop for the specified period of time.

The GUI event loop being integrated with your command prompt and
the figures being in interactive mode are independent of each other.
If you use `pyplot.ion` but have not arranged for the event loop integration,
your figures will appear but will not be interactive while the prompt is waiting for input.
You will not be able to pan/zoom and the figure may not even render
(the window might appear black, transparent, or as a snapshot of the
desktop under it). Conversely, if you configure the event loop
integration, displayed figures will be "live" while waiting for input
at the prompt, regardless of pyplot's "interactive mode". In either
case, the figures will be "live" if you use
``pyplot.show(block=True)``, `.pyplot.pause`, or run the the GUI main
loop in some other way.
integration, displayed figures will be responsive while waiting for input
at the prompt, regardless of pyplot's "interactive mode".

No matter what combination of interactive mode setting and event loop integration,
figures will be responsive if you use ``pyplot.show(block=True)``, `.pyplot.pause`, or run
the GUI main loop in some other way.


.. warning::
Expand All @@ -201,7 +194,7 @@ Default UI


The windows created by :mod:`~.pyplot` have an interactive toolbar with navigation
buttons and a readout of where the cursor is in dataspace. A number of
buttons and a readout of the data values the cursor is pointing at. A number of
helpful keybindings are registered by default.


Expand Down Expand Up @@ -240,8 +233,7 @@ Preserve aspect ratio hold **CONTROL** when panning/zooming with mo
Other Python prompts
====================

If you can not or do not want to use IPython, interactive mode works
in the vanilla python prompt
Interactive mode works in the default Python prompt:


.. sourcecode:: pycon
Expand All @@ -265,11 +257,11 @@ Jupyter Notebooks / Lab
using an interactive backend. The default backend in notebooks,
the inline backend, is not. `~ipykernel.pylab.backend_inline`
renders the figure once and inserts a static image into the
notebook when the cell is executed. The images are static and can
not be panned / zoomed, take user input, or be updated from other
notebook when the cell is executed. Because the images are static, they
can not be panned / zoomed, take user input, or be updated from other
cells.

To get interactive figures in the 'classic' notebook or jupyter lab
To get interactive figures in the 'classic' notebook or Jupyter lab,
use the `ipympl <https://github.com/matplotlib/ipympl>`__ backend
(must be installed separately) which uses the **ipywidget** framework.
If ``ipympl`` is installed use the magic:
Expand All @@ -280,25 +272,24 @@ If ``ipympl`` is installed use the magic:

to select and enable it.

If you only need to use the classic notebook you can use
If you only need to use the classic notebook, you can use

.. sourcecode:: ipython

%matplotlib notebook

which uses the `.backend_nbagg` backend which ships with Matplotlib.
However nbagg does not work in Jupyter Lab.
which uses the `.backend_nbagg` backend provided by Matplotlib;
however, nbagg does not work in Jupyter Lab.

GUIs + jupyter
GUIs + Jupyter
~~~~~~~~~~~~~~

If you are running your jupyter kernel locally you can use one of the
GUI backends. The process running your kernel will show a GUI window
on your desktop adjacent to your web browser. However if you move
that notebook to a remote server the kernel will try to open the GUI
window on *that* computer. Unless you have arranged to forward the
xserver back to your desktop, you not be able to see or interact with
the figure (if it does not raise an exception outright).
You can also use one of the non-``ipympl`` GUI backends in a Jupyter Notebook.
If you are running your Jupyter kernel locally, the GUI window will spawn on
your desktop adjacent to your web browser. If you run your notebook on a remote server,
the kernel will try to open the GUI window on the remote computer. Unless you have
arranged to forward the xserver back to your desktop, you will not be able to
see or interact with the window. It may also raise an exception.



Expand Down