Matplotlib视频创建

Matplotlib视频创建,matplotlib,Matplotlib,EDIT:importantanceofbeingernest提供了答案,但我仍请大家解释一下,为什么savefig逻辑不同于animation逻辑。 我想在matplotlib中制作一个视频。我看了很多手册和例子,但还是不明白。(关于matplotlib,我总是复制示例,因为在使用了五年python和两年mathplotlib之后,我仍然理解0.0%的matplotlib语法) 半打小时后,我想到了这一点。嗯,我得到的是空视频。不知道为什么 import os import math impo

EDIT:importantanceofbeingernest提供了答案,但我仍请大家解释一下,为什么
savefig
逻辑不同于
animation
逻辑。

我想在
matplotlib
中制作一个视频。我看了很多手册和例子,但还是不明白。(关于matplotlib,我总是复制示例,因为在使用了五年python和两年mathplotlib之后,我仍然理解0.0%的matplotlib语法)

半打小时后,我想到了这一点。嗯,我得到的是空视频。不知道为什么

import os
import math
import matplotlib
matplotlib.use("Agg")
from matplotlib import pyplot as plt
import matplotlib.animation as animation

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

numb=100
temp=[0.0]*numb
cont=[0.0]*numb
for i in range(int(4*numb/10),int(6*numb/10)):
    temp[i]=2
    cont[i]=2

fig = plt.figure()
plts=fig.add_subplot(1,1,1)

plts.set_ylim([0,2.1])
plts.get_xaxis().set_visible(False)
plts.get_yaxis().set_visible(False)
ims = []

for i in range(1,10):
    line1, = plts.plot(range(0,numb),temp, linewidth=1, color='black')
    line2, = plts.plot(range(0,numb),cont, linewidth=1, color='red')
#    savefig is here for testing, works perfectly!
#    fig.savefig('test'+str(i)+'.png', bbox_inches='tight', dpi=300)
    ims.append([line1,line2])
    plts.lines.remove(line1)
    plts.lines.remove(line2)
    for j in range(1,10):
        tempa=0
        for k in range (1,numb-1):
            tempb=temp[k]+0.51*(temp[k-1]-2*temp[k]+temp[k+1])
            temp[k-1]=tempa
            tempa=tempb
        temp[numb-1]=0
    for j in range(1,20):
        conta=0
        for k in range (1,numb-1):
            contb=cont[k]+0.255*(cont[k-1]-2*cont[k]+cont[k+1])
            cont[k-1]=conta
            conta=contb
        cont[numb-1]=0

im_ani = animation.ArtistAnimation(fig, ims, interval=50, repeat_delay=3000,blit=True)
im_ani.save('im.mp4', writer=writer)

有人能帮我吗?

如果你想要一个不是空的绘图,主要的想法是不要从绘图中删除线条

也就是说,删除这两行

plts.lines.remove(line1)
plts.lines.remove(line2)
如果删除这两行,输出将如下所示

[]

现在有人可能会问,为什么我不需要在每个迭代步骤中删除艺术家,否则所有的线条都会一次填充画布

答案是,艺术化处理了这个问题。它将仅显示所提供列表中与给定时间步长相对应的艺术家。因此,在for循环结束时,您将得到绘制到画布上的所有线条,一旦动画开始,这些线条都将被删除,并且一次只显示一组艺术家

在这种情况下,使用循环保存单个图像当然不是一个好主意,因为最终图像将同时包含所有绘制的线

然后,解决方案是运行两次脚本,一次用于动画,另一次在每个时间步中删除行。或者,最好使用动画istself来创建图像

im_ani.save('im.png', writer="imagemagick") 
将在当前文件夹中将图像创建为
im-.png
。它需要安装imagemagick


我在这里试图回答评论中的两个问题:

1。我在删除第1行和第2行之前添加了它们。但在最后的结果中他们还是消失了。为什么

您已将这些行追加到列表中。之后,从轴上删除线。现在这些线在列表中,但不是轴的一部分。执行动画时,matplotlib会在列表中查找线并使其可见。但它们不在轴中(因为它们已被删除),因此某些Line2D对象的可见性会发生更改,这些对象不存在于任何轴中,但仅存在于内存中的某个位置。但这并没有反映在绘图中,因为绘图不再知道这条线

2.如果我理解正确,当您发布line1时,=plts.plot。。。命令,然后将line1 plot对象添加到plts graph对象。但是,如果通过发出line1更改line1 plot对象,=plts.plot。。。命令再次执行时,matplotlib会更改line1对象,但在此之前,会将旧line1永久保存到plts图形对象。这就是造成我问题的原因吗


否。第一步是正确的,
line1,=plts.plot(..)
将Line2D对象添加到轴。但是,在后面的循环步骤
line1中,=plts.plot()
创建另一个Line2D对象并将其放置到画布上。初始Line2D对象是未更改的,它不知道现在在绘图中它旁边还有其他线条。因此,如果不删除这些线,它们将在末尾的静态绘图中全部可见。

关键是绘图中的数据应该更改,视频中每个图片的数据都不同。所以主要的问题是,这个问题的整个逻辑可能是完全错误的,但我不能控制自己,因为我什么都不懂。我不确定我是否理解整个逻辑是错误的。我发现不删除应该显示的内容是很合乎逻辑的。有趣的是,如果我删除这两行,生成的PNG将是错误的。怎么会?一个用于savefig的逻辑和另一个用于视频的逻辑??我必须删除它,因为否则所有情节都会在最后一个PNGOK上累积,既然您回答了我的问题,我将接受它。希望以后有人能解释为什么
savefig
动画不同。为什么我的解释不够清楚?@ImportanceOfBeingErnest从提供解决方案的意义上说,你的答案很清楚,但是我真的想理解为什么我的逻辑是错误的,也就是说,这些命令背后发生了什么。