numpy Matplotlib动画在几帧后冻结或无法工作

ukqbszuj  于 2023-06-06  发布在  其他
关注(0)|答案(8)|浏览(190)

我已经花了几个小时来尝试让这个简单的脚本工作,但我所做的一切似乎都没有帮助。这是对Matplotlib网站上最基本的动画情节示例代码的轻微修改,应该只显示几帧噪声(顺便说一句,我对他们网站上未经修改的代码也有同样的问题)。
在我的电脑与TkAgg后端我得到约20帧(出60)之前,绘图窗口冻结。使用Qt 4Agg,我只得到一个冻结的黑色窗口,没有绘制任何帧。我尝试了不同NumPy,PyQt,Python和Matplotlib版本的多种组合,但总是得到相同的结果。
请让我知道这是否对你有用,或者如果有什么看起来不对劲。我很确定这在过去确实有效,所以我认为这可能是Windows问题或与ion()相关的问题。
仅供参考,我使用的是Windows 7(32位),我已经测试了Python 2.6/2.7,MPL 1.0.0/0.9.9.8,PyQt 4.6/4.7,Numpy 1.4/1.5b。

import matplotlib
matplotlib.use('TkAgg') # Qt4Agg gives an empty, black window
from pylab import *
import time

ion()
hold(False)

# create initial plot
z = zeros(10)
line, = plot(z)
ylim(-3, 3)

for i in range(60):
    print 'frame:', i

    d = randn(10)
    line.set_ydata(d)

    draw()
    time.sleep(10e-3)

这个更简单的版本在第一对帧之后也会冻结:

from pylab import *

ion()
hold(False)

for i in range(40):
    plot(randn(10))
    draw()

show()

谢谢!

编辑:这些人似乎和我有相同或相似的问题:

  • mail-archive.com/matplotlib-users@lists.sourceforge.net/msg10844.html
  • stackoverflow.com/questions/2604119/matplotlib-pyplot-pylab-not-updating-figure-while-isinteractive-using-ipython
  • mail-archive.com/matplotlib-users@lists.sourceforge.net/msg01283.html

看起来他们中的任何一个人都无法修复它:(

hpxqektj

hpxqektj1#

通常你不能像这样使用show()和draw()。正如帖子所建议的,你需要一个小的GUI循环,只要看看Matplotlib页面上的动画示例就可以了。

n6lpvg4x

n6lpvg4x2#

经过几个小时的努力,我想我已经找到了答案:要使用matplotlib来做这些简单的动画,你可以使用GTKAgg后端。这在scipy食谱中是作为一句话说的,但我认为应该更清楚地强调这一点。当我使用它,我可以运行你的动画,直到结束没有冻结或任何其他问题。
注意,要使用这个后端,你需要安装PyGTK。我不知道你在Windows上还需要什么(因为我在Linux上),但这似乎是最低限度的。此外,如果你想在默认情况下使用它,你必须将这一行添加到你的matplotlibrc(在Linux上放置在~/.matplotlib/matplotlibrc):

backend      : GTKAgg

要使用其他后端,你需要遵循官方的matplotlib examples,但这意味着你必须构建一个迷你gui应用程序来运行一个简单的动画,我觉得这很糟糕!

esyap4oy

esyap4oy3#

我为这个问题挣扎了很长一段时间。我建议看看这个例子:http://matplotlib.sourceforge.net/examples/animation/strip_chart_demo.html
我以为我完全遵循了这个例子,但它没有工作。它只会运行一次“更新”功能。原来我的代码中唯一的区别是animation.FuncAnimation()没有赋值给变量。只要我将animation.FuncAnimation()的返回值赋给一个值,一切都正常了。

k7fdbhmy

k7fdbhmy4#

我有(我想)同样的麻烦,如果我把焦点从窗口上移开或试图拖动它,窗口会冻结,在Windows 7上使用Python 2.7和Matplotlib 1.3,以及TKAgg后端。我在主while循环中调用了time.sleep(1),当我用plt.pause(1)替换它时,问题就解决了。所以,尝试使用matplotlib的pause函数而不是time模块的sleep函数,它对我很有效。

uxhixvfz

uxhixvfz5#

调用time.sleep()或plt.pause()会在使用blitting时导致图形窗口 Flink ,但我通过简单地显式调用事件循环获得了良好的结果:

fig.canvas.blit() # or draw()
fig.canvas.start_event_loop(0.001) #1 ms seems enough
uklbhaso

uklbhaso6#

来自未来的问候
下面是你在Python 3中如何做到这一点:

import matplotlib
matplotlib.use('TkAgg') # Qt4Agg gives an empty, black window
import matplotlib.pylab as plt
import time

# create initial plot
z = zeros(10)
line, = plot(z)
ylim(-3, 3)

for i in range(60):
    print('frame:', i)

    d = randn(10)
    line.set_ydata(d)
    draw()
    #replace time.sleep() with plt.pause()
    plt.pause(0.5)

我摆脱了对ion()hold(False)的调用。我还将time.sleep替换为plt.pause

bpzcxfmw

bpzcxfmw7#

通常,GUI框架需要“拥有”程序的主循环。在一个紧密的循环中,通过休眠来延迟迭代通常会“破坏”GUI应用程序(您的问题描述与这些方面的典型破坏是一致的)。有可能matplotlib开发人员已经实现了一些幕后逻辑来防止这些锁定发生在某些工具包上,但是稍微调整一下你的程序应该可以消除mainloop所有权成为问题的任何机会(我认为这是非常可能的)。Matplotlib动画wiki还建议对任何重要的内容使用本机事件循环(可能是出于这个原因)
我建议您使用GUI工具包在一定的延迟之后调度函数调用,而不是坐在sleeps的循环中。

def update_function():
    # do frame calculation here

refresh_timer = QtCore.QTimer()
QtCore.QObject.connect( refresh_timer, QtCore.SIGNAL('timeout()'), update_function )
refresh_timer.start( 1.0 / 30 ) # have update_function called at 30Hz

查看matplotlib文档表明,可以原生地使用它们的API,但我无法通过快速搜索找到任何好的示例。

jk9hmnmh

jk9hmnmh8#

当你说在前几帧后冻结时,你的意思是2帧或3帧,或者说,40帧或60帧,因为这些是你的循环的上限?
如果你想让动画无限期地持续下去,你需要像这样的东西

while True:
    d = randn(10)
    line.set_ydata(d)
    draw()
    time.sleep(10e-3)

但你必须强制退出程序。

相关问题