Issue
I have created a regular animation using mathplotlib. here is the relevent line:
myAnimation = animation.FuncAnimation(fig, animate_points_in_orbits, frames=np.arange(0, len(time_frames)),
interval=3, blit=True, repeat=True, repeat_delay=1000)
The animation looks good in the preview:
However, when I save the animation to mp4 using this line:
myAnimation.save('first_animation.mp4', fps=30, extra_args=['-vcodec', 'libx264'])
There is some issue with the layers: the blue circle overrides the green dot. which should not happen because the blue circle is plotted before the animation and is not part of the animation at all. in the animation, only the locations of the dots are modified. Here is a screenshot from the mp4 video:
I have tried to play with the coded, bitrate and dpi as suggested in this answer, but nothing seems to work.
Edit:
I could understand what causes the issue, though still not sure why this happens in the first place. Here is a simple code to produce the issue:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
TWO_PI_RANGE = np.arange(0.0, 2*np.pi, 0.01)
def draw_circle():
x_array = np.sin(TWO_PI_RANGE)
y_array = np.cos(TWO_PI_RANGE)
plt.plot(x_array, y_array, 'blue')
def animate_points(i):
g.set_data(np.sin(i), np.cos(i))
return g,
fig = plt.figure(figsize=(5, 5))
g, = plt.plot([0], [0], "o", color='green', markersize=8)
draw_circle()
myAnimation = animation.FuncAnimation(fig, animate_points, frames=TWO_PI_RANGE, interval=3, blit=True, repeat=True, repeat_delay=1000)
myAnimation.save('test.mp4', fps=60, extra_args=['-vcodec', 'libx264'])
plt.show()
Now, if I put the draw_circle
before g, = plt.plot([0], [0], "o", color='green', markersize=8)
, the mp4 video looks fine (like the preview)
Solution
It appears the cause for the mismatch between the preview and the mp4 is a bug in the preview. Neither set_data
function, nor the fact that an object is returned by the animate function, should cause the object to lose its zorder property and become on top. Hence in the given code that plots the blue circle after the green dot, we would expect the green dot to be behind the blue circle as presented in the mp4. This behavior should also be expected in the preview (plt.show()
)
However, as @PaulBrodersen brought to my attention there is an open issue that the zorder of an object might be overridden if the object is returned from the animate function, if blit
is set to be True (as in our example):
In animated plots, the order in which artists are drawn is determined by their position in the sequence returned by the animation function, despite their own "zorder" property.
When blit
is set to False, both the preview and the mp4 result in the same outcome.
Hence it was suggested that:
With blitting the animated artists must be on top of all the other artists in the axes so we are already treating the animated artists differently.
Answered By - d_e
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.