在matplotlib中,有没有办法异步弹出一个数字?

时间:2011-02-19 13:19:39

标签: matplotlib

在matplotlib中,是否有一种简单的方法可以在不中断脚本控制流的情况下绘制图形?

为了清晰起见使用伪代码,这是我正在努力实现的目标:

fig1 = figure()
fig1.plot_a_figure(datasets)

for dataset in datasets:
   results = analyze(dataset)    # this takes several minutes
   update(fig1)
   pop_up_another_figure(results) # would like to have a look at this one
                                  # while the next dataset is being processed

当然,我可以保存这些中间数字,但我只需要快速浏览一下它们,最好让它们实时弹出屏幕。

编辑:一个可运行的例子:

#!/usr/bin/python
import pylab as plb
import matplotlib.pyplot as plt

fig1=plt.figure(1)
ax = fig1.add_subplot(1,1,1)

ax.plot([1,2,3],[4,5,6],'ro-')

#fig1.show()  # this does not show a figure if uncommented
plt.show()    # until the plot window is closed, the next line is not executed

print "doing something else now"

我错过了非常基本的东西吗?

2 个答案:

答案 0 :(得分:13)

首先,不要忘记一个简单的替代方法就是使用plt.figure(2)plt.figure(3)等创建新的数字窗口。如果您真的想要更新现有的数字窗口,最好保留你的线对象上的句柄

h = ax.plot([1,2,3],[4,5,6],'ro-')

然后你会做类似的事情:

h[0].set_data(some_new_results)
ax.figure.canvas.draw()

至于问题的真正含义,如果你还在努力阅读这篇文章......


如果您希望plt.show()无阻塞,则需要启用交互模式。要修改您的可运行示例,以便立即打印“立即执行其他操作”,而不是等待图窗口关闭,以下操作将会执行以下操作:

#!/usr/bin/python
import pylab as plb
import matplotlib.pyplot as plt

fig1=plt.figure(1)
ax = fig1.add_subplot(1,1,1)

ax.plot([1,2,3],[4,5,6],'ro-')

#fig1.show()  # this does not show a figure if uncommented
plt.ion()     # turns on interactive mode
plt.show()    # now this should be non-blocking

print "doing something else now"
raw_input('Press Enter to continue...')

然而,这只是表面上的事情 - 一旦你开始想要在与情节互动的同时做背景工作,就会出现许多复杂情况。这是使用基本上是状态机的绘画的自然结果,它在面向对象的环境中与线程和编程不能很好地协作。

  • 昂贵的计算必须进入工作线程(或者进入子进程)以避免冻结GUI。
  • Queue应该用于传递输入数据并以线程安全的方式从工作函数中获取结果。
  • 根据我的经验,在工作线程中调用draw()是不安全的,因此您还需要设置一种方法来安排重绘。
  • 不同的后端可能会开始做奇怪的事情,TkAgg似乎是唯一一个100%工作的人(见here)。

最简单和最好的解决方案不是使用vanilla python解释器,而是使用ipython -pylab(正如ianalis正确建议的那样),因为他们已经找到了使交互式工作顺利进行所需的大部分技巧。它可以在没有ipython / pylab的情况下完成,但这是一项大量的额外工作。

注意:我仍然经常喜欢在使用ipython和pyplot GUI窗口时修剪工作线程,并且为了使线程顺利运行,我还需要使用另一个命令行参数ipython -pylab -wthread。我python 2.7.1+ matplotlib v1.1.0,您的里程可能会有所不同。希望这有帮助!

Ubuntu用户的注意事项:存储库现在仍然在v0.99上很长一段时间了,值upgradingmatplotlib因为有{{3}来到v1.0版本,包括 Bugfix marathon ,以及对show()行为的重大更改。

答案 1 :(得分:2)

最简单的解决方案可能是使用IPython作为你的python shell。使用-pylab选项运行它。

ipython -pylab