matplotlib-inline
Inline Matplotlib backend that renders figures directly inside Jupyter and IPython notebook cells.
Repository Health
Technical Analysis
matplotlib-inline is the backend that lets Matplotlib figures appear directly beneath the code cell that created them in Jupyter Notebook, JupyterLab, and other IPython-based clients. It implements the module://matplotlib_inline.backend_inline backend Matplotlib loads when a notebook runs %matplotlib inline, converting each figure into a display payload (PNG, SVG, JPEG, PDF, or retina PNG) that IPython’s rich display system sends to the frontend.
The package was split out of IPython itself so that it could be installed independently, without pulling in the full IPython or Matplotlib dependency trees at install time. It hooks into IPython’s post_execute event to automatically flush and close figures after each cell runs, exposes an InlineBackend traitlets Configurable for tuning figure formats and savefig keyword arguments, and provides set_matplotlib_formats/set_matplotlib_close helper functions for adjusting that behavior from user code or %config magics.
What You Get
- A registered Matplotlib backend (
module://matplotlib_inline.backend_inline) that converts figures to display payloads instead of opening interactive windows - Automatic figure flushing and cleanup wired into IPython’s
post_executeevent viaconfigure_inline_support - An
InlineBackendtraitletsConfigurableexposingfigure_formats,print_figure_kwargs, andclose_figuressettings via%configmagics oripython_config.py set_matplotlib_formats()andset_matplotlib_close()helper functions for adjusting output format and cell-close behavior from user code- Automatic light/dark background metadata detection for figures with transparent backgrounds, so frontends can render them legibly in either theme
Common Use Cases
- Running
%matplotlib inlinein a Jupyter notebook or JupyterLab session to have plots appear directly below the cell that produced them - Configuring output resolution or format (e.g. switching to
retinaorsvg) for sharper figures in exported notebooks or reports - Building third-party tools (e.g. Spyder) that need programmatic access to the same inline-figure configuration Jupyter uses
- Keeping figures alive across cells by setting
close_figures = Falseto iteratively refine a plot over multiple notebook cells
Under The Hood
Architecture
The package is a thin, single-purpose bridge between three systems: Matplotlib’s backend plugin API, IPython’s event/display system, and traitlets’ configuration framework. backend_inline.py implements the two functions Matplotlib’s backend contract requires (new_figure_manager/new_figure_manager_given_figure), plus show() and flush_figures(), which walk Matplotlib’s global figure manager registry (Gcf) and hand each active figure to IPython.display.display() as a display payload. configure_inline_support() is the integration point: it registers flush_figures as an IPython post_execute callback so every cell automatically renders and (optionally) closes its figures, and it swaps matplotlib.rcParams in and out to apply/restore the inline-specific rc overrides. config.py is deliberately import-isolated from Matplotlib so that configuration state can be constructed without triggering Matplotlib’s own import cost. The module-level _enable_matplotlib_integration() call at import time auto-wires the backend into the running IPython shell if one is detected, with a fallback that defers registration to post_run_cell if a circular-import edge case is hit.
Tech Stack
The only runtime dependency declared in pyproject.toml is traitlets, used for the InlineBackend SingletonConfigurable class and its typed trait descriptors (Bool, Dict, Instance, Set, Unicode). Matplotlib and IPython are treated as soft/optional dependencies at the top of backend_inline.py — imported lazily and only exercised at runtime — specifically so pip install matplotlib-inline stays lightweight for tools that just need the entry point registered. The project builds with flit_core and targets Python 3.9+. Its [project.entry-points."matplotlib.backend"] section registers inline = matplotlib_inline.backend_inline so Matplotlib’s backend resolution can discover it without any Jupyter-specific glue.
Code Quality
Tests live under tests/ and are run with pytest configured via nbval, which executes and diffs the notebooks in tests/notebooks/ as the primary test fixtures, alongside a small test_import.py sanity check. pyproject.toml enables ruff (with pyupgrade, isort, and flake8-bugbear rule sets) and a mypy configuration with warn_unreachable and stricter error codes, plus xfail_strict and filterwarnings = ["error"] in the pytest config to catch silent warnings. The codebase is small (a handful of files) and reads as focused and stable rather than actively iterated — most functions are short, docstringed, and unchanged from their long-standing IPython-derived implementations.
What Makes It Unique
Its distinguishing design choice is architectural minimalism in service of a specific dependency-hygiene goal: this backend used to live inside IPython itself, and the project was deliberately extracted so that packages needing to register the entry point (or reference InlineBackend) don’t have to install all of IPython or Matplotlib. That single-purpose scope, combined with its role as the de facto standard rendering path for %matplotlib inline across virtually every Jupyter-compatible frontend, is the whole value proposition rather than any novel algorithm or feature set.