在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()创建的图形。
这可能吗?有时计算很长,如果在检查中间结果时进行计算将会有所帮助。
当前回答
嗯,我在搞清楚非阻塞命令方面遇到了很大的困难……但最后,我成功地重做了“Cookbook/Matplotlib/Animations -动画选定的绘图元素”的例子,所以它可以在Ubuntu 10.04的Python 2.6.5上与线程一起工作(并通过全局变量或多进程管道在线程之间传递数据)。
脚本可以在这里找到:Animating_selected_plot_elements-thread.py -否则粘贴在下面(注释更少)以供参考:
import sys
import gtk, gobject
import matplotlib
matplotlib.use('GTKAgg')
import pylab as p
import numpy as nx
import time
import threading
ax = p.subplot(111)
canvas = ax.figure.canvas
# for profiling
tstart = time.time()
# create the initial line
x = nx.arange(0,2*nx.pi,0.01)
line, = ax.plot(x, nx.sin(x), animated=True)
# save the clean slate background -- everything but the animated line
# is drawn and saved in the pixel buffer background
background = canvas.copy_from_bbox(ax.bbox)
# just a plain global var to pass data (from main, to plot update thread)
global mypass
# http://docs.python.org/library/multiprocessing.html#pipes-and-queues
from multiprocessing import Pipe
global pipe1main, pipe1upd
pipe1main, pipe1upd = Pipe()
# the kind of processing we might want to do in a main() function,
# will now be done in a "main thread" - so it can run in
# parallel with gobject.idle_add(update_line)
def threadMainTest():
global mypass
global runthread
global pipe1main
print "tt"
interncount = 1
while runthread:
mypass += 1
if mypass > 100: # start "speeding up" animation, only after 100 counts have passed
interncount *= 1.03
pipe1main.send(interncount)
time.sleep(0.01)
return
# main plot / GUI update
def update_line(*args):
global mypass
global t0
global runthread
global pipe1upd
if not runthread:
return False
if pipe1upd.poll(): # check first if there is anything to receive
myinterncount = pipe1upd.recv()
update_line.cnt = mypass
# restore the clean slate background
canvas.restore_region(background)
# update the data
line.set_ydata(nx.sin(x+(update_line.cnt+myinterncount)/10.0))
# just draw the animated artist
ax.draw_artist(line)
# just redraw the axes rectangle
canvas.blit(ax.bbox)
if update_line.cnt>=500:
# print the timing info and quit
print 'FPS:' , update_line.cnt/(time.time()-tstart)
runthread=0
t0.join(1)
print "exiting"
sys.exit(0)
return True
global runthread
update_line.cnt = 0
mypass = 0
runthread=1
gobject.idle_add(update_line)
global t0
t0 = threading.Thread(target=threadMainTest)
t0.start()
# start the graphics update thread
p.show()
print "out" # will never print - show() blocks indefinitely!
希望这能帮助到一些人, 干杯!
其他回答
在许多情况下,将图像保存为硬盘上的.png文件会更方便。原因如下:
优点:
在这个过程中,你可以随时打开、查看和关闭它。当应用程序运行较长时间时,这尤其方便 时间。 什么都不会弹出,你也不会被迫打开窗户。这在处理许多数字时特别方便。 您的图像可用于以后的参考,并且在关闭图形窗口时不会丢失。
缺点:
我唯一能想到的是,你将不得不去查找文件夹,并打开自己的图像。
使用plt.show(block=False),并在脚本的末尾调用plt.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
使用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()
我所发现的最佳解决方案是,程序不会等待您关闭图形,并将所有的图放在一起,以便您可以并排检查它们,这是在最后显示所有的图。 但是通过这种方式,您不能在程序运行时检查图。
# stuff
numFig = 1
plt.figure(numFig)
numFig += 1
plt.plot(x1, y1)
# other stuff
plt.figure(numFig)
numFig += 1
plt.plot(x2, y2)
# more stuff
plt.show()