pythonmatplotlibanimationffmpeg

How could I create a fps=1 mp4 video using FFMpegWriter from matplotlib.animation?


I would like to create a video to visualize a small dataset. This dataset contains only 10 or 20 frames of data, and I want to visualize it one frame a second and make a .mp4 video using FFMpegWriter.

But when I set fps=1, there is a long time black screen of the result video and only a still image. After that, this .mp4 ends. An example of code is as follows:

import numpy as np
from matplotlib.animation import FFMpegWriter

np.random.seed(0)
fig, ax = plt.subplots(figsize=(9, 4))
ln, = ax.plot([])
ax.set_xlim([0, 1000])
ax.set_ylim([-1, 1])
ax.grid(True)

writer = FFMpegWriter(fps=1)
with writer.saving(fig, "writer_test.mp4", 300):
    for i in range(20):
        x = np.arange(1000)
        t = np.random.randn(1000)
        y = np.sin(2 * np.pi * t)
        ln.set_data(x, y)
        writer.grab_frame()
plt.show()

If I change fps to 10, then the video flows well but end too soon. Can I grab and make videos one frame per second?


Solution

  • As commented above, this is not so much different from matplotlib implementation, but you open the output file with specified framerate, which makes it easier to grasp imo.

    import numpy as np
    from matplotlib import pyplot as plt
    import ffmpegio
    
    np.random.seed(0)
    fig, ax = plt.subplots(figsize=(9, 4),dpi=300)
    ln, = ax.plot([])
    ax.set_xlim([0, 1000])
    ax.set_ylim([-1, 1])
    ax.grid(True)
    
    with ffmpegio.open(
      "writer_test.mp4", # output file name
      "wv", # open file in write-video mode
      1, # framerate in frames/second
      pix_fmt="yuv420p", # specify the pixel format (default is yuv444p)
      overwrite=True
    ) as writer:
        for i in range(20):
            x = np.arange(1000)
            t = np.random.randn(1000)
            y = np.sin(2 * np.pi * t)
            ln.set_data(x, y)
            writer.write(fig)
    

    You can add any ffmpeg output & global options as arguments to the open().

    Addendum (8/3/24):

    To use this package and mpl plugin, you need to install the packages first:

    pip install ffmpegio ffmpegio-plugin-mpl