使用matplotlib在python中制作多个动画

使用matplotlib在python中制作多个动画,python,matplotlib,animation,Python,Matplotlib,Animation,我想使用matplotlib的动画功能来显示和保存多个动画。以前,我只是使用pyplot在每一步都有一个短暂的停顿来伪造动画,但我没有找到将这些“动画”保存为视频的方法,所以我改用真实动画。以下是我启动时代码的虚拟版本(将运行): 从matplotlib导入pyplot作为plt 将numpy作为np导入 班级走廊: 定义初始化(自): self.end_pos=5 self.cur\u pos=0 def设置(自): self.cur\u pos=0 def go(自我决定): 如果decis

我想使用matplotlib的动画功能来显示和保存多个动画。以前,我只是使用pyplot在每一步都有一个短暂的停顿来伪造动画,但我没有找到将这些“动画”保存为视频的方法,所以我改用真实动画。以下是我启动时代码的虚拟版本(将运行):

从matplotlib导入pyplot作为plt
将numpy作为np导入
班级走廊:
定义初始化(自):
self.end_pos=5
self.cur\u pos=0
def设置(自):
self.cur\u pos=0
def go(自我决定):
如果decision==0且self.cur\u pos>0:
self.cur_pos-=1
elif决策==1:
self.cur_pos+=1
完成=self.cur\u pos>=self.end\u pos
返回完成
def绘图(自身,图):
图clear()
ax=图gca()
ax.set(xlim=(-0.5,5.5),ylim=(-0.5,0.5))
最大散射(自电流位置,0,s=350)
plt.draw()
plt.暂停(0.01)
sim=走廊()
对于范围(5)内的num_sim:
打印(“运行模拟{}”。格式(num_sim))
sim.setup()
模拟绘图(plt.gcf())
尽管如此:
done=sim.go(np.random.randint(0,2))
模拟绘图(plt.gcf())
如果这样做:
打破
#在此处保存动画
此处需要注意的关键事项:

  • 使用
    go
  • 使用
    draw
  • “完成”条件指示模拟应在何时结束
  • 一旦动画结束,我想保存它,但我们还没有完成!保存动画后,我想启动一个新的。这将在外循环中发生5次
  • 所以我改变了我的代码,这样我可以使用一个动画对象,这就是现在的情况:

    从matplotlib导入pyplot作为plt
    从matplotlib.animation导入FuncAnimation
    将numpy作为np导入
    班级走廊:
    定义初始化(自):
    self.end_pos=5
    self.cur\u pos=0
    def设置(自):
    self.cur\u pos=0
    def go(自我决定):
    如果decision==0且self.cur\u pos>0:
    self.cur_pos-=1
    elif决策==1:
    self.cur_pos+=1
    完成=self.cur\u pos>=self.end\u pos
    返回完成
    def绘图(自身,图):
    图clear()
    ax=图gca()
    ax.set(xlim=(-0.5,5.5),ylim=(-0.5,0.5))
    最大散射(自电流位置,0,s=350)
    plt.draw()
    plt.暂停(0.01)
    sim=走廊()
    对于范围(5)内的num_sim:
    打印(“运行模拟{}”。格式(num_sim))
    sim.setup()
    全部完成=错误
    图=plt.图()
    def gen_frame_until_done():#使用生成器生成帧,只要没有全部完成
    全球一切就绪
    i=0
    虽然并非所有工作都已完成:
    i+=1
    产量一
    def animate(i):#animate函数代替while循环
    模拟绘图(图)
    done=sim.go(np.random.randint(0,2))
    如果这样做:
    全球一切就绪
    全部完成=正确
    模拟绘图(图)
    anim=FuncAnimation(图,动画,帧=gen\u frame\u,直到完成,重复=False)
    plt.show()
    #动画保存(…)
    
    这将运行,但它不会给我我想要的。它将只显示一个动画,终端将显示运行模拟0的
    。当触发
    all_done
    且模拟结束时,程序将等待我退出绘图窗口。一旦退出,程序将继续进行下一次模拟并重复

    我不喜欢这样,我必须手动退出窗口。通过将阻塞
    plt.show()
    替换为

    plt.show(block=False)
    plt.暂停(3)
    plt.close()
    
    这将允许程序继续,而无需手动退出窗口。但是,在继续下一个动画之前,只允许显示3秒钟的动画

    我想要的是:

    • 我希望能够显示模拟,直到模拟结束。当它结束时,我希望窗口自动关闭
    • 我希望下一个模拟在上一个动画窗口之后运行一个新的动画窗口

    同样,我使用动画对象是因为我需要能够将动画保存为视频。但是如果有其他方法可以做到这一点,我肯定会接受。

    如果在
    animate
    函数的
    if done
    子句中添加
    plt.close()
    调用,绘图窗口将在模拟完成时关闭,下一个窗口将在下一次模拟时打开

    为了使下一个动画不需要与鼠标进行任何交互,我们还需要将
    block=False
    添加到
    plt.show
    ;我们可以检查
    all_done
    是否为真,如果动画没有完成,
    plt.pause()

    例如:

    for num_sim in range(5):
        print("running simulation {}".format(num_sim))
        sim.setup()
        all_done = False
        fig = plt.figure()
    
        def gen_frame_until_done(): # Using a generator to give me frames as long as not all_done
            global all_done
            i = 0
            while not all_done:
                i += 1
                yield i
        
        def animate(i): # Animate function takes the place of the while loop
            sim.draw(fig)
            done = sim.go(np.random.randint(0,2))
            if done:
                global all_done
                all_done = True
                sim.draw(fig)
                plt.close(fig)
        
        anim = FuncAnimation(fig, animate, frames=gen_frame_until_done, repeat=False)
        
        plt.show(block=False)
        while all_done is False:
            plt.pause(1)
    

    谢谢你的回复!这是一个很大的帮助。但这对我来说并不完全有效,因为动画将播放单个模拟,然后窗口将关闭。然后它就会结冰。它不会继续下一个动画,除非我以某种方式与计算机交互,即单击鼠标或移动鼠标。如果我只是坐着看,它会播放动画,关上窗户,然后它似乎在等我做什么。。。在Mac 10.14上运行。6@KindaTechy你是对的。我想我的编辑通过在
    plt.show()
    的末尾设置
    block=False
    ,然后对照
    all_done
    来确定是否需要暂停@tmdavison!这解决了我的问题。我希望我能更好地理解plt是如何工作的,这样我就能更好地理解这段代码是如何运行的。。。这里我只需要注意,我必须将anim.save(…)函数放在plt.show(block=False)之上,否则我无法保存和渲染。