Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Animation saving via ffmpeg stops after some 300 frames #10729

Closed
ImportanceOfBeingErnest opened this issue Mar 9, 2018 · 7 comments

Comments

Projects
None yet
5 participants
@ImportanceOfBeingErnest
Copy link
Contributor

commented Mar 9, 2018

Bug report

Bug summary

Saving an animation with 1000 frames to a mp4 file via the ffmpeg writer fails on matplotlib 2.2. Instead of the desired 1000 frames, only some 300 frames are saved, then the process stops.
The same code works fine on matplotlib 2.1.

Code for reproduction

The following is the example code from basic_example_writer, with the number of frames modified to 1000.

import matplotlib
matplotlib.use("Agg")
print matplotlib.__version__
import matplotlib.pyplot as plt
import matplotlib.animation as animation

def update_line(num, data, line):
    line.set_data(data[..., :num])
    print num
    return line,

# Set up formatting for the movie files
Writer = animation.writers['ffmpeg']
writer = Writer(fps=15, metadata=dict(artist='Me'), bitrate=1800)  # try -1 as well

fig1 = plt.figure()

data = np.random.rand(2, 1000)
l, = plt.plot([], [], 'r-')
plt.xlim(0, 1)
plt.ylim(0, 1)
plt.xlabel('x')
plt.title('test')
line_ani = animation.FuncAnimation(fig1, update_line, 1000, fargs=(data, l),
                                   interval=50, blit=True)
line_ani.save('lines.mp4', writer=writer)

Actual outcome

In matplotlib 2.2 this code prints the numbers up to some endnumber of around 290. Then nothing happens - i.e. the process does not finish, just halts. There is a mp4 file created which shows those first 290 frames correctly (0:20 min long video). This file is created after the running process is manually termined.
Creating an animated gif via the imagemagick writer is perfectly possible though.

Expected outcome

In matplotlib 2.1 the code produces an mp4 file with 1000 frames (i.e. a 1:06 min long video) as expected.

Further details
Some relevant rcParams here:

print plt.rcParams["savefig.bbox"]           # None
print plt.rcParams["animation.writer"]       # ffmpeg
print plt.rcParams["animation.codec"]        # h264
print plt.rcParams["animation.ffmpeg_path"]  # ffmpeg
print plt.rcParams["animation.ffmpeg_args"]  # []

They are the same in both cases.

The actual number of frames produces varies. It is depending on the bitrate. 5 successive runs produce

with bitrate 1800
295, 293, 290, 291, 293  frames

bitrate -1 (default)
311, 311, 311, 311, 305  frames

This issue has been brought up in this SO post. In that case the example uses images and the maximal number of frames is again different from this example here.

Matplotlib version

  • Operating system: Windows 8.1
  • Matplotlib version: 2.2 (for nonworking code), 2.1 (for working code)
  • Matplotlib backend : Agg
  • Python version: 2.7.10
  • Other libraries: ffmpeg 2.8.4 (built with gcc 5.2)
@jklymak

This comment has been minimized.

Copy link
Contributor

commented Mar 9, 2018

I got to 1000.... Must be memory dependent, or machine dependent (Mac, 16 Gb). Funny that it'd work for 2.1 though...

@ImportanceOfBeingErnest

This comment has been minimized.

Copy link
Contributor Author

commented Mar 9, 2018

When running this I have 30% memory usage (so plenty of room to the top). I also have 16 GB Ram available. The saving does not visibly change the memory usage. CPU goes down at the moment the last image is handled, ie. when 294 is printed.

image

@QuLogic

This comment has been minimized.

Copy link
Member

commented Mar 9, 2018

I got to 1000 as well, so I'm not sure what the problem is.

@cgohlke

This comment has been minimized.

Copy link
Contributor

commented Mar 9, 2018

Looks like the culprit is at https://github.com/matplotlib/matplotlib/blob/v2.2.x/lib/matplotlib/animation.py#L673. Logging is not quieted because _log.getEffectiveLevel() > logging.DEBUG.

@anntzer

This comment has been minimized.

Copy link
Contributor

commented Mar 9, 2018

that line should definitely be ">" (on a logical pov, regardless of whether the buffer overfills)

@anntzer anntzer added this to the v2.2.1 milestone Mar 9, 2018

@jklymak jklymak referenced this issue Mar 9, 2018

Merged

FIX: ffmpeg logging level #10739

0 of 6 tasks complete
@jklymak

This comment has been minimized.

Copy link
Contributor

commented Mar 9, 2018

Thanks for catching!

The logic error aside, is this an ffmpeg bug that doesn't let the verbosity level be a certain size, or is it our bug? Because this'll still not work if someone uses a non-DEBUG logging level.

@QuLogic

This comment has been minimized.

Copy link
Member

commented Mar 9, 2018

It's really more on our side. As noted in the comment, the subprocess pipe will overflow, probably because we only read it at the end (but I didn't look.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.