有没有一种方法可以分离matplotlib图,以便继续计算?

问题:有没有一种方法可以分离matplotlib图,以便继续计算?

在Python解释器中执行了这些指令后,将获得一个带有绘图的窗口:

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

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

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

After these instructions in the Python interpreter one gets a window with a plot:

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

Unfortunately, I don’t know how to continue to interactively explore the figure created by show() while the program does further calculations.

Is it possible at all? Sometimes calculations are long and it would help if they would proceed during examination of intermediate results.


回答 0

使用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()

Use matplotlib‘s calls that won’t block:

Using 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()

Using interactive mode:

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

使用关键字“ block”来覆盖阻止行为,例如

from matplotlib.pyplot import show, plot

plot(1)  
show(block=False)

# your code

继续您的代码。

Use the keyword ‘block’ to override the blocking behavior, e.g.

from matplotlib.pyplot import show, plot

plot(1)  
show(block=False)

# your code

to continue your code.


回答 2

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

但是,如果您需要更通用的解决方案,或者没有其他方法,则可以使用multprocessingpython中包含的模块运行在单独的进程中阻塞的任何内容。计算将继续:

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调用

It is better to always check with the library you are using if it supports usage in a non-blocking way.

But if you want a more generic solution, or if there is no other way, you can run anything that blocks in a separated process by using the multprocessing module included in python. Computation will continue:

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()

That has the overhead of launching a new process, and is sometimes harder to debug on complex scenarios, so I’d prefer the other solution (using matplotlib‘s nonblocking API calls)


回答 3

尝试

import matplotlib.pyplot as plt
plt.plot([1,2,3])
plt.show(block=False)
# other code
# [...]

# Put
plt.show()
# at the very end of your script to make sure Python doesn't bail out
# before you finished examining.

show()文档说:

在非交互模式下,显示所有图形并阻止直到图形被关闭;在交互模式下,除非在从非交互模式更改为交互模式之前创建图形(不推荐),否则它无效。在这种情况下,它会显示数字,但不会阻止。

可以将单个实验性关键字参数block设置为True或False,以覆盖上述阻止行为。

Try

import matplotlib.pyplot as plt
plt.plot([1,2,3])
plt.show(block=False)
# other code
# [...]

# Put
plt.show()
# at the very end of your script to make sure Python doesn't bail out
# before you finished examining.

The show() documentation says:

In non-interactive mode, display all figures and block until the figures have been closed; in interactive mode it has no effect unless figures were created prior to a change from non-interactive to interactive mode (not recommended). In that case it displays the figures but does not block.

A single experimental keyword argument, block, may be set to True or False to override the blocking behavior described above.


回答 4

重要提示:只是为了澄清一些内容。我假设命令在.py脚本中,并且使用例如python script.py从控制台调用脚本。

一个对我有用的简单方法是:

  1. 在show中使用block = False:plt.show(block = False)
  2. 在.py脚本的末尾使用另一个 show()。

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()

IMPORTANT: Just to make something clear. I assume that the commands are inside a .py script and the script is called using e.g. python script.py from the console.

A simple way that works for me is:

  1. Use the block = False inside show : plt.show(block = False)
  2. Use another show() at the end of the .py script.

Example of script.py file:

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()


回答 5

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

在python shell中使用matplotlib

You may want to read this document in matplotlib‘s documentation, titled:

Using matplotlib in a python shell


回答 6

就我而言,我想在计算窗口时弹出几个窗口。供参考,方法如下:

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。关于matplotlib的OO接口的非常有用的指南

In my case, I wanted to have several windows pop up as they are being computed. For reference, this is the way:

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. A quite useful guide to matplotlib’s OO interface.


回答 7

好吧,我很难弄清非阻塞命令.​​..但是最后,我设法重做了“ Cookbook / Matplotlib / Animations-动画选定的绘图元素 ”示例,因此它可以与线程一起使用(并在线程之间传递数据通过全局变量或通过multiprocessPipe)(在Ubuntu 10.04上的Python 2.6.5上)。

可以在以下位置找到该脚本:Animating_selected_plot_elementsthread.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! 

希望这对某人有帮助,
干杯!

Well, I had great trouble figuring out the non-blocking commands… But finally, I managed to rework the “Cookbook/Matplotlib/Animations – Animating selected plot elements” example, so it works with threads (and passes data between threads either via global variables, or through a multiprocess Pipe) on Python 2.6.5 on Ubuntu 10.04.

The script can be found here: Animating_selected_plot_elements-thread.py – otherwise pasted below (with fewer comments) for reference:

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! 

Hope this helps someone,
Cheers!


回答 8

在许多情况下,将图像另存为.png文件到硬盘驱动器上更为方便。原因如下:

优点:

  • 您可以在过程中随时打开,查看和关闭它。当您的应用程序长时间运行时,这特别方便。
  • 什么都不会弹出,也不用强迫您打开窗户。当您处理许多数字时,这特别方便。
  • 您的图像可供访问以供以后参考,并且在关闭图形窗口时不会丢失。

退税:

  • 我唯一能想到的是,您将必须去查找文件夹并自己打开图像。

In many cases it is more convenient til save the image as a .png file on the hard drive. Here is why:

Advantages:

  • You can open it, have a look at it and close it down any time in the process. This is particularly convenient when your application is running for a long time.
  • Nothing pops up and you are not forced to have the windows open. This is particularly convenient when you are dealing with many figures.
  • Your image is accessible for later reference and is not lost when closing the figure window.

Drawback:

  • The only thing I can think of is that you will have to go and finder the folder and open the image yourself.

回答 9

如果您在控制台中工作,即IPython可以使用plt.show(block=False)其他答案中指出的方法。但是,如果您很懒,则可以键入:

plt.show(0)

会是一样的。

If you are working in console, i.e. IPython you could use plt.show(block=False) as pointed out in the other answers. But if you’re lazy you could just type:

plt.show(0)

Which will be the same.


回答 10

我还必须添加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)

I had to also add plt.pause(0.001) to my code to really make it working inside a for loop (otherwise it would only show the first and last plot):

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)

回答 11

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

尽管脚本仍在运行。

On my system show() does not block, although I wanted the script to wait for the user to interact with the graph (and collect data using ‘pick_event’ callbacks) before continuing.

In order to block execution until the plot window is closed, I used the following:

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

Note, however, that canvas.start_event_loop_default() produced the following warning:

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)

although the script still ran.


回答 12

我还希望我的绘图显示运行其余代码(然后继续显示),即使有错误(我有时使用绘图进行调试)。我编写了这个小技巧,以便该with语句中的所有图都具有相同的表现。

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

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

如果/当我实施适当的“使绘图保持打开状态(即使发生错误)并允许显示新绘图”时,我希望脚本在没有用户干预的情况下正确退出(出于批处理目的)。

我可能会使用类似超时问题的“脚本结尾!\ n如果您想中止绘图输出(您有5秒钟),请按 p:“,来自/programming/26704840/corner我的情况下等待用户输入中断的实现

I also wanted my plots to display run the rest of the code (and then keep on displaying) even if there is an error (I sometimes use plots for debugging). I coded up this little hack so that any plots inside this with statement behave as such.

This is probably a bit too non-standard and not advisable for production code. There is probably a lot of hidden “gotchas” in this 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

If/when I implement a proper “keep the plots open (even if an error occurs) and allow new plots to be shown”, I would want the script to properly exit if no user interference tells it otherwise (for batch execution purposes).

I may use something like a time-out-question “End of script! \nPress p if you want the plotting output to be paused (you have 5 seconds): ” from https://stackoverflow.com/questions/26704840/corner-cases-for-my-wait-for-user-input-interruption-implementation.


回答 13

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.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

OP询问有关拆除matplotlib地块的问题。大多数答案都假定命令是从python解释器中执行的。此处提供的用例是我偏爱在运行a的终端(例如bash)中测试代码,file.py并且您希望绘制图但python脚本完成并返回命令提示符。

此独立文件用于multiprocessing启动一个单独的过程,以使用绘制数据matplotlib。主线程退出使用os._exit(1)中提到的这个职位。的os._exit()主要退出,但叶势力matplotlib子进程还活着,直到响应关闭绘图窗口。完全是一个单独的过程。

这种方法有点像Matlab开发会话,其中包含带有响应命令提示符的图形窗口。使用这种方法,您已经失去了与图形窗口过程的所有联系,但是,可以进行开发和调试。只需关闭窗口并继续测试即可。

multiprocessing专为仅python代码执行而设计,这使其可能比更加适合subprocessmultiprocessing是跨平台的,因此几乎不需要调整就可以在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

The OP asks about detatching matplotlib plots. Most answers assume command execution from within a python interpreter. The use-case presented here is my preference for testing code in a terminal (e.g. bash) where a file.py is run and you want the plot(s) to come up but the python script to complete and return to a command prompt.

This stand-alone file uses multiprocessing to launch a separate process for plotting data with matplotlib. The main thread exits using the os._exit(1) mentioned in this post. The os._exit() forces main to exit but leaves the matplotlib child process alive and responsive until the plot window is closed. It’s a separate process entirely.

This approach is a bit like a Matlab development session with figure windows that come up with a responsive command prompt. With this approach, you have lost all contact with the figure window process, but, that’s ok for development and debugging. Just close the window and keep testing.

multiprocessing is designed for python-only code execution which makes it perhaps better suited than subprocess. multiprocessing is cross-platform so this should work well in Windows or Mac with little or no adjustment. There is no need to check the underlying operating system. This was tested on 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

Running file.py brings up a figure window, then __main__ exits but the multiprocessing + matplotlib figure window remains responsive with zoom, pan, and other buttons because it is an independent process.

Check the processes at the bash command prompt with:

ps ax|grep -v grep |grep file.py


回答 15

我认为,该线程中的答案提供的方法不适用于每个系统,并且无法在更复杂的情况下(例如动画)使用。我建议在以下线程中查看MiKTeX的答案,该线程中找到了一种可靠的方法: 如何等待matplotlib动画结束?

In my opinion, the answers in this thread provide methods which don’t work for every systems and in more complex situations like animations. I suggest to have a look at the answer of MiKTeX in the following thread, where a robust method has been found: How to wait until matplotlib animation ends?


回答 16

如果您想打开多个图形,同时将它们全部打开,则此代码对我有用:

show(block=False)
draw()

If you want to open multiple figures, while keeping them all opened, this code worked for me:

show(block=False)
draw()

回答 17

虽然没有直接回答OP的请求,但我发布了此变通办法,因为它可能会在这种情况下帮助某些人:

  • 我用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”标识循环中的图,因此不会被覆盖。

While not directly answering OPs request, Im posting this workaround since it may help somebody in this situation:

  • Im creating an .exe with pyinstaller since I cannot install python where I need to generate the plots, so I need the python script to generate the plot, save it as .png, close it and continue with the next, implemented as several plots in a loop or using a function.

for this Im using:

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() 

Where “var” identifies the plot in the loop so it wont be overwritten.


回答 18

使用plt.show(block=False)和在脚本调用的结尾plt.show()

这将确保脚本完成后不会关闭窗口。

Use plt.show(block=False), and at the end of your script call plt.show().

This will ensure that the window won’t be closed when the script is finished.