Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
inal(例如bash),其中运行file.py,您希望打印出来,但python脚本需要完成并返回到命令提示符_Python_Matplotlib_Plot - Fatal编程技术网

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,show
draw()
对我不起作用,它不会打开任何窗口。但是使用
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()