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 with 'ffmpeg' backend and 'savefig.bbox = tight' garbles video #6416

Closed
chipmuenk opened this issue May 13, 2016 · 10 comments
Closed
Assignees
Milestone

Comments

@chipmuenk
Copy link

chipmuenk commented May 13, 2016

Using

Setting savefig.bbox = tight either in matplotlibrc or as an rcParam garbles an mp4 video written by ffmpeg. Even starting the script with --verbose-debug gives no warning or message that something might be wrong.

I also cannot change the frame rate - neither interval nor fps has any effect, I always get 5 fps (this is consistent with the options passed to ffmpeg which always says '-r 5').

Example (slightly modded) taken from
https://jakevdp.github.io/blog/2012/08/18/matplotlib-animation-tutorial/ :

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

plt.rcParams['animation.ffmpeg_path'] = 'D:/Programme/ffmpeg/bin/ffmpeg.exe'
plt.rcParams['savefig.bbox'] = 'tight'     # tight garbles the video!!!

movie_file = 'D:/Daten/basic_animation.mp4'
mywriter = animation.FFMpegWriter()

fig = plt.figure()
fig.set_size_inches(4, 5, True)
ax = plt.axes(xlim=(0, 2), ylim=(-2, 2))
line, = ax.plot([], [], lw=2)

def init():
    line.set_data([], [])
    return line,

def animate(i):
    x = np.linspace(0, 2, 1000)
    y = np.sin(2 * np.pi * (x - 0.01 * i))
    line.set_data(x, y)
    return line,

anim = animation.FuncAnimation(fig, animate, init_func=init,
                               interval = 1000, frames = 20, blit=True)

anim.save(movie_file, dpi=100, fps = 30, writer=mywriter, 
          extra_args=['-vcodec', 'libx264'])

plt.show()
@dopplershift
Copy link
Contributor

I can reproduce the fps issue here locally on OSX on python 3.4, matplotlib 1.5.1. Not sure why -r 5 is getting passed.
(I'd say let's leave the 'tight' issue to #2483).

@dopplershift dopplershift self-assigned this May 13, 2016
@dopplershift dopplershift added this to the 1.5.2 (Critical bug fix release) milestone May 13, 2016
@tacaswell
Copy link
Member

It might be worth using an rccontext in anim.save to force the bounding box to always be off?

This is an awfully large foot-cannon to have very lightly documented.

@dopplershift
Copy link
Contributor

That's a really good idea--I'll go ahead and include that when I put up a PR to fix the fps issue.

@dopplershift
Copy link
Contributor

Ok, so there are really two things that are different cases that we haven't hit before:

  1. Using rcparams for tight bbox. We can address this using rc_context, as suggested by @tacaswell
  2. Passing in a MovieWriter instance along with some kwargs that are used in the creation of a MovieWriter instance (when save needs to create one). The question is: Should we modify the passed in MovieWriter using the kwargs? Or should we just document that these are ignored if writer is a MovieWriter instance?

In the meanwhile, the work-around/intended use would be to do:

mywriter = animation.FFMpegWriter(fps=30, extra_args=['-vcodec', 'libx264'])

and

anim.save(movie_file, dpi=100, writer=mywriter)

Clearly, since I had to actually dig into this problem, it's not intuitive; I'm just not sure what the right answer is.

dopplershift added a commit to dopplershift/matplotlib that referenced this issue May 13, 2016
This fixes part of matplotlib#6416 by resetting the 'savefig.bbox' rcParam if it
is set to 'tight'.
@chipmuenk
Copy link
Author

The workaround works for me (for the fps issue) - thanx for the explanation and the quick solution!

For debugging purposes, it would be great to see messages created by the actual movie writer (ffmpeg in my case): An invalid parameter in the extra_args list e.g. just raises an IOError.

dopplershift added a commit to dopplershift/matplotlib that referenced this issue May 15, 2016
This fixes part of matplotlib#6416 by resetting the 'savefig.bbox' rcParam if it
is set to 'tight'.
@dopplershift
Copy link
Contributor

Having given this some thought, I think the right solution is to document the kwargs which will have no effect when writer is an instance of MovieWriter and to issue a warning when both are supplied (which will of course say the arguments should be supplied when creating the MovieWriter.)

Anyone else have any thoughts?

@tacaswell
Copy link
Member

No one reads warnings 👿.

I lean towards raise, but would merge a PR which added the warnings.

@dopplershift
Copy link
Contributor

raise works for me too. One point: raising the error could break code that "works". I think this is fine (since existing code can't be working as intended)...but how do we feel about that for matplotlib?

@tacaswell
Copy link
Member

I tend to view that as ok, it is just telling users that code that wasn't working really isn't working.

@dopplershift
Copy link
Contributor

Fixed by #6441 and #6421.

tacaswell pushed a commit to tacaswell/matplotlib that referenced this issue May 22, 2016
This fixes part of matplotlib#6416 by resetting the 'savefig.bbox' rcParam if it
is set to 'tight'.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants