在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"
我错过了非常基本的东西吗?
答案 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...')
然而,这只是表面上的事情 - 一旦你开始想要在与情节互动的同时做背景工作,就会出现许多复杂情况。这是使用基本上是状态机的绘画的自然结果,它在面向对象的环境中与线程和编程不能很好地协作。
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上很长一段时间了,值upgrading为matplotlib
因为有{{3}来到v1.0版本,包括 Bugfix marathon ,以及对show()
行为的重大更改。
答案 1 :(得分:2)
最简单的解决方案可能是使用IPython作为你的python shell。使用-pylab选项运行它。
ipython -pylab