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

ev-*_*-br 14 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
Run Code Online (Sandbox Code Playgroud)

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

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

#!/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"
Run Code Online (Sandbox Code Playgroud)

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

wim*_*wim 14

首先第一件事情,不要忘了一个简单的办法是只让新的数字窗户plt.figure(2),plt.figure(3)等等.如果你真的想更新现有的数字窗口,你最好保持一个手柄上的线条与对象

h = ax.plot([1,2,3],[4,5,6],'ro-')
Run Code Online (Sandbox Code Playgroud)

然后你会做类似的事情:

h[0].set_data(some_new_results)
ax.figure.canvas.draw()
Run Code Online (Sandbox Code Playgroud)

至于问题的真正含义,如果你还在努力解读这个问题......


如果要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...')
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

注意Ubuntu用户:该库仍然回到v0.99现在相当长的一段时间,这是值得升级matplotlib,因为有很多的改进上来的V1.0版本包括bug修正马拉松,以及行为的重大变化show().