在Python解释器中的这些指令之后,会得到一个带有绘图的窗口:
from matplotlib.pyplot import *
plot([1,2,3])
show()
# other code
不幸的是,我不知道在程序进行进一步计算时如何继续以show()
的形式继续交互式探索图形。
有可能吗?有时计算很长,如果他们在检查中间结果期间继续进行计算会有所帮助。
答案 0 :(得分:190)
使用不会阻止的matplotlib
来电:
使用draw()
:
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()
答案 1 :(得分:120)
使用关键字“block”来覆盖阻止行为,例如
from matplotlib.pyplot import show, plot
plot(1)
show(block=False)
# your code
继续你的代码。
答案 2 :(得分:29)
如果它支持以非阻止方式使用,最好始终检查您正在使用的库。
但是如果你想要一个更通用的解决方案,或者没有其他方法,你可以使用python中包含的multprocessing
模块运行在分离进程中阻塞的任何东西。计算将继续:
from multiprocessing import Process
from matplotlib.pyplot import plot, show
def plot_graph(*args):
for data in args:
plot(data)
show()
p = Process(target=plot_graph, args=([1, 2, 3],))
p.start()
print 'yay'
print 'computation continues...'
print 'that rocks.'
print 'Now lets wait for the graph be closed to continue...:'
p.join()
这有启动新流程的开销,有时在复杂的情况下难以调试,所以我更喜欢其他解决方案(使用matplotlib
的{{3}})
答案 3 :(得分:21)
尝试
from matplotlib.pyplot import *
plot([1,2,3])
show(block=False)
# other code
# [...]
# Put
show()
# at the very end of your script
# to make sure Python doesn't bail out
# before you finished examining.
在非交互模式下,显示所有数字并阻止,直到数字关闭为止;在交互模式下,除非在从非交互模式更改为交互模式之前创建数字(不推荐),否则它无效。在这种情况下,它会显示数字,但不会阻止。
单个实验性关键字参数
block
可以设置为True
或False
,以覆盖上述阻止行为。
答案 4 :(得分:10)
您可能希望在matplotlib
的文档中阅读此文档,标题为:
答案 5 :(得分:8)
就我而言,我想在计算时弹出几个窗口。作为参考,这是方式:
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()
PS。非常有用的guide to matplotlib's OO interface。
答案 6 :(得分:7)
重要:只是为了说清楚。我假设命令在.py
脚本中,并且使用例如调用脚本来调用脚本。来自控制台的python script.py
。
对我有用的一个简单方法是:
script.py
文件的示例:
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()
答案 7 :(得分:6)
好吧,我很难搞清楚非阻塞命令......但最后,我设法重做“Cookbook/Matplotlib/Animations - Animating selected plot elements”示例,因此它适用于线程(并在线程之间传递数据)在Ubuntu 10.04上的Python 2.6.5上通过全局变量或通过多进程Pipe
)。
可以在此处找到该脚本: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!
希望这有助于某人,
干杯!
答案 8 :(得分:5)
在许多情况下,将图像保存为硬盘驱动器上的.png文件会更加方便。原因如下:
<强>优点:强>
<强>缺点:强>
答案 9 :(得分:5)
如果您在控制台中工作,即IPython
,则可以使用其他答案中指出的plt.show(block=False)
。但如果你很懒,你可以输入:
plt.show(0)
这将是相同的。
答案 10 :(得分:3)
我还希望我的绘图显示运行其余代码(然后继续显示),即使出现错误(我有时会使用绘图进行调试)。我编写了这个小小的hack,以便这个with
语句中的任何一个图都表现如此。
这可能有点过于标准,不适用于生产代码。可能有很多隐藏的&#34;陷阱&#34;在这段代码中。
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
如果/当我实施正确的&#34;保持图表打开(即使发生错误)并允许显示新的图表#34;,如果没有用户干扰告诉它,我希望脚本正确退出否则(用于批量执行)。
我可能会使用类似超时问题的内容&#34;脚本结束! \ n如果你想让绘图输出暂停(你有5秒),请按p:&#34;来自https://stackoverflow.com/questions/26704840/corner-cases-for-my-wait-for-user-input-interruption-implementation。
答案 11 :(得分:3)
我还必须在代码中添加plt.pause(0.001)
以使其在for循环中正常工作(否则它只显示第一个和最后一个绘图):
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)
答案 12 :(得分:2)
在我的系统上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)
虽然脚本仍在运行。
答案 13 :(得分:2)
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
答案 14 :(得分:1)
在我看来,这个主题中的答案提供的方法不适用于每个系统以及动画等更复杂的情况。我建议在下面的线程中查看MiKTeX的答案,其中找到了一个健壮的方法: How to wait until matplotlib animation ends?
答案 15 :(得分:0)
如果你想打开多个数字,同时保持全部打开,这段代码对我有用:
show(block=False)
draw()
答案 16 :(得分:0)
OP要求分离matplotlib
地块。大多数答案都假定命令是从python解释器中执行的。此处提供的用例是我偏爱在运行file.py
的终端(例如bash)中测试代码,并且希望绘制图,但是python脚本完成并返回命令提示。
此独立文件使用multiprocessing
启动一个单独的过程,用于使用matplotlib
绘制数据。主线程使用this中提到的os._exit(1)
退出。 os._exit()
强制main退出,但使matplotlib
子进程处于活动状态并作出响应,直到关闭绘图窗口。完全是一个单独的过程。
这种方法有点像Matlab开发会话,其中包含带有响应式命令提示符的图形窗口。使用这种方法,您已经失去了与图形窗口过程的所有联系,但是,可以进行开发和调试。只需关闭窗口并继续测试即可。
multiprocessing
设计用于仅执行python的代码,这使其可能比subprocess
更适用。 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
答案 17 :(得分:0)
使用plt.show(block=False)
,并在脚本结束时调用plt.show()
。
这将确保脚本完成后不会关闭窗口。
答案 18 :(得分:0)
虽然没有直接回答OP的请求,但我发布了此替代方法,因为它可能会在这种情况下帮助某些人:
为此Im使用:
answer
其中“ var”标识循环中的图,因此不会被覆盖。
答案 19 :(得分:0)
我的回答有点离题,但是由于这个问题中提到的问题,我只是决定摆脱应用程序中的matplotlib。
或者,您可以使用plotly。它不会阻止该过程。