Matplotlib视频创建 [英] Matplotlib video creation

查看:33
本文介绍了Matplotlib视频创建的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ImportanceOfBeingErnest 提供了答案,但我仍然邀请大家解释,为什么 savefig 逻辑与 animation 逻辑不同.

我想在 matplotlib 中制作视频.我浏览了手册和示例,但我只是不明白.(关于matplotlib,我一直都是抄例子,因为python 5年,mathplotlib 2年,matplotlib的语法我还是懂0.0%)

六个小时后,我想到了这里.好吧,我得到空的视频.不知道为什么.

导入操作系统导入数学导入 matplotlibmatplotlib.use("Agg")从 matplotlib 导入 pyplot 作为 plt导入matplotlib.animation作为动画#设置电影文件的格式作家= animation.writers ['ffmpeg']作家=作家(fps = 15,元数据= dict(艺术家='我'),比特率= 1800)麻木=100温度=[0.0]*麻木继续= [0.0] *麻木对于范围内的 i(int(4*numb/10),int(6*numb/10)):temp [i] = 2续[i]=2无花果= 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 = []对于范围内的 i (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在这里进行测试,效果很好!# fig.savefig('test'+str(i)+'.png', bbox_inches='tight', dpi=300)ims.append([line1,line2])plts.lines.remove(line1)plts.lines.remove(line2)对于范围(1,10)中的j:tempa = 0对于范围内的 k (1,numb-1):tempb=temp[k]+0.51*(temp[k-1]-2*temp[k]+temp[k+1])temp [k-1] = tempa温度=温度temp [numb-1] = 0对于范围(1,20)中的j:接触=0对于范围内的 k (1,numb-1):contb=cont[k]+0.255*(cont[k-1]-2*cont[k]+cont[k+1])cont[k-1]=contaconta=contbcont [numb-1] = 0im_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)

如果删除这两行,输出将如下所示

[

解决方案要么是运行两次脚本,一次用于动画,另一次是在每个时间步中删除线条.或者,也许更好,使用动画本身来创建图像.

im_ani.save('im.png', writer="imagemagick")

将在当前文件夹中将图像创建为 im-< nr> .png .它需要安装 imagemagick.

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

1..在删除它们之前,我先添加了line1和line2.他们仍然消失在最终结果中.怎么会来?

您已将这些行附加到列表中.之后,您从轴上删除了线条.现在,这些线在列表中,但不是轴的一部分.制作动画时,matplotlib在列表中找到线并使其可见.但是它们不在轴中(因为它们已被删除),因此某些Line2D对象的可见性发生了变化,该对象不在任何轴中,而仅在内存中的某个位置.但这并没有反映在情节中,因为情节不再知道这条线.

2. 如果我理解正确,当您发出 line1, = plts.plot... 命令时,line1 绘图对象将添加到 plts 图形对象中.但是,如果您通过再次发出 line1, = plts.plot... 命令更改 line1 绘图对象,matplotlib 确实更改 line1 对象,但在此之前会将旧 line1 永久保存到 plts 图形对象.这是我的问题的原因吗?

没有.第一步是正确的,line1, = plts.plot(..) 将 Line2D 对象添加到坐标区.但是,在随后的循环步骤 line1中,= plts.plot()创建另一个 Line2D对象并将其放置在画布上.初始 Line2D 对象未更改,并且它不知道绘图中现在旁边还有其他一些线.因此,如果不删除这些线,它们将全部显示在最后的静态图中.

EDIT: ImportanceOfBeingErnest provided the answer, however I am still inviting you all to explain, why is savefig logic different from animation logic.

I want to make a video in matplotlib. I went through manuals and examples and I just don't get it. (regarding matplotlib, I always copy examples, because after five years of python and two years of mathplotlib I still understand 0.0% of matplotlib syntax)

After half a dozen hours here is what I came up to. Well, I get empty video. No idea why.

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)

Can someone help me with this?

解决方案

If you want to have a plot which is not empty, the main idea would be not to remove the lines from the plot.

That is, delete the two lines

plts.lines.remove(line1)
plts.lines.remove(line2)

If you delete these two lines the output will look something like this

[Link to orginial size animation]

Now one might ask, why do I not need to remove the artist in each iteration step, as otherwise all of the lines would populate the canvas at once?

The answer is that the ArtistAnimation takes care of this. It will only show those artists in the supplied list that correspond to the given time step. So while at the end of the for loop you end up with all the lines drawn to the canvas, once the animation starts they will all be removed and only one set of artists is shown at a time.

In such a case it is of course not a good idea to use the loop for saving the individual images as the final image would contain all of the drawn line at once,

The solution is then either to make two runs of the script, one for the animation, and one where the lines are removes in each timestep. Or, maybe better, use the animation istself to create the images.

im_ani.save('im.png', writer="imagemagick") 

will create the images as im-<nr>.png in the current folder. It will require to have imagemagick installed.


I'm trying here to answer the two questions from the comments:

1. I have appended line1 and line2 before deleting them. Still they disappeared in the final result. How come?

You have appended the lines to a list. After that you removed the lines from the axes. Now the lines are in the list but not part of the axes. When doing the animation, matplotlib finds the lines in the list and makes them visible. But they are not in the axes (because they have been removed) so the visibility of some Line2D object, which does not live in any axes but only somewhere in memory, is changed. But that isn't reflected in the plot because the plot doesn't know this line any more.

2. If I understand right, when you issue line1, = plts.plot... command then the line1 plot object is added to the plts graph object. However, if you change the line1 plot object by issuing line1, = plts.plot... command again, matplotlib does change line1 object but before that saves the old line1 to the plts graph object permanently. Is this what caused my problem?

No. The first step is correct, line1, = plts.plot(..) adds a Line2D object to the axes. However, in a later loop step line1, = plts.plot() creates another Line2D object and puts it to the canvas. The initial Line2D object is not changed and it doesn't know that there is now some other line next to it in the plot. Therefore, if you don't remove the lines they will all be visible in the static plot at the end.

这篇关于Matplotlib视频创建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆