22

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

在 python 3(带有 matplotlib git build ... 版本 1.2.x 的 python 3.2.3)中,这工作正常。作为一个简单的例子(通过 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)

在 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)

但是,这也不起作用。同样,它运行干净但不显示图形。似乎只有在等待用户输入时才会这样做。我不清楚这是为什么,但是当将 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()

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

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

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

谢谢; 我将不胜感激任何帮助...

4

2 回答 2

23

您希望该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'

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

文档:

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.

一个真正过度杀戮的方法是使用matplotlib.animate模块。另一方面,如果需要,它为您提供了一种保存数据的好方法(摘自我对Python-1 second plots continuous presentation的回答)。

例子api教程

于 2012-10-10T18:48:11.587 回答
2

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

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

于 2015-03-20T02:05:59.133 回答