Skip to content

Commit

Permalink
Allow swapping the underlying rendering backend.
Browse files Browse the repository at this point in the history
This patch implements backend_inline.set_rendering_backend, such that
`set_rendering_backend("foo")` behaves as if calling
`matplotlib.use("foo")`, which allows selecting an alternative rendering
backend.

In matplotlib itself, the only relevant alternative rendering backend is
cairo, which is generally less feature-ful than agg, but there are also
third-party backends, such as mplcairo
(`set_rendering_backend("module://mplcairo.base")`) which provide e.g.
improved text rendering for complex scripts (Arabic, Hebrew) and
different compositing options.
  • Loading branch information
anntzer committed Feb 5, 2023
1 parent fbf0ab8 commit 2b4a17c
Showing 1 changed file with 26 additions and 9 deletions.
35 changes: 26 additions & 9 deletions matplotlib_inline/backend_inline.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
# Copyright (c) IPython Development Team.
# Distributed under the terms of the BSD 3-Clause License.

import importlib

import matplotlib
from matplotlib import colors
from matplotlib.backends import backend_agg
from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib._pylab_helpers import Gcf
from matplotlib.figure import Figure

Expand All @@ -18,6 +18,29 @@
from .config import InlineBackend


def set_rendering_backend(backend_name):
"""
Set the rendering backend.
Parameters
----------
backend_name : str
A backend name, as would be passed to ``matplotlib.use()``. The
backend should be non-interactive.
"""
global _backend_module, FigureCanvas
_backend_module = importlib.import_module(
backend_name[9:] if backend_name.startswith("module://")
else f"matplotlib.backends.backend_{backend_name.lower()}")
# Changes to matplotlib in version 1.2 requires a mpl backend to supply a
# FigureCanvas. See https://github.com/matplotlib/matplotlib/pull/1125
FigureCanvas = _backend_module.FigureCanvas


_backend_module = FigureCanvas = None # Will be set by the call below.
set_rendering_backend("agg") # The default rendering backend.


def new_figure_manager(num, *args, FigureClass=Figure, **kwargs):
"""
Return a new figure manager for a new figure instance.
Expand All @@ -33,7 +56,7 @@ def new_figure_manager_given_figure(num, figure):
This function is part of the API expected by Matplotlib backends.
"""
manager = backend_agg.new_figure_manager_given_figure(num, figure)
manager = _backend_module.new_figure_manager_given_figure(num, figure)

# Hack: matplotlib FigureManager objects in interacive backends (at least
# in some of them) monkeypatch the figure object and add a .show() method
Expand Down Expand Up @@ -152,12 +175,6 @@ def flush_figures():
show._draw_called = False


# Changes to matplotlib in version 1.2 requires a mpl backend to supply a default
# figurecanvas. This is set here to a Agg canvas
# See https://github.com/matplotlib/matplotlib/pull/1125
FigureCanvas = FigureCanvasAgg


def configure_inline_support(shell, backend):
"""Configure an IPython shell object for matplotlib use.
Expand Down

0 comments on commit 2b4a17c

Please sign in to comment.