在Python解释器中的这些指令之后,你会看到一个带有图形的窗口:
from matplotlib.pyplot import *
plot([1,2,3])
show()
# other code
不幸的是,我不知道如何在程序进行进一步计算时继续交互式地探索show()创建的图形。
这可能吗?有时计算很长,如果在检查中间结果时进行计算将会有所帮助。
在Python解释器中的这些指令之后,你会看到一个带有图形的窗口:
from matplotlib.pyplot import *
plot([1,2,3])
show()
# other code
不幸的是,我不知道如何在程序进行进一步计算时继续交互式地探索show()创建的图形。
这可能吗?有时计算很长,如果在检查中间结果时进行计算将会有所帮助。
当前回答
OP询问分离matplotlib图。大多数回答假设从python解释器中执行命令。这里给出的用例是我对在终端(例如bash)中测试代码的偏好,在终端中运行file.py,并且您希望出现绘图,但python脚本完成并返回命令提示符。
这个独立文件使用多处理启动一个单独的进程,用matplotlib绘制数据。主线程使用本文中提到的os._exit(1)退出。os._exit()强制main退出,但在plot窗口关闭之前,matplotlib子进程仍然活跃并保持响应。这是一个完全独立的过程。
这种方法有点像带有图形窗口的Matlab开发会话,会产生响应式命令提示符。使用这种方法,您将失去与图形窗口进程的所有联系,但是,这对于开发和调试来说是可以的。只需关闭窗口并继续测试。
多处理是专为python代码执行而设计的,这使得它可能比子进程更适合。multiprocessing是跨平台的,所以这应该在Windows或Mac上工作得很好,很少或没有调整。不需要检查底层操作系统。这是在linux Ubuntu 18.04LTS上测试的。
#!/usr/bin/python3
import time
import multiprocessing
import os
def plot_graph(data):
from matplotlib.pyplot import plot, draw, show
print("entered plot_graph()")
plot(data)
show() # this will block and remain a viable process as long as the figure window is open
print("exiting plot_graph() process")
if __name__ == "__main__":
print("starting __main__")
multiprocessing.Process(target=plot_graph, args=([1, 2, 3],)).start()
time.sleep(5)
print("exiting main")
os._exit(0) # this exits immediately with no cleanup or buffer flushing
运行file.py会弹出一个图形窗口,然后__main__退出,但是multiprocessing + matplotlib图形窗口仍然对缩放、平移和其他按钮有响应,因为它是一个独立的进程。
在bash命令提示符下检查进程:
Ps ax|grep -v grep |grep file.py
其他回答
在我的系统上,show()没有阻塞,尽管我希望脚本在继续之前等待用户与图形交互(并使用'pick_event'回调来收集数据)。
为了阻止执行直到绘图窗口关闭,我使用了以下方法:
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.plot(x,y)
# set processing to continue when window closed
def onclose(event):
fig.canvas.stop_event_loop()
fig.canvas.mpl_connect('close_event', onclose)
fig.show() # this call does not block on my system
fig.canvas.start_event_loop_default() # block here until window closed
# continue with further processing, perhaps using result from callbacks
但是请注意,canvas.start_event_loop_default()产生了以下警告:
C:\Python26\lib\site-packages\matplotlib\backend_bases.py:2051: DeprecationWarning: Using default event loop until function specific to this GUI is implemented
warnings.warn(str,DeprecationWarning)
尽管脚本仍然在运行。
下面是我找到的最简单的解决方案(线程阻塞代码)
plt.show(block=False) # this avoids blocking your thread
plt.pause(1) # comment this if you do not want a time delay
# do more stuff
plt.show(block=True) # this prevents the window from closing on you
使用matplotlib调用不会阻塞:
使用画():
from matplotlib.pyplot import plot, draw, show
plot([1,2,3])
draw()
print('continue computation')
# at the end call show to ensure window won't close.
show()
使用交互模式:
from matplotlib.pyplot import plot, ion, show
ion() # enables interactive mode
plot([1,2,3]) # result shows immediatelly (implicit draw())
print('continue computation')
# at the end call show to ensure window won't close.
show()
在我的例子中,我希望在计算窗口时弹出几个窗口。作为参考,方法如下:
from matplotlib.pyplot import draw, figure, show
f1, f2 = figure(), figure()
af1 = f1.add_subplot(111)
af2 = f2.add_subplot(111)
af1.plot([1,2,3])
af2.plot([6,5,4])
draw()
print 'continuing computation'
show()
一个非常有用的matplotlib的OO接口指南。
在我看来,这个帖子中的答案提供的方法并不适用于每个系统和更复杂的情况,如动画。我建议在下面的帖子中看看MiKTeX的答案,在那里找到了一个健壮的方法: 如何等待matplotlib动画结束?