matplotlib/matplotlib · error · TypeError

grab_frame got an unexpected keyword argument {k!r}

Error message

grab_frame got an unexpected keyword argument {k!r}

What it means

grab_frame ultimately calls fig.savefig(**savefig_kwargs) after _validate_grabframe_kwargs strips the writer's own controls. The keys 'dpi', 'bbox_inches' and 'format' are managed by the writer (dpi comes from the figure, bbox must not be tight per error 69, format is writer.frame_format), so passing any of them via savefig_kwargs raises TypeError 'grab_frame got an unexpected keyword argument {k!r}'.

Source

Thrown at lib/matplotlib/animation.py:1835

                if not isinstance(i, mpl.artist.Artist):
                    raise err

            self._drawn_artists = sorted(self._drawn_artists,
                                         key=lambda x: x.get_zorder())

            for a in self._drawn_artists:
                a.set_animated(self._blit)


def _validate_grabframe_kwargs(savefig_kwargs):
    if mpl.rcParams['savefig.bbox'] == 'tight':
        raise ValueError(
            f"{mpl.rcParams['savefig.bbox']=} must not be 'tight' as it "
            "may cause frame size to vary, which is inappropriate for animation."
        )
    for k in ('dpi', 'bbox_inches', 'format'):
        if k in savefig_kwargs:
            raise TypeError(
                f"grab_frame got an unexpected keyword argument {k!r}"
            )

View on GitHub (pinned to b379c1b69e)

Solutions

  1. Control resolution via the figure: fig.set_dpi(72) (or pass dpi when creating the figure / to the writer where supported) before anim.save
  2. Remove dpi/bbox_inches/format from savefig_kwargs; pass only genuinely pass-through kwargs like facecolor or transparent
  3. Set writer.frame_format (e.g. PillowWriter(frame_format='png')) instead of 'format'
  4. Handle bbox via layout engines (layout='constrained') or post-crop the video

Example fix

# before
anim.save("out.mp4", savefig_kwargs={"dpi": 72})  # TypeError

# after
fig.set_dpi(72)
anim.save("out.mp4")
Defensive patterns

Strategy: validation

Validate before calling

WRITER_OWNED = {"dpi", "bbox_inches", "format"}

def safe_grabframe_kwargs(savefig_kwargs):
    bad = WRITER_OWNED & set(savefig_kwargs)
    if bad:
        raise TypeError(f"keys {sorted(bad)} are controlled by the writer/figure, "
                        f"got them in savefig_kwargs")
    return savefig_kwargs

Prevention

When it happens

Trigger: anim.save('out.mp4', savefig_kwargs={'dpi': 72}); anim.save('out.mp4', savefig_kwargs={'bbox_inches': 'tight'}); anim.save('out.gif', savefig_kwargs={'format': 'png'}); calling writer.grab_frame(dpi=...) directly.

Common situations: Copy-pasting savefig kwargs from static-export code into anim.save; trying to control output resolution per-save; generic export wrappers that forward one kwargs dict to both plt.savefig and anim.save.

Related errors


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