From 106678e09109e89c8e17c6dea5d930be863314cd Mon Sep 17 00:00:00 2001 From: Ian Thomas Date: Mon, 29 Apr 2024 17:00:13 +0100 Subject: [PATCH] Update Matplotlib docs --- IPython/core/pylabtools.py | 6 ++- IPython/core/shellapp.py | 12 ++++-- docs/source/interactive/plotting.rst | 52 ++++++++++++++++--------- docs/source/interactive/reference.rst | 56 +++++++++------------------ docs/source/whatsnew/version8.rst | 2 +- 5 files changed, 65 insertions(+), 63 deletions(-) diff --git a/IPython/core/pylabtools.py b/IPython/core/pylabtools.py index 1f5a11f37e1..af0f8810a81 100644 --- a/IPython/core/pylabtools.py +++ b/IPython/core/pylabtools.py @@ -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 = { @@ -485,6 +485,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: diff --git a/IPython/core/shellapp.py b/IPython/core/shellapp.py index 99d1d8a9f44..3815a0ecb92 100644 --- a/IPython/core/shellapp.py +++ b/IPython/core/shellapp.py @@ -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: @@ -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 @@ -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( diff --git a/docs/source/interactive/plotting.rst b/docs/source/interactive/plotting.rst index f473bd00160..b854c2429a4 100644 --- a/docs/source/interactive/plotting.rst +++ b/docs/source/interactive/plotting.rst @@ -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 -------- @@ -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 `. This +may execute the ``%matplotlib`` :ref:`magic command `. 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 diff --git a/docs/source/interactive/reference.rst b/docs/source/interactive/reference.rst index b11097abed5..2d356059146 100644 --- a/docs/source/interactive/reference.rst +++ b/docs/source/interactive/reference.rst @@ -44,7 +44,7 @@ the command-line by passing the full class name and a corresponding value; type <...snip...> --matplotlib= (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...> @@ -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. @@ -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:: @@ -657,7 +657,7 @@ 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() @@ -665,7 +665,7 @@ 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. @@ -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` @@ -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: @@ -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: diff --git a/docs/source/whatsnew/version8.rst b/docs/source/whatsnew/version8.rst index 7c8495e24c6..f6e6798a6af 100644 --- a/docs/source/whatsnew/version8.rst +++ b/docs/source/whatsnew/version8.rst @@ -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: