ipympl for Interactive Matplotlib Figures in Jupyter
Matplotlib Jupyter Integration
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:
%matplotlib ipymplAfter 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:
pip install ipymplThe README also documents a conda installation:
conda install -c conda-forge ipymplAfter installation, start or open a Jupyter environment and select the backend in a notebook cell:
%matplotlib ipymplThe 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:
conda install -c conda-forge nodejs
jupyter labextension install @jupyter-widgets/jupyterlab-manager jupyter-matplotlibThe 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.
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:
pixi run npm run watchpixi run jupyter labThe 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
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.
[](https://hysenlabs.com/projects/matplotlib-ipympl)Was this useful?