pylab.ion() 在 python 2、matplotlib 1.1.1 和程序运行时更新绘图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12822762/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 11:56:21  来源:igfitidea点击:

pylab.ion() in python 2, matplotlib 1.1.1 and updating of the plot while the program runs

pythonmatplotlib

提问by 0range

what I am trying to do is having a script compute something, prepare a plot and show the already obtained results as a pylab.figure - in python 2 (specifically python 2.7) with a stable matplotlib (which is 1.1.1).

我想要做的是让脚本计算一些东西,准备一个绘图并将已经获得的结果显示为 pylab.figure - 在具有稳定 matplotlib(即 1.1.1)的 python 2(特别是 python 2.7)中。

In python 3 (python 3.2.3 with a matplotlib git build ... version 1.2.x), this works fine. As a simple example (simulating a lengthy computation by time.sleep()) consider

在 python 3(python 3.2.3 with a matplotlib git build ... version 1.2.x)中,这很好用。作为一个简单的例子(通过 time.sleep() 模拟一个冗长的计算)考虑

import pylab
import time
import random

dat=[0,1]
pylab.plot(dat)
pylab.ion()
pylab.draw()    
for i in range (18):
    dat.append(random.uniform(0,1))
    pylab.plot(dat)
    pylab.draw()
    time.sleep(1)

In python 2 (version 2.7.3 vith matplotlib 1.1.1), the code runs cleanly without errors but does not show the figure. A little trial and error with the python2 interpreter seemed to suggest to replace pylab.draw() with pylab.show(); doing this once is apparently sufficient (not, as with draw calling it after every change/addition to the plot). Hence:

在 python 2(版本 2.7.3 vith matplotlib 1.1.1)中,代码运行干净没有错误,但没有显示图。对 python2 解释器的一些尝试和错误似乎建议用 pylab.show() 替换 pylab.draw(); 这样做一次显然就足够了(不是,就像在每次更改/添加绘图后绘制调用它一样)。因此:

import pylab
import time
import random

dat=[0,1]
pylab.plot(dat)
pylab.ion()
pylab.show()    
for i in range (18):
    dat.append(random.uniform(0,1))
    pylab.plot(dat)
    #pylab.draw()
    time.sleep(1)

However, this doesn't work either. Again, it runs cleanly but does not show the figure. It seems to do so only when waiting for user input. It is not clear to me why this is, but the plot is finally shown when a raw_input() is added to the loop

但是,这也不起作用。同样,它运行得很干净,但没有显示图。似乎只有在等待用户输入时才会这样做。我不清楚为什么会这样,但是当 raw_input() 添加到循环中时,最终会显示该图

import pylab
import time
import random

dat=[0,1]
pylab.plot(dat)
pylab.ion()
pylab.show()    
for i in range (18):
    dat.append(random.uniform(0,1))
    pylab.plot(dat)
    #pylab.draw()
    time.sleep(1)
    raw_input()

With this, the script will of course wait for user input while showing the plot and will not continue computing the data before the user hits enter. This was, of course, not the intention.

有了这个,脚本当然会在显示绘图时等待用户输入,并且在用户点击输入之前不会继续计算数据。这当然不是本意。

This may be caused by different versions of matplotlib (1.1.1 and 1.2.x) or by different python versions (2.7.3 and 3.2.3).

这可能是由不同版本的 matplotlib(1.1.1 和 1.2.x)或不同的 Python 版本(2.7.3 和 3.2.3)引起的。

Is there any way to accomplish with python 2 with a stable (1.1.1) matplotlib what the above script (the first one) does in python 3, matplotlib 1.2.x: - computing data (which takes a while, in the above example simulated by time.sleep()) in a loop or iterated function and - (while still computing) showing what has already been computed in previous iterations - and not bothering the user to continually hit enter for the computation to continue

有什么方法可以用稳定的 (1.1.1) matplotlib 来完成 python 2 上面的脚本(第一个)在 python 3,matplotlib 1.2.x 中所做的: - 计算数据(这需要一段时间,在上面的例子中)由 time.sleep()) 在循环或迭代函数中模拟,并且 - (同时仍在计算)显示在之前的迭代中已经计算的内容 - 并且不会打扰用户不断点击 Enter 以继续计算

Thanks; I'd appreciate any help...

谢谢; 我很感激任何帮助...

采纳答案by tacaswell

You want the pausefunction to give the gui framework a chance to re-draw the screen:

您希望该pause函数为 gui 框架提供重新绘制屏幕的机会:

import pylab
import time
import random
import matplotlib.pyplot as plt

dat=[0,1]
fig = plt.figure()
ax = fig.add_subplot(111)
Ln, = ax.plot(dat)
ax.set_xlim([0,20])
plt.ion()
plt.show()    
for i in range (18):
    dat.append(random.uniform(0,1))
    Ln.set_ydata(dat)
    Ln.set_xdata(range(len(dat)))
    plt.pause(1)

    print 'done with loop'

You don't need to create a new Line2Dobject every pass through, you can just update the data in the existing one.

您不需要Line2D每次通过都创建一个新对象,您只需更新现有对象中的数据即可。

Documentation:

文档:

pause(interval)
    Pause for *interval* seconds.

    If there is an active figure it will be updated and displayed,
    and the gui event loop will run during the pause.

    If there is no active figure, or if a non-interactive backend
    is in use, this executes time.sleep(interval).

    This can be used for crude animation. For more complex
    animation, see :mod:`matplotlib.animation`.

    This function is experimental; its behavior may be changed
    or extended in a future release.

A really over-kill method to is to use the matplotlib.animatemodule. On the flip side, it gives you a nice way to save the data if you want (ripped from my answer to Python- 1 second plots continous presentation).

一个真正过头的方法是使用matplotlib.animate模块。另一方面,如果您愿意,它为您提供了一种保存数据的好方法(从我对Python 的回答中摘录 - 1 秒绘图连续演示)。

example, api, tutorial

示例, api,教程

回答by hunse

Some backends (in my experience "Qt4Agg") require the pausefunction, as @tcaswell suggested.

pause正如@tcaswell 建议的那样,某些后端(以我的经验为“Qt4Agg”)需要该功能。

Other backends (in my experience "TkAgg") seem to just update on draw()without requiring a pause. So another solution is to switch your backend, for example with matplotlib.use('TkAgg').

其他后端(以我的经验为“TkAgg”)似乎只是更新draw()而不需要pause. 所以另一个解决方案是切换你的后端,例如使用matplotlib.use('TkAgg').