matplotlib/matplotlib · error · RuntimeError

{mpl.rcParams['pgf.texsystem']!r} not found; install it or c

Error message

{mpl.rcParams['pgf.texsystem']!r} not found; install it or change rcParams['pgf.texsystem'] to an available TeX implementation

What it means

backend_pgf spawns rcParams['pgf.texsystem'] (an engine such as xelatex, pdflatex or lualatex) as a subprocess. A FileNotFoundError from Popen — the configured engine is not on PATH — is re-raised as a RuntimeError that tells you to install the engine or point pgf.texsystem at one that exists.

Source

Thrown at lib/matplotlib/backends/backend_pgf.py:298

                f"{self._build_latex_header()}",
                stdout)
        self.latex = None  # Will be set up on first use.
        # Per-instance cache.
        self._get_box_metrics = functools.lru_cache(self._get_box_metrics)

    def _setup_latex_process(self, *, expect_reply=True):
        # Open LaTeX process for real work; register it for deletion.  On
        # Windows, we must ensure that the subprocess has quit before being
        # able to delete the tmpdir in which it runs; in order to do so, we
        # must first `kill()` it, and then `communicate()` with or `wait()` on
        # it.
        try:
            self.latex = subprocess.Popen(
                [mpl.rcParams["pgf.texsystem"], "-halt-on-error", "-no-shell-escape"],
                stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                encoding="utf-8", cwd=self.tmpdir)
        except FileNotFoundError as err:
            raise RuntimeError(
                f"{mpl.rcParams['pgf.texsystem']!r} not found; install it or change "
                f"rcParams['pgf.texsystem'] to an available TeX implementation"
            ) from err
        except OSError as err:
            raise RuntimeError(
                f"Error starting {mpl.rcParams['pgf.texsystem']!r}") from err

        def finalize_latex(latex):
            latex.kill()
            try:
                latex.communicate()
            except RuntimeError:
                latex.wait()

        self._finalize_latex = weakref.finalize(
            self, finalize_latex, self.latex)
        # write header with 'pgf_backend_query_start' token
        self._stdin_writeln(self._build_latex_header())

View on GitHub (pinned to b379c1b69e)

Solutions

  1. Install a TeX distribution (TeX Live, MiKTeX) and make sure its bin directory is on PATH
  2. Point rcParams['pgf.texsystem'] at an engine you actually have: mpl.rcParams['pgf.texsystem'] = 'pdflatex'
  3. Verify visibility first: shutil.which(mpl.rcParams['pgf.texsystem'])
  4. If TeX is unavailable, use a non-TeX backend (Agg/PDF/SVG)

Example fix

# before
mpl.rcParams['pgf.texsystem'] = 'xelatex'  # xelatex not installed -> RuntimeError
mpl.use('pgf')

# after
mpl.rcParams['pgf.texsystem'] = 'pdflatex'  # engine that IS on PATH
mpl.use('pgf')
Defensive patterns

Strategy: validation

Validate before calling

import shutil
import matplotlib as mpl

def texsystem_available() -> bool:
    return shutil.which(mpl.rcParams['pgf.texsystem']) is not None

if not texsystem_available():
    for engine in ('pdflatex', 'xelatex', 'lualatex'):
        if shutil.which(engine):
            mpl.rcParams['pgf.texsystem'] = engine
            break
    else:
        raise SystemExit('no TeX engine found; install TeX Live or MiKTeX')

Try / catch

try:
    mpl.use('pgf')
    fig.savefig('out.pgf')
except RuntimeError as err:
    if 'not found' not in str(err):
        raise
    mpl.rcParams['pgf.texsystem'] = 'pdflatex'  # an engine that exists
    fig.savefig('out.pgf')

Prevention

When it happens

Trigger: Using the pgf backend on a machine with no TeX distribution installed, or with pgf.texsystem set to an engine variant that is absent (e.g. 'lualatex' missing while only pdflatex is installed).

Common situations: Slim Docker images, fresh OS installs, Windows with MiKTeX not on PATH, conda environments without a tex package, CI runners lacking latex.

Related errors


AI-assisted analysis of matplotlib/matplotlib@b379c1b69e (2026-08-21). Data as JSON: /api/errors/d44e7d6a009b418c. Report an issue: GitHub.