Open-source project
matplotlib/ipympl avatar
matplotlib/ipympl

ipympl for Interactive Matplotlib Figures in Jupyter

Matplotlib Jupyter Integration

1,661 stars235 forksJupyter NotebookBSD-3-Clause

At a glance

What is it?
ipympl connects Matplotlib's interactive backend to the Jupyter widget system, allowing figures to respond to events and participate in widget layouts. It is a practical choice for notebook-based plotting when the standard Matplotlib interface is insufficient.
Who is it for?
Adopt ipympl when a notebook needs an interactive Matplotlib canvas that can be composed with other Jupyter widgets. Do not choose it merely for static plots, or for notebook servers whose installed Matplotlib and JupyterLab versions do not match the compatibility table.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 84 days ago.
What is it written in?
Mainly Jupyter Notebook, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The notebook gap ipympl fills

Matplotlib normally produces figures, but the interaction available in a notebook depends on the backend in use. ipympl addresses the case where a notebook author needs more than a static image and the basic controls exposed by the ordinary notebook interface. The project enables Matplotlib's interactive features in Jupyter Notebook and JupyterLab through the Jupyter interactive widgets framework.

The intended users are Python developers, scientists, and researchers who build notebook workflows in which plots need to be inspected or manipulated during execution. A figure can become part of a wider interface that also contains Jupyter widgets. That matters when a plot is one component of an analysis tool rather than the final output of a cell.

The project does not replace Matplotlib. It supplies a Matplotlib backend and frontend integration, so existing plotting code remains Matplotlib code. Its scope is notebook execution. It is not a general-purpose GUI toolkit, and the README does not describe a deployment model for building a standalone desktop application around the figure.

How the ipympl backend becomes a widget

The repository contains Python code under `ipympl/`, TypeScript source under `src/`, and build configuration for Jupyter extensions. The package metadata identifies the Python distribution as `ipympl` and the JavaScript package as `jupyter-matplotlib`. The JavaScript package describes itself as a Matplotlib Jupyter interactive widget, while its published files include compiled library code, distribution bundles, and CSS.

The documented activation step is a Matplotlib Jupyter magic:

python
%matplotlib ipympl

After that selection, the notebook uses ipympl instead of the default Matplotlib notebook backend. The README states that the figure `canvas` element is a proper Jupyter interactive widget and can be positioned in interactive widget layouts. In practical terms, the important boundary is between Matplotlib's figure state and the widget layer. Matplotlib handles drawing and interaction events, while the Jupyter widget layer makes the canvas available to the notebook's widget model and layout system.

The source tree also shows separate concerns for Python and the browser side. Python files sit in `ipympl/`, while `src/`, `webpack.config.js`, `tsconfig.json`, and package scripts define the JavaScript and extension build. That separation explains why installation is not only a Python package operation for older JupyterLab environments.

Installing ipympl and selecting the backend

For a normal installation, the README gives both pip and conda commands. Choose the package manager that matches the environment rather than installing both. The pip command installs the Python distribution:

bash
pip install ipympl

The README also documents a conda installation:

bash
conda install -c conda-forge ipympl

After installation, start or open a Jupyter environment and select the backend in a notebook cell:

python
%matplotlib ipympl

The reader should see the backend selection take effect for subsequent plotting cells. The README does not include a minimal `plot()` example, so there is no project-specific output to quote here. The repository does document a full example notebook and hosted examples through Notebook.link and MyBinder. Those are useful references for observing widget interaction, but a hosted notebook is not a substitute for checking compatibility in the reader's own environment.

JupyterLab 3 is the stated recommendation. For JupyterLab 2, the README gives a manual extension installation path, which is a different setup from simply installing the Python package. This distinction matters because package installation alone may not install every frontend asset required by an older JupyterLab release.

JupyterLab compatibility and version pairing

ipympl has a second package identity that matters during installation. The Python package is `ipympl`, while the frontend package is `jupyter-matplotlib`. The README says that JupyterLab 1 and 2 users must install the right `jupyter-matplotlib` version for the installed `ipympl` and JupyterLab versions. The old-extension instructions show how tightly these versions are coupled.

For JupyterLab 2, the documented commands are:

bash
conda install -c conda-forge nodejs
jupyter labextension install @jupyter-widgets/jupyterlab-manager jupyter-matplotlib

The README provides a concrete historical example. Installing `ipympl` 0.5.1 requires `jupyter-matplotlib` 0.7.0, and that frontend version is stated to be compatible only with JupyterLab 1. The compatibility table gives a different pairing for current releases: `ipympl` 0.10.0 with `jupyter-matplotlib` 0.12.0, JupyterLab `>=2,<5`, and Matplotlib `>=3.5.0`.

That table is a compatibility boundary, not a general promise about every environment. The Python metadata requires Python 3.9 or later and declares support for JupyterLab 3 and 4 classifiers. It also requires `matplotlib>=3.5.0,<4`, `ipywidgets>=7.6.0,<9`, and `ipython<10`. An existing environment with older or newer components should be checked against those constraints before installation.

Development builds and frontend rebuild rules

Contributors who modify ipympl need to account for both Python and JavaScript. The README recommends `pixi` because the development environment contains Python and Node.js dependencies. Its documented setup installs dependencies, installs the Python package in editable mode, installs JavaScript packages, builds the extension, and registers the labextension in development mode.

bash
pixi install
pixi run pip install -e .
pixi run jlpm install
pixi run jlpm build
pixi run jupyter labextension develop --overwrite .

The workflow then uses separate terminals for automatic rebuilding and JupyterLab:

bash
pixi run npm run watch
bash
pixi run jupyter lab

The README gives a direct behavioral rule for contributors: after a TypeScript or JavaScript change, wait for the watch build and refresh the browser. After a Python change, restart the notebook kernel. That distinction is important because a browser refresh cannot reload arbitrary Python process state, while a kernel restart cannot substitute for a rebuilt frontend bundle.

Classic Jupyter Notebook development has an additional path. The README documents installing and enabling the notebook extension, with `pixi` and conda/mamba variants. This extra setup is specific to development for classic Notebook and should not be copied indiscriminately into a current JupyterLab installation.

Limitations that affect adoption decisions

The first limitation is environment coupling. ipympl is not just a switch in a Python script. The backend, `ipywidgets`, Matplotlib, JupyterLab, and the `jupyter-matplotlib` frontend package form a compatibility set. The README's table exists because the project cannot be treated as version-agnostic across notebook environments.

The second limitation is scope. ipympl enables interactive figures inside Jupyter Notebook and JupyterLab. The repository metadata does not claim support for non-Jupyter desktop embedding, and the README does not describe a standalone application deployment path. If the required interface is outside the notebook widget system, the documented project does not establish that it is the right tool.

There is also an operational limitation for contributors. Changes to Python require a kernel restart, while frontend changes require a completed build and browser refresh. That is a manageable development workflow, but it is more involved than editing a single Python plotting cell. The repository's JavaScript source, webpack configuration, TypeScript configuration, and labextension scripts confirm that frontend changes are a separate part of the project.

Finally, the README points users to an example notebook for detailed behavior. It does not provide a complete API reference for every canvas interaction or document a rollback procedure. Teams requiring a documented upgrade and rollback policy would need to establish that outside the README rather than assuming it is part of ipympl.

ipympl compared with a standard Matplotlib backend

The relevant alternative is the standard Matplotlib notebook integration selected through Matplotlib's own notebook magic, without installing ipympl. The README presents ipympl as the option for enabling Matplotlib's interactive features through Jupyter widgets. Its differentiator is therefore not a different plotting API. It is the integration path between the Matplotlib figure and the Jupyter widget layout.

A standard backend is simpler when the notebook only needs to display figures with the ordinary notebook interface. It avoids the additional `jupyter-matplotlib` frontend installation and the compatibility pairing that ipympl requires, particularly for older JupyterLab releases. ipympl is more appropriate when the figure `canvas` must be handled as a Jupyter interactive widget or placed into interactive widget layouts.

This is a concrete trade-off. Choosing ipympl adds a frontend and version-management concern in exchange for widget composition. It should not be selected merely because the project is related to Matplotlib. The repository's stated reason to use it is notebook interactivity, especially when the plot needs to behave as part of a larger widget-based interface.

Maintenance, licensing, and upgrade implications

The repository is not archived, and its last push was on 2026-07-31. The release information lists `v0.10.0` on 2026-01-21, `v0.9.8` on 2025-10-09, and `0.9.7` on 2025-03-05. Those dates indicate recent project activity, but maintenance status should not be reduced to release count. Upgrade planning still requires checking the installed frontend package and the compatibility table.

The project uses the BSD-3-Clause license, as stated in both the repository metadata and `package.json`. That identifier describes the project's declared licensing terms. This article does not interpret those terms or provide legal advice. The license file remains the relevant project-specific source for its exact provisions.

The upgrade cost is higher than a pure Python-only dependency bump when JupyterLab assets need changing. The Python distribution, the frontend extension, and the notebook runtime should be considered together. The README specifically warns users of JupyterLab 1 and 2 to select matching `jupyter-matplotlib` versions. It also documents a development build process that includes Node.js, `jlpm`, and labextension commands. A controlled upgrade should therefore begin with the current version pair and the relevant compatibility row.

Editorial conclusion

Adopt ipympl when a notebook needs an interactive Matplotlib canvas that can be composed with other Jupyter widgets. Do not choose it merely for static plots, or for notebook servers whose installed Matplotlib and JupyterLab versions do not match the compatibility table. Check the Python environment, the Matplotlib version, and the `ipympl` to `jupyter-matplotlib` pairing before upgrading; the current repository records `ipympl` 0.10.0 with `jupyter-matplotlib` 0.12.0 as the relevant pair.

Frequently asked questions

How do I install ipympl for Jupyter?

The README documents `pip install ipympl` and `conda install -c conda-forge ipympl`. Then enable the backend in a notebook with `%matplotlib ipympl`.

Which JupyterLab versions are compatible with ipympl?

The README recommends JupyterLab 3 for current use and provides manual instructions for JupyterLab 2. Its compatibility table lists `ipympl` 0.10.0 with JupyterLab `>=2,<5`, but the installed version pair must be checked.

Why does ipympl require a separate jupyter-matplotlib package?

The Python package is `ipympl`, while the repository's JavaScript package is `jupyter-matplotlib`. The README says older JupyterLab versions need the matching frontend extension installed separately.

Can an ipympl figure be used in a Jupyter widget layout?

Yes. The README states that the figure `canvas` element is a Jupyter interactive widget and can be positioned in interactive widget layouts.

What should I restart after changing ipympl source code?

The README says to wait for the frontend watch build and refresh the browser after TypeScript or JavaScript changes. After Python changes, restart the notebook kernel.

Official sources

  1. License: BSD-3-Clause
  2. matplotlib/ipympl on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/matplotlib-ipympl.svg)](https://hysenlabs.com/projects/matplotlib-ipympl)

Was this useful?