inal(例如bash),其中运行file.py,您希望打印出来,但python脚本需要完成并返回到命令提示符
此独立文件使用inal(例如bash),其中运行file.py,您希望打印出来,但python脚本需要完成并返回到命令提示符,python,matplotlib,plot,Python,Matplotlib,Plot,此独立文件使用多处理启动一个单独的进程,用于使用matplotlib打印数据。主线程使用后文中提到的os.\u exit(1)退出。os.\u exit()强制退出main,但使matplotlib子进程处于活动状态并响应,直到绘图窗口关闭。这是一个完全独立的过程 这种方法有点像Matlab开发会话,其中的图形窗口提供了响应命令提示符。使用这种方法,您已经失去了与figure window进程的所有联系,但是,这对于开发和调试来说是可以的。只需关闭窗口并继续测试 多处理是专为纯python代码执
多处理
启动一个单独的进程,用于使用matplotlib
打印数据。主线程使用后文中提到的os.\u exit(1)
退出。os.\u exit()
强制退出main,但使matplotlib
子进程处于活动状态并响应,直到绘图窗口关闭。这是一个完全独立的过程
这种方法有点像Matlab开发会话,其中的图形窗口提供了响应命令提示符。使用这种方法,您已经失去了与figure window进程的所有联系,但是,这对于开发和调试来说是可以的。只需关闭窗口并继续测试
多处理
是专为纯python代码执行而设计的,这使得它可能比子进程
更适合<代码>多处理是跨平台的,因此它在Windows或Mac中应该可以很好地工作,几乎不需要调整。无需检查底层操作系统。这是在linux Ubuntu18.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
会弹出一个图形窗口,然后退出\uuuuu main\uuuuuu
,但多处理
+matplotlib
图形窗口会使用缩放、平移和其他按钮保持响应,因为它是一个独立的进程
使用以下命令检查bash命令提示符下的进程:
ps ax | grep-v grep | grep file.py
使用plt.show(block=False)
,并在脚本结束时调用plt.show()
这将确保脚本完成后窗口不会关闭。虽然不直接回答OPs请求,但我会发布此解决方案,因为它可能会在这种情况下帮助某些人:
- 我正在使用pyinstaller创建一个.exe,因为我无法在需要生成绘图的地方安装python,所以我需要python脚本来生成绘图,将其另存为.png,关闭它并继续下一个,作为循环中的几个绘图或使用函数来实现
为此,我使用:
import matplotlib.pyplot as plt
#code generating the plot in a loop or function
#saving the plot
plt.savefig(var+'_plot.png',bbox_inches='tight', dpi=250)
#you can allways reopen the plot using
os.system(var+'_plot.png') # unfortunately .png allows no interaction.
#the following avoids plot blocking the execution while in non-interactive mode
plt.show(block=False)
#and the following closes the plot while next iteration will generate new instance.
plt.close()
其中“var”标识循环中的绘图,因此它不会被覆盖。我的答案有点离题,但我决定在我的应用程序中避开matplotlib,因为这个问题中说明了一个问题
或者,您可以使用。它不会阻止此过程。谢谢!因为我的系统上还没有Python 2.6,所以我使用threading.Thread作为进程的替代品。我观察到随后的打印语句变得慢得令人无法忍受(第三次打印,我在等待1分钟后发出键盘中断)。这是使用线程而不是多重处理的结果吗?@Metore:是的,线程很糟糕。您总是可以使用python进行多处理,这绝对是非常棒的。你知道为什么打印语句在Emacs(python模式)下直到绘图窗口关闭时才执行吗?在Ubuntu 8.10(Intrepid)中,包(对于python,你没有错过如果uuuuu name_uuuuu=='uuu main_uuuu':
?对于matplotlib 0.98.3,正确的导入来自matplotlib.pyplot导入plot,draw,showdraw()
对我不起作用,它不会打开任何窗口。但是使用show(block=False)
而不是draw()
似乎在matplotlib 1.1中做到了这一点。@nosklo,你看到了吗?你把它做成了python@noskolo。如果我有几个图,如何在继续背景的同时绘制和显示图1?我希望这个图一直打开,直到生成下一个图,所以最后我打开了所有图,代码就完成了解决方案,它让我等待关闭图1,然后代码继续。谢谢!!draw()
对我也不起作用,只是pause(0.001)
did:我无法确认16:52从nosklo选择的解决方案是否有效。对于我来说,draw不会打开窗口显示绘图,只有最后的阻止显示解决方案。但是,他17:00的回答是正确的。通过ion()打开交互模式
解决了这个问题。如果你是一名高级程序员,你可以使用os.fork()
,但请记住,使用os.fork()
可能会很棘手,因为你是通过复制旧进程来创建一个新进程。谢谢!Spyder在启动时导入-pylab,这通常很有用,但在ioff()时,means show()不会阻塞-这允许您修复此行为!但这将立即关闭绘图窗口,不会保持绘图打开。是的,如果您从命令行调用脚本,这是正确的。如果您在Ipython shell中,窗口将不会关闭。请检查@Nico的答案,了解在一般情况下会保持窗口打开的技巧。对我来说,这不会关闭只有脚本完成后,窗口才会立即关闭(因此,如果您希望脚本保持打开状态,可以在脚本末尾手动阻止)。是的,当脚本退出时,未阻止的窗口将关闭。您可以(a)允许阻止上一次绘图,或(b)不退出脚本(可能要求输入:“按以退出绘图”或者类似的东西)。如果你试图生成大量图像,我完全同意。缩回png不是交互式的:\show(block=False)已被弃用,现在不再有效为什么不使用draw();[.other code];show()?据我所知,block=False已被弃用为什么你认为它已被弃用?我看到它被记录在案。在存在之前,如何按enter键?这对我在macOS上的matplotlib3是有效的。太好了!请看@nico schlömer的回答我试图使用你的解决方案,但它似乎对我不起作用,我正在试图找出原因。我没有跑步通过终端但从Pycharm IDE读取代码,如果这有什么区别的话,尽管它不应该这样做。好的,最终对我有效的是将子进程设置为de。daemon=False
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()
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!
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
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)
from matplotlib.pyplot import show, plot
plot(1)
show(block=False)
# your code
from contextlib import contextmanager
@contextmanager
def keep_plots_open(keep_show_open_on_exit=True, even_when_error=True):
'''
To continue excecuting code when plt.show() is called
and keep the plot on displaying before this contex manager exits
(even if an error caused the exit).
'''
import matplotlib.pyplot
show_original = matplotlib.pyplot.show
def show_replacement(*args, **kwargs):
kwargs['block'] = False
show_original(*args, **kwargs)
matplotlib.pyplot.show = show_replacement
pylab_exists = True
try:
import pylab
except ImportError:
pylab_exists = False
if pylab_exists:
pylab.show = show_replacement
try:
yield
except Exception, err:
if keep_show_open_on_exit and even_when_error:
print "*********************************************"
print "Error early edition while waiting for show():"
print "*********************************************"
import traceback
print traceback.format_exc()
show_original()
print "*********************************************"
raise
finally:
matplotlib.pyplot.show = show_original
if pylab_exists:
pylab.show = show_original
if keep_show_open_on_exit:
show_original()
# ***********************
# Running example
# ***********************
import pylab as pl
import time
if __name__ == '__main__':
with keep_plots_open():
pl.figure('a')
pl.plot([1,2,3], [4,5,6])
pl.plot([3,2,1], [4,5,6])
pl.show()
pl.figure('b')
pl.plot([1,2,3], [4,5,6])
pl.show()
time.sleep(1)
print '...'
time.sleep(1)
print '...'
time.sleep(1)
print '...'
this_will_surely_cause_an_error
plt.show(0)
show(block=False)
draw()
import matplotlib.pyplot as plt
plt.scatter([0], [1])
plt.draw()
plt.show(block=False)
for i in range(10):
plt.scatter([i], [i+1])
plt.draw()
plt.pause(0.001)
plt.figure(1)
plt.imshow(your_first_image)
plt.figure(2)
plt.imshow(your_second_image)
plt.show(block=False) # That's important
raw_input("Press ENTER to exist") # Useful when you run your Python script from the terminal and you want to hold the running to see your figures until you press Enter
plt.imshow(*something*)
plt.colorbar()
plt.xlabel("true ")
plt.ylabel("predicted ")
plt.title(" the matrix")
# Add block = False
plt.show(block = False)
################################
# OTHER CALCULATIONS AND CODE HERE ! ! !
################################
# the next command is the last line of my script
plt.show()
#!/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
import matplotlib.pyplot as plt
#code generating the plot in a loop or function
#saving the plot
plt.savefig(var+'_plot.png',bbox_inches='tight', dpi=250)
#you can allways reopen the plot using
os.system(var+'_plot.png') # unfortunately .png allows no interaction.
#the following avoids plot blocking the execution while in non-interactive mode
plt.show(block=False)
#and the following closes the plot while next iteration will generate new instance.
plt.close()