如何在视频中保存动画而不显示前面的帧?

1 投票
1 回答
2489 浏览
提问于 2025-04-18 00:26

我想用Python保存一个动画,但我得到的帧是重叠在一起的!我想要每一帧单独显示。以下是我使用的代码:

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
from numpy import pi, cos, sin

fig = plt.figure()
plt.axis([-1.5, 1.5,-1.5, 1.5])
ax = plt.gca()
ax.set_aspect(1)

N=100

xp = [None] * N
yp = [None] * N

def init():
    # initialize an empty list of cirlces
    return []

def animate(i):

    xp[i]=sin(i*pi/10)
    yp[i]=cos(i*pi/10)

    patches = []

    patches.append(ax.add_patch( plt.Circle((xp[i],yp[i]),0.02,color='b') ))
    return patches 

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

anim.save("example.avi")
plt.show()

1 个回答

1

有些事情我不太确定,感觉axis.plot()和FuncAnimate()的行为是不一样的。不过,下面的代码在这两种情况下都能正常工作。

只用一个图形(在你的情况下)

你代码中的关键点是,每次循环时你都在添加一个新的圆形,除了旧的圆形:

patches = []
patches.append(ax.add_patch( plt.Circle((xp[i],yp[i]),0.02,color='b') ))

虽然你清空了图形列表,但它们仍然保存在坐标轴上。

所以,建议你只创建一个圆形,然后改变它的位置。

init()清除第一帧

另外,init()需要清除基础帧中的图形。

独立示例

from matplotlib import pyplot as plt
from matplotlib import animation
from numpy import pi, cos, sin

fig = plt.figure()
plt.axis([-1.5, 1.5, -1.5, 1.5])
ax = plt.gca()
ax.set_aspect(1)
N = 100
xp = []
yp = []


# add one patch at the beginning and then change the position
patch = plt.Circle((0, 0), 0.02, color='b')
ax.add_patch(patch)
def init():
    patch.set_visible(False)
    # return what you want to be cleared when axes are reset
    # this actually clears even if patch not returned it so I'm not sure
    # what it really does
    return tuple()


def animate(i):
    patch.set_visible(True)  # there is probably a more efficient way to do this
    # just change the position of the patch
    x, y = sin(i*pi/10), cos(i*pi/10)
    patch.center = x, y
    # I left this. I guess you need a history of positions.
    xp.append(x)
    yp.append(y)
    # again return what you want to be cleared after each frame
    # this actually clears even if patch not returned it so I'm not sure
    # what it really does
    return tuple()


anim = animation.FuncAnimation(fig, animate, init_func=init,
                               frames=N-1, interval=20, blit=True)
# for anyone else, if you get strange errors, make sure you have ffmpeg
# on your system and its bin folder in your path or use whatever
# writer you have as: writer=animation.MencoderWriter etc...
# and then passing it to save(.., writer=writer)
anim.save('example.mp4')
plt.show()

返回值???

关于init()animate()的返回值,似乎返回什么都没关系。那个单一的图形仍然可以移动并正确绘制,而不会清除之前的图形。

撰写回答