在Python解释器中的这些指令之后,你会看到一个带有图形的窗口:

from matplotlib.pyplot import *
plot([1,2,3])
show()
# other code

不幸的是,我不知道如何在程序进行进一步计算时继续交互式地探索show()创建的图形。

这可能吗?有时计算很长,如果在检查中间结果时进行计算将会有所帮助。


当前回答

我还希望我的图显示运行其余的代码(然后继续显示),即使出现错误(我有时使用图进行调试)。我编写了这个小代码,让这个with语句中的任何plot都像这样。

这可能有点太非标准了,不适合用于生产代码。这段代码中可能有很多隐藏的“陷阱”。

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

如果/当我实现了一个适当的“保持图打开(即使发生错误)并允许显示新的图”,我希望脚本在没有用户干扰的情况下正确退出(用于批处理执行)。

我可能会使用超时问题“脚本结束!”\nPress p如果你想要绘图输出暂停(你有5秒):" from https://stackoverflow.com/questions/26704840/corner-cases-for-my-wait-for-user-input-interruption-implementation。

其他回答

您可能需要阅读matplotlib文档中的这个文档,标题为:

在python shell中使用matplotlib

最好总是检查您正在使用的库是否支持以非阻塞的方式使用。

但是如果你想要一个更通用的解决方案,或者如果没有其他方法,你可以通过使用python中包含的多处理模块来运行任何在分离进程中阻塞的东西。计算将继续:

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的非阻塞API调用)

如果你在控制台工作,即IPython,你可以使用plt.show(block=False),正如在其他答案中指出的那样。但如果你很懒,你可以输入:

plt.show(0)

这是一样的。

在我的系统上,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)

尽管脚本仍然在运行。

在我的例子中,我希望在计算窗口时弹出几个窗口。作为参考,方法如下:

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接口指南。