matplotlib/matplotlib · error · ValueError

streamed pgf-code does not support raster graphics, consider

Error message

streamed pgf-code does not support raster graphics, consider using the pgf-to-pdf option

What it means

PGF output references raster images with \includegraphics pointing at PNG files written next to the output file. That only works when the destination is a real file on disk (self.fh has a name attribute); printing pgf code into a stream such as io.BytesIO or sys.stdout cannot reference sibling files, so draw_image raises ValueError recommending the pgf-to-pdf route.

Source

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

        _writeln(self.fh, r"\pgfusepath{%s}" % ",".join(actions))

    def option_scale_image(self):
        # docstring inherited
        return True

    def option_image_nocomposite(self):
        # docstring inherited
        return not mpl.rcParams['image.composite_image']

    def draw_image(self, gc, x, y, im, transform=None):
        # docstring inherited

        h, w = im.shape[:2]
        if w == 0 or h == 0:
            return

        if not os.path.exists(getattr(self.fh, "name", "")):
            raise ValueError(
                "streamed pgf-code does not support raster graphics, consider "
                "using the pgf-to-pdf option")

        # save the images to png files
        path = pathlib.Path(self.fh.name)
        fname_img = "%s-img%d.png" % (path.stem, self.image_counter)
        Image.fromarray(im[::-1]).save(path.parent / fname_img)
        self.image_counter += 1

        # reference the image in the pgf picture
        _writeln(self.fh, r"\begin{pgfscope}")
        self._print_pgf_clip(gc)
        f = 1. / self.dpi  # from display coords to inch
        if transform is None:
            _writeln(self.fh,
                     r"\pgfsys@transformshift{%fin}{%fin}" % (x * f, y * f))
            w, h = w * f, h * f
        else:

View on GitHub (pinned to b379c1b69e)

Solutions

  1. Save to a real path instead: fig.savefig('out.pgf'), then read the file (and the sibling -img*.png files) from disk
  2. Keep the pgf backend but request PDF: fig.savefig('out.pdf') — the pgf-to-pdf path works from temp files and supports raster images
  3. For in-memory PDF with images, switch to the native pdf backend: fig.savefig(buf, format='pdf', backend='pdf')

Example fix

# before
buf = io.BytesIO()
fig.savefig(buf, format='pgf')  # figure contains imshow -> ValueError

# after
fig.savefig('out.pgf')            # real path: sibling PNGs can be written
# or: fig.savefig('out.pdf')       # pgf-to-pdf route
Defensive patterns

Strategy: validation

Validate before calling

import os

def pgf_target_ok(target) -> bool:
    return isinstance(target, (str, os.PathLike))

if figure_has_images(fig) and not pgf_target_ok(dest):
    dest = tempfile.mkdtemp() + '/out.pgf'  # write to disk instead
fig.savefig(dest, format='pgf')

Try / catch

try:
    fig.savefig(buf, format='pgf')
except ValueError as err:
    if 'raster graphics' not in str(err):
        raise
    fig.savefig('out.pdf')  # pgf-to-pdf route supports images

Prevention

When it happens

Trigger: fig.savefig(buf, format='pgf') with buf a BytesIO/StringIO while the figure contains an image artist (imshow, imread-based plots); any print_pzf call where the file handle has no usable name.

Common situations: Web services generating pgf bytes in memory; test suites capturing output in BytesIO; refactoring path-based savefig to stream-based without remembering the sibling-PNG constraint.

Related errors


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