Matplotlib 动画要么在几帧后冻结,要么根本不起作用

发布于 2024-09-13 04:28:41 字数 1603 浏览 2 评论 0原文

我已经尝试了几个小时来让这个简单的脚本正常工作,但我所做的似乎都没有帮助。它是对 Matplotlib 网站上最基本的动画绘图示例代码的轻微修改,应该只显示几帧噪音(顺便说一句,我对其网站上未修改的代码也有同样的问题)。

在我的带有 TkAgg 后端的计算机上,在绘图窗口冻结之前,我得到了大约 20 帧(共 60 帧)。使用 Qt4Agg 我只会得到一个冻结的黑色窗口,并且根本没有绘制任何帧。我尝试了不同 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()

谢谢!

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

没有看起来他们中的任何一个都能够修复它:(

I've been trying for hours to get this simple script working, but nothing I do seems to help. It's a slight modification of the most basic animated plot sample code from the Matplotlib website, that should just show a few frames of noise (I have the same issue with the unmodified code from their website BTW).

On my computer with the TkAgg backend I get about 20 frames (out of 60) before the plot window freezes. With Qt4Agg I just get a frozen, black window and no frames at all are plotted. I've tried multiple combinations of different NumPy, PyQt, Python and Matplotlib versions, but always get the same result.

Please let me know if this works for you or if anything looks wrong. I'm pretty sure this did work in the past, so I'm thinking it may be a Windows issue or something related to ion().

FYI I'm using Windows 7 (32 bit) and I've tested with 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)

This simpler version also freezes after the first couple frames:

from pylab import *

ion()
hold(False)

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

show()

Thanks!

EDIT: These people seem to be having the same or a similar problem as me:

  • mail-archive.com/[email protected]/msg10844.html
  • stackoverflow.com/questions/2604119/matplotlib-pyplot-pylab-not-updating-figure-while-isinteractive-using-ipython
  • mail-archive.com/[email protected]/msg01283.html

Doesn't look like any of them were able to fix it either :(

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

反差帅 2024-09-20 04:28:41

通常,GUI 框架需要“拥有”程序的主循环。坐在紧密循环中并通过睡眠来延迟迭代通常会“破坏”GUI 应用程序(您的问题描述与这些方面的典型破坏一致)。 matplotlib 开发人员可能已经实现了一些幕后逻辑,以防止某些工具包发生这些锁定,但稍微重组您的程序应该可以消除主循环所有权成为问题的任何可能性(这非常我很可能)思考)。 matplotlib 动画wiki 还建议对任何不平凡的事情使用本机事件循环(可能由于这个原因)

我建议您不要坐在睡眠循环中,而是使用 GUI 工具包在一定的延迟后安排函数调用。

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,但我无法通过快速搜索找到任何好的示例。

Typically, GUI frameworks need to 'own' the main loop of the program. Sitting in a tight loop with sleeps to delay iterations will usually 'break' GUI applications (your problem description is consistent with typical breakage along these lines). It's possible that the matplotlib devs have implemented some behind the scenes logic to pevent these lockups from happening for certain toolkits but restructuring your program slightly should eliminate any chance of mainloop ownership being the problem (which is very likely I think). The matplotlib animation wiki also suggests using native event loops for anything nontrivial (probably for this reason)

Rather than sitting in a loop with sleeps, I suggest that, instead, you use the GUI toolkit to schedule a function call after a certain delay.

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

Looking at the matplotlib documentation suggests that it may be possible to use their API natively but I couldn't find any good examples using just a quick search.

野侃 2024-09-20 04:28:41

经过几个小时与同一问题的斗争,我想我已经找到了答案:要使用 matplotlib 制作这些简单的动画,您可以使用GTKAgg后端。这是 scipy Cookbook 中的一个顺便评论,但我认为应该强调得更清楚。当我使用它时,我可以运行你的动画直到最后,而不会出现冻结或任何其他问题。

请注意,要使用此后端,您需要安装 PyGTK。我不知道 Windows 上还需要什么(因为我使用的是 Linux),但这似乎是最低要求。此外,如果你想默认使用它,你必须将此行添加到你的 matplotlibrc 中(在 Linux 上放置在 ~/.matplotlib/matplotlibrc 上):

backend      : GTKAgg

要使用其他后端,你需要遵循官方 matplotlib 示例,但这意味着您必须构建一个迷你 GUI 应用程序才能运行简单的动画,并且我觉得那很糟糕!

After many hours fighting with this same issue I think I've found the answer: To do these simple animations with matplotlib you can only use the GTKAgg backend. This is stated as a passing remark in the scipy cookbook, but I think it should be stressed more clearly. When I use it, I can run your animations until the end without freezes or any other problem.

Beware that to use this backend you need to install PyGTK. I don't know what else you need on Windows (because I'm on Linux) but that seems the minimum. Besides, if you want to use it by default you have to add this line to your matplotlibrc (on Linux placed on ~/.matplotlib/matplotlibrc):

backend      : GTKAgg

To use the other backends you need to follow the official matplotlib examples, but that means you have to build a mini-gui application just to run a simple animation, and I find that quite awful!

半世晨晓 2024-09-20 04:28:41

当您说在前几帧后冻结时,您的意思是 2 或 3,或者说 40 或 60,因为这些是循环的上限?

如果您希望动画无限期地继续,您需要类似的内容

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

,但您必须强制退出程序。

When you say freezes after the first couple of frames do you mean 2 or 3, or say, 40 or 60, as those are the upper limits of your loop?

If you want the animation to continue indefinitely you need something like

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

But you'll have to force quit your program.

诗化ㄋ丶相逢 2024-09-20 04:28:41

一般来说你不能像这样使用show()和draw()。正如帖子所建议的,您需要一个小的 GUI 循环,只需查看 Matplotlib 页面上的动画示例即可。

Generally you can't use show() and draw() like this. As the Posts are suggesting, you need a small GUI loop, just look at the Animations examples on the Matplotlib page.

记忆之渊 2024-09-20 04:28:41

我在同样的问题上挣扎了很长一段时间。我建议看一下这个例子: http://matplotlib.sourceforge.net/examples /animation/strip_chart_demo.html

我以为我完全遵循了这个示例,但它不起作用。它只会运行一次“更新”功能。结果我的代码中唯一的区别是 animation.FuncAnimation() 没有分配给变量。一旦我将 animation.FuncAnimation() 的返回值分配给一个值,一切就正常了。

I was struggling with this same problem for quite a while. I would recommend taking a look at this example: http://matplotlib.sourceforge.net/examples/animation/strip_chart_demo.html

I thought I was following this example exactly, but it wasn't working. It would only run the "update" function one time. Turns out the only difference in my code was that the animation.FuncAnimation() was not assigned to a variable. As soon as I assigned the return value of animation.FuncAnimation() to a value, everything worked.

诗酒趁年少 2024-09-20 04:28:41

我也遇到了(我认为)同样的问题,如果我将焦点从窗口上移开或尝试拖动它,在 Windows 7 上使用 Python 2.7 和 Matplotlib 1.3 以及 TKAgg 后端,窗口就会冻结。我在主 while 循环中调用了 time.sleep(1) ,当我用 plt.pause(1) 替换它时,问题就解决了。因此,尝试使用 matplotlib 的暂停函数而不是时间模块睡眠函数,它对我有用。

I was having (I think) the same trouble, where the window would freeze if I took the focus off it or tried to drag it around, using Python 2.7 on Windows 7 with Matplotlib 1.3, and TKAgg backend. I had a call to time.sleep(1) in my main while loop, and when I replaced that with plt.pause(1), that fixed the problem. So, try and use matplotlib's pause function rather than time module sleep function, it worked for me.

街道布景 2024-09-20 04:28:41

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

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

calling time.sleep() or plt.pause() causes flicker on the graph window when using blitting, but I got good results by simply calling the event loop explicitely :

fig.canvas.blit() # or draw()
fig.canvas.start_event_loop(0.001) #1 ms seems enough
山川志 2024-09-20 04:28:41

来自未来的问候。

下面是在 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) 的调用。我还用 plt.pause 替换了 time.sleep

greetings from the future.

Here's how you'd do it in 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)

I got rid of the call to ion() and hold(False). I also replaced time.sleep with plt.pause

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文