如何为Matplotlib图的时间顺序动画
image
image-processing
python
5
0

我想在matplotlib中绘制一系列.png图像。目的是快速绘制它们以模拟电影的效果,但是我还有其他原因想要避免实际创建.avi文件或保存matplotlib图形,然后在Python之外按顺序查看它们。

我专门尝试在Python的for循环中依次查看图像文件。假设我已经正确导入了matplotlib,并且我有自己的函数'new_image()'和'new_rect()',这是一些示例代码,因为show()函数对GUI主循环的调用会产生阻塞作用,因此它们无法工作:

 for index in index_list:
     img = new_image(index)
     rect = new_rect(index)

     plt.imshow(img)
     plt.gca().add_patch(rect)
     plt.show()

     #I also tried pausing briefly and then closing, but this doesn't
     #get executed due to the GUI mainloop from show()
     time.sleep(0.25)
     plt.close()

上面的代码仅显示第一个图像,但随后程序挂起并等待我手动关闭生成的图形窗口。一旦我关闭它,程序便会挂起,并且不会重新绘制新的图像数据。我该怎么办?还要注意,我尝试用plt.draw()命令替换plt.show()命令,然后在for循环外添加plt.show()。这不会显示任何内容,只会挂起。

参考资料:
Stack Overflow
收藏
评论
共 2 个回答
高赞 时间 活跃

基于http://matplotlib.sourceforge.net/examples/animation/simple_anim_tkagg.html

import time
import numpy as np
import matplotlib
matplotlib.use('TkAgg') # do this before importing pylab

import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)

def animate():
    tstart = time.time()                   # for profiling
    data=np.random.randn(10,10)
    im=plt.imshow(data)

    for i in np.arange(1,200):
        data=np.random.randn(10,10)
        im.set_data(data)
        fig.canvas.draw()                         # redraw the canvas
    print 'FPS:' , 200/(time.time()-tstart)

win = fig.canvas.manager.window
fig.canvas.manager.window.after(100, animate)
plt.show()

plt.imshow可以接受float数组,uint8数组或PIL图像。因此,如果您有PNG文件的目录,则可以将其作为PIL图像打开并进行动画处理,如下所示:

import matplotlib
matplotlib.use('TkAgg') # do this before importing pylab
import matplotlib.pyplot as plt
import Image
import glob

fig = plt.figure()
ax = fig.add_subplot(111)

def animate():
    filenames=sorted(glob.glob('*.png'))
    im=plt.imshow(Image.open(filenames[0]))
    for filename in filenames[1:]:
        image=Image.open(filename)
        im.set_data(image)
        fig.canvas.draw() 

win = fig.canvas.manager.window
fig.canvas.manager.window.after(100, animate)
plt.show()
收藏
评论

我为此找到的最好方法是在导入pylab之后使用命令pylab.ion()

这是一个确实使用show()的脚本,但是每次调用pylab.draw()pylab.draw()显示不同的图,并且使图窗口无限期地显示。它使用简单的输入逻辑来决定何时关闭图形(因为使用show()意味着pylab不会处理Windows x按钮上的点击),但是作为另一个按钮或文本字段添加到gui中应该很简单。

import numpy as np
import pylab
pylab.ion()

def get_fig(fig_num, some_data, some_labels):

    fig = pylab.figure(fig_num,figsize=(8,8),frameon=False)
    ax = fig.add_subplot(111)
    ax.set_ylim([0.1,0.8]); ax.set_xlim([0.1, 0.8]);
    ax.set_title("Quarterly Stapler Thefts")
    ax.pie(some_data, labels=some_labels, autopct='%1.1f%%', shadow=True);
    return fig

my_labels = ("You", "Me", "Some guy", "Bob")

# To ensure first plot is always made.
do_plot = 1; num_plots = 0;

while do_plot:
    num_plots = num_plots + 1;
    data = np.random.rand(1,4).tolist()[0]

    fig = get_fig(num_plots,data,my_labels)
    fig.canvas.draw()
    pylab.draw()

    print "Close any of the previous plots? If yes, enter its number, otherwise enter 0..."
    close_plot = raw_input()

    if int(close_plot) > 0:
        pylab.close(int(close_plot))

    print "Create another random plot? 1 for yes; 0 for no."
    do_plot = raw_input();

    # Don't allow plots to go over 10.
    if num_plots > 10:
        do_plot = 0

pylab.show()

通过在这里修改基本逻辑,我可以让它关闭窗口并连续绘制图像以模拟电影的播放,或者我可以保持键盘控制它如何逐步移动电影。

注意:这对我在所有平台上都有效,并且似乎完全优于上面的窗口画布管理器方法,并且不需要'TkAgg'选项。

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号