在Python 2中,使用matplotlib 1.1.1版本时,pylab.ion()的作用是在程序运行时更新图表。

22
我试图做的是让一个脚本计算一些东西,准备绘制并显示已经获得的结果作为一个pylab.figure - 在Python 2(具体来说是Python 2.7)中使用稳定的matplotlib(即1.1.1)。
在Python 3中(带有matplotlib git构建...版本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)
在Python 2(版本为2.7.3,带有matplotlib 1.1.1)中,该代码可以干净地运行而不出现错误,但不显示图形。在Python2解释器中进行少量试验和错误似乎表明需要用pylab.show()替换pylab.draw();只需执行一次即可(不像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)引起的。
是否有办法在Python 2中使用稳定的(1.1.1)matplotlib实现上述Python 3、matplotlib 1.2.x中脚本的功能: - 在循环或迭代函数中计算数据(这需要一段时间,在上面的示例中通过time.sleep()模拟),并且 - (同时仍在计算中)显示已经在先前迭代中计算出的内容 - 而且不必让用户不断按回车键才能进行计算
谢谢;任何帮助都将不胜感激...
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 continous presentation)。 示例API教程

2

根据我的经验,一些后端(例如“Qt4Agg”)需要使用pause函数,正如@tcaswell所建议的那样。

其他后端(例如“TkAgg”)似乎只在draw()上更新而不需要pause。因此,另一个解决方案是切换您的后端,例如使用matplotlib.use('TkAgg')


TkAgg也需要一个暂停。(在Mac上,截至撰写本文的当前版本) - wedi
TkAgg在Ubuntu 16.04下也需要暂停。 - Fanta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接