Skip to content

Commit

Permalink
Update Matplotlib docs (#14425)
Browse files Browse the repository at this point in the history
This updates the docs in line with the recent changes to move Matplotlib
backend resolution to Matplotlib itself. In passing I have removed
references to things that have definitely disappeared from Matplotlib
(such as `qt4`), and I've added a comment about when
`_matplotlib_manages_backends()` can be removed in future.

This, along with #14420, should conclude the backend transition.
  • Loading branch information
Carreau committed May 7, 2024
2 parents e96ec57 + 106678e commit 4bc1baa
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 63 deletions.
6 changes: 5 additions & 1 deletion IPython/core/pylabtools.py
Expand Up @@ -14,7 +14,7 @@


# Matplotlib backend resolution functionality moved from IPython to Matplotlib
# in IPython 8.24 and Matplotlib 3.9.1. Need to keep `backends` and `backend2gui`
# in IPython 8.24 and Matplotlib 3.9.0. Need to keep `backends` and `backend2gui`
# here for earlier Matplotlib and for external backend libraries such as
# mplcairo that might rely upon it.
_deprecated_backends = {
Expand Down Expand Up @@ -487,6 +487,10 @@ def _matplotlib_manages_backends() -> bool:
matplotlib.backends.registry.backend_registry is available along with
member functions resolve_gui_or_backend, resolve_backend, list_all, and
list_gui_frameworks.
This function can be removed as it will always return True when Python
3.12, the latest version supported by Matplotlib < 3.9, reaches
end-of-life in late 2028.
"""
global _matplotlib_manages_backends_value
if _matplotlib_manages_backends_value is None:
Expand Down
12 changes: 8 additions & 4 deletions IPython/core/shellapp.py
Expand Up @@ -82,12 +82,14 @@
shell_flags['pylab'] = (
{'InteractiveShellApp' : {'pylab' : 'auto'}},
"""Pre-load matplotlib and numpy for interactive use with
the default matplotlib backend."""
the default matplotlib backend. The exact options available
depend on what Matplotlib provides at runtime.""",
)
shell_flags['matplotlib'] = (
{'InteractiveShellApp' : {'matplotlib' : 'auto'}},
"""Configure matplotlib for interactive use with
the default matplotlib backend."""
the default matplotlib backend. The exact options available
depend on what Matplotlib provides at runtime.""",
)

# it's possible we don't want short aliases for *all* of these:
Expand All @@ -114,7 +116,7 @@
class MatplotlibBackendCaselessStrEnum(CaselessStrEnum):
"""An enum of Matplotlib backend strings where the case should be ignored.
Prior to Matplotlib 3.9.1 the list of valid backends is hardcoded in
Prior to Matplotlib 3.9.0 the list of valid backends is hardcoded in
pylabtools.backends. After that, Matplotlib manages backends.
The list of valid backends is determined when it is first needed to avoid
Expand Down Expand Up @@ -205,12 +207,14 @@ class InteractiveShellApp(Configurable):
matplotlib = MatplotlibBackendCaselessStrEnum(
allow_none=True,
help="""Configure matplotlib for interactive use with
the default matplotlib backend.""",
the default matplotlib backend. The exact options available
depend on what Matplotlib provides at runtime.""",
).tag(config=True)
pylab = MatplotlibBackendCaselessStrEnum(
allow_none=True,
help="""Pre-load matplotlib and numpy for interactive use,
selecting a particular matplotlib backend and loop integration.
The exact options available depend on what Matplotlib provides at runtime.
""",
).tag(config=True)
pylab_import_all = Bool(
Expand Down
52 changes: 33 additions & 19 deletions docs/source/interactive/plotting.rst
Expand Up @@ -16,6 +16,8 @@ difference as object are most of the time represented by text, but in notebook
and similar interface you will get richer outputs.


.. _matplotlib_magic:

Plotting
--------

Expand All @@ -27,41 +29,53 @@ Plotting
advantages of working outside of IPython as well.


One major feature of the IPython kernel is the ability to display plots that
are the output of running code cells. The IPython kernel is designed to work
One major feature of the IPython kernel is the ability to display plots that
are the output of running code cells. The IPython kernel is designed to work
seamlessly with the matplotlib_ plotting library to provide this functionality.

To set this up, before any plotting or import of matplotlib is performed you
must execute the ``%matplotlib`` :ref:`magic command <magics_explained>`. This
may execute the ``%matplotlib`` :ref:`magic command <magics_explained>`. This
performs the necessary behind-the-scenes setup for IPython to work correctly
hand in hand with ``matplotlib``; it does *not*, however, actually execute any
Python ``import`` commands, that is, no names are added to the namespace.

If the ``%matplotlib`` magic is called without an argument, the
output of a plotting command is displayed using the default ``matplotlib``
backend in a separate window. Alternatively, the backend can be explicitly
requested using, for example::
If you do not use the ``%matplotlib`` magic or you call it without an argument,
the output of a plotting command is displayed using the default ``matplotlib``
backend, which may be different depending on Operating System and whether
running within Jupyter or not.

Alternatively, the backend can be explicitly requested using, for example::

%matplotlib gtk

A particularly interesting backend, provided by IPython, is the ``inline``
backend. This is available only for the Jupyter Notebook and the
Jupyter QtConsole. It can be invoked as follows::
The argument passed to the ``%matplotlib`` magic command may be the name of any
backend understood by ``matplotlib`` or it may the name of a GUI loop such as
``qt`` or ``osx``, in which case an appropriate backend supporting that GUI
loop will be selected. To obtain a full list of all backends and GUI loops
understood by ``matplotlib`` use ``%matplotlib --list``.

%matplotlib inline
There are some specific backends that are used in the Jupyter ecosystem:

With this backend, the output of plotting commands is displayed *inline* within
frontends like the Jupyter notebook, directly below the code cell that produced
it. The resulting plots will then also be stored in the notebook document.
- The ``inline`` backend is provided by IPython and can be used in Jupyter Lab,
Notebook and QtConsole; it is the default backend when using Jupyter. The
outputs of plotting commands are displayed *inline* within frontends like
Jupyter Notebook, directly below the code cells that produced them.
The resulting plots will then also be stored in the notebook document.

.. seealso::
- The ``notebook`` or ``nbagg`` backend is built into ``matplotlib`` and can be
used with Jupyter ``notebook <7`` and ``nbclassic``. Plots are interactive so
they can be zoomed and panned.

`Plotting with Matplotlib`_ example notebook
- The ``ipympl`` or ``widget`` backend is for use with Jupyter ``lab`` and
``notebook >=7``. It is in a separate ``ipympl`` module that must be
installed using ``pip`` or ``conda`` in the usual manner. Plots are
interactive so they can be zoomed and panned.

.. seealso::

The matplotlib_ library also ships with ``%matplotlib notebook`` command that
allows interactive figures if your environment allows it.
`Plotting with Matplotlib`_ example notebook

See the matplotlib_ documentation for more information.
See the matplotlib_ documentation for more information, in particular the
section on backends.

.. include:: ../links.txt
56 changes: 18 additions & 38 deletions docs/source/interactive/reference.rst
Expand Up @@ -44,7 +44,7 @@ the command-line by passing the full class name and a corresponding value; type
<...snip...>
--matplotlib=<CaselessStrEnum> (InteractiveShellApp.matplotlib)
Default: None
Choices: ['auto', 'gtk', 'gtk3', 'gtk4', 'inline', 'nbagg', 'notebook', 'osx', 'qt', 'qt5', 'qt6', 'tk', 'wx']
Choices: ['auto', 'gtk3', 'gtk4', 'inline', 'nbagg', 'notebook', 'osx', 'qt', 'qt5', 'qt6', 'tk', 'wx']
Configure matplotlib for interactive use with the default matplotlib
backend.
<...snip...>
Expand Down Expand Up @@ -623,11 +623,11 @@ code snippet::
a = 42
IPython.embed()

and within the IPython shell, you reassign `a` to `23` to do further testing of
and within the IPython shell, you reassign `a` to `23` to do further testing of
some sort, you can then exit::

>>> IPython.embed()
Python 3.6.2 (default, Jul 17 2017, 16:44:45)
Python 3.6.2 (default, Jul 17 2017, 16:44:45)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.2.0.dev -- An enhanced Interactive Python. Type '?' for help.

Expand All @@ -641,9 +641,9 @@ Once you exit and print `a`, the value 23 will be shown::
In: print(a)
23

It's important to note that the code run in the embedded IPython shell will
*not* change the state of your code and variables, **unless** the shell is
contained within the global namespace. In the above example, `a` is changed
It's important to note that the code run in the embedded IPython shell will
*not* change the state of your code and variables, **unless** the shell is
contained within the global namespace. In the above example, `a` is changed
because this is true.

To further exemplify this, consider the following example::
Expand All @@ -657,15 +657,15 @@ To further exemplify this, consider the following example::

Now if call the function and complete the state changes as we did above, the
value `42` will be printed. Again, this is because it's not in the global
namespace::
namespace::

do()

Running a file with the above code can lead to the following session::

>>> do()
42
Python 3.6.2 (default, Jul 17 2017, 16:44:45)
Python 3.6.2 (default, Jul 17 2017, 16:44:45)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.2.0.dev -- An enhanced Interactive Python. Type '?' for help.

Expand Down Expand Up @@ -902,7 +902,7 @@ For users, enabling GUI event loop integration is simple. You simple use the
%gui [GUINAME]

With no arguments, ``%gui`` removes all GUI support. Valid ``GUINAME``
arguments include ``wx``, ``qt``, ``qt5``, ``qt6``, ``gtk``, ``gtk3`` ``gtk4``, and
arguments include ``wx``, ``qt``, ``qt5``, ``qt6``, ``gtk3`` ``gtk4``, and
``tk``.

Thus, to use wxPython interactively and create a running :class:`wx.App`
Expand Down Expand Up @@ -937,29 +937,12 @@ PyQt and PySide
When you use ``--gui=qt`` or ``--matplotlib=qt``, IPython can work with either
PyQt or PySide. ``qt`` implies "use the latest version available", and it favors
PyQt over PySide. To request a specific version, use ``qt5`` or ``qt6``. Note that
Qt4 is not supported with the ``--gui`` switch (and has not been for some time now).
PyQt over PySide. To request a specific version, use ``qt5`` or ``qt6``.

If specified, IPython will respect the environment variable ``QT_API`` used
by ETS. ETS 4.0 also works with both PyQt4 and PySide, but it requires
PyQt4 to use its v2 API. So if ``QT_API=pyside`` PySide will be used,
and if ``QT_API=pyqt`` then PyQt4 will be used *with the v2 API* for
QString and QVariant, so ETS codes like MayaVi will also work with IPython.

If you launch IPython in matplotlib mode with ``ipython --matplotlib=qt``,
then IPython will ask matplotlib which Qt library to use (only if QT_API is
*not set*), via the 'backend.qt4' rcParam. If matplotlib is version 1.0.1 or
older, then IPython will always use PyQt4 without setting the v2 APIs, since
neither v2 PyQt nor PySide work.

.. warning::

Note that this means for ETS 4 to work with PyQt4, ``QT_API`` *must* be set
to work with IPython's qt integration, because otherwise PyQt4 will be
loaded in an incompatible mode.

It also means that you must *not* have ``QT_API`` set if you want to
use ``--gui=qt`` with code that requires PyQt4 API v1.
If specified, IPython will respect the environment variable ``QT_API``. If
``QT_API`` is not specified and you launch IPython in matplotlib mode with
``ipython --matplotlib=qt`` then IPython will ask matplotlib which Qt library
to use. See the matplotlib_ documentation on ``QT_API`` for further details.


.. _matplotlib_support:
Expand All @@ -969,19 +952,16 @@ Plotting with matplotlib

matplotlib_ provides high quality 2D and 3D plotting for Python. matplotlib_
can produce plots on screen using a variety of GUI toolkits, including Tk,
PyGTK, PyQt4 and wxPython. It also provides a number of commands useful for
PyGTK, PyQt6 and wxPython. It also provides a number of commands useful for
scientific computing, all with a syntax compatible with that of the popular
Matlab program.

To start IPython with matplotlib support, use the ``--matplotlib`` switch. If
IPython is already running, you can run the :magic:`matplotlib` magic. If no
arguments are given, IPython will automatically detect your choice of
matplotlib backend. You can also request a specific backend with
``%matplotlib backend``, where ``backend`` must be one of: 'tk', 'qt', 'wx',
'gtk', 'osx'. In the web notebook and Qt console, 'inline' is also a valid
backend value, which produces static figures inlined inside the application
window instead of matplotlib's interactive figures that live in separate
windows.
matplotlib backend. For information on matplotlib backends see
:ref:`matplotlib_magic`.


.. _interactive_demos:

Expand Down
2 changes: 1 addition & 1 deletion docs/source/whatsnew/version8.rst
Expand Up @@ -10,7 +10,7 @@ IPython 8.24
Back on regular release schedule, as usual month releases are relatively tiny.

The biggest change is the move of the matplotlib backend handling from IPython
to matplotlib. :ghpull:`14371`:ghpull:`14403`.
to matplotlib. :ghpull:`14371` :ghpull:`14403`.

We will note:

Expand Down

0 comments on commit 4bc1baa

Please sign in to comment.