Skip to content
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

Add matplotlib.backend entry points #549

Merged
merged 2 commits into from
Mar 12, 2024

Conversation

ianthomas23
Copy link
Member

This adds entry points to pyproject.toml for ipympl to register itself as a Matplotlib backend using the names "widget" and "ipympl". It is part of the planned transition of backend mapping from IPython to Matplotlib (matplotlib/matplotlib#27663 and ipython/ipython#14311).

I have bumped the package version as it will be used by Matplotlib to determine if a backward-compatible shim is required for this backend. I have also bumped some of the pre-commit hook versions which was required for flake to be happy on my dev machine.

@@ -540,7 +540,8 @@ def show(block=None):


def flush_figures():
if rcParams['backend'] == 'module://ipympl.backend_nbagg':
backend = matplotlib.get_backend()
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 is considered the correct way to determine the current Matplotlib backend, it just calls rcParams['backend'] internally.

@SylvainCorlay SylvainCorlay merged commit 25a8ba1 into matplotlib:main Mar 12, 2024
9 checks passed
@ianthomas23 ianthomas23 deleted the entry_points branch March 12, 2024 20:38
Carreau added a commit to ipython/ipython that referenced this pull request Apr 12, 2024
This is WIP to move IPython's backend mapping into Matplotlib and
extends it to allow backends to register themselves via [entry
points](https://setuptools.pypa.io/en/latest/userguide/entry_point.html#entry-points-for-plugins).
It is a coordinated effort across Matplotlib, IPython, matplotlib-inline
and ipympl. Closes #14311. Most of the work is in Matplotlib
(matplotlib/matplotlib#27948) but I will repeat the relevant points
here.

When using a Matplotlib magic command of the form `%matplotlib
something` the identification of the Matplotlib backend and GUI loop are
now performed in Matplotlib not IPython. This supports:

1. Matplotlib backends that IPython already supports such as `qtagg` and
`tkagg`.
2. Other built-in Matplotlib backends such as `qtcairo`.
3. Backends that use `module://something` syntax such as
`module://mplcairo.qt`.
4. Backends that self-register using entry points, currently `inline`
and `widget`/`ipympl`.

Implementation details:

1. The magic command is now explicitly `%matplotlib gui_or_backend`
rather than `%matplotlib gui`. This is already effectively the case as
e.g. `%matplotlib ipympl` is really a backend not GUI name. Within
Matplotlib the `gui_or_backend` is checked first to see if it is a GUI
name and then falls back to checking if it is a backend name.
2. If you select the `inline` backend the corresponding GUI is now
`None` not `inline`. All backends which do not have a GUI loop return
`None`, otherwise we have to keep explicit checks within IPython for
particular backends.
3. `backends` and `backend2gui` are now deprecated but are still
exposed, with a deprecation warning, if required. If using Matplotlib,
ipympl, etc releases that include the corresponding changes to this PR
then they are not needed as Matplotlib deals with it all. But for
backward compatibility they must still be available for a while along
with the remainder of the existing backend-handling code.
4. I haven't yet updated the documentation but we need to keep
information about valid GUI frameworks and I propose that we should
remove all lists of valid Matplotlib backends, replacing them with
instructions on how to obtain the current list (pointing to the
Matplotlib docs and using `%matplotlib --list`). If we keep any lists
then they will inevitably become out of date. This extends to the
`backend_keys` in IPython/core/shellapp.py.

Because the four related projects are loosely coupled without direct
dependencies on each other (except for `ipython` and
`matplotlib-inline`), backward compatibility requires all possible
combinations of projects before and after the new functionality (I will
call these "old" and "new" from now on) to continue to work. I have
tested these all locally, and the CI of this PR will test new IPython
against old Matplotlib for example, but I need to add one or more new
temporary CI runs to test new IPython against new Matplotlib etc. The
identification of new versus old depends on version checks on the other
libraries, so here is a table that I will update showing the current
status of progress in the 4 projects:

| Project | Relevant PRs | Possible release version |
| --- | --- | --- |
| matplotlib-inline | ipython/matplotlib-inline#34,
ipython/matplotlib-inline#35 | 0.1.7 |
| ipympl | matplotlib/ipympl#549 | 0.9.4 |
| Matplotlib | matplotlib/matplotlib#27948 | 3.9.1 |
| IPython | #14371 (this) | 8.24.0 |

The two widget projects can be released soon, once we are happy with the
entry point approach. The other two projects' PRs will have to be
synchronised as each includes version checks on each other.

To do

- [ ] Add CI runs against the new PR branches of the other projects.
- [ ] Add comments for conditions required for backward-compatibility
code blocks to be removed.
- [ ] Update documentation, including removal of lists of valid
backends.
- [ ] Update version checks before merging.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants