계산이 계속 될 수 있도록 matplotlib 플롯을 분리하는 방법이 있습니까?

StackOverflow https://stackoverflow.com/questions/458209

  •  19-08-2019
  •  | 
  •  

문제

Python 통역사의 이러한 지침 후에는 플롯이있는 창을 얻습니다.

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

불행히도, 나는 show() 프로그램은 추가 계산을 수행합니다.

전혀 가능합니까? 때로는 계산이 길고 중간 결과를 검사하는 동안 진행되는 경우 도움이됩니다.

도움이 되었습니까?

해결책

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

다른 팁

키워드 '블록'을 사용하여 차단 동작을 무시하십시오.

from matplotlib.pyplot import show, plot

plot(1)  
show(block=False)

# your code

코드를 계속합니다.

사용중인 라이브러리를 항상 확인하는 것이 좋습니다. 비 차단 방법.

그러나보다 일반적인 솔루션을 원하거나 다른 방법이 없다면 사용하여 분리 된 프로세스에서 차단하는 것을 실행할 수 있습니다. 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'에스 비 차단 API 호출)

노력하다

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.

그만큼 show() 선적 서류 비치 말 :

비 중 활성화 모드에서는 그림이 닫힐 때까지 모든 수치를 표시하고 차단하십시오. 대화식 모드에서는 비 결과에서 대화식 모드로 변경하기 전에 수치가 생성되지 않는 한 (권장되지 않음) 효과가 없습니다. 이 경우 그림을 표시하지만 차단하지 않습니다.

단일 실험 키워드 인수, block, 설정 될 수 있습니다 True 또는 False 위에서 설명한 차단 동작을 무시합니다.

이 문서를 읽고 싶을 수도 있습니다 matplotlib제목의 문서 :

파이썬 쉘에서 matplotlib 사용

중요한: 무언가를 명확하게하기 위해. 명령이 a 내부에 있다고 가정합니다 .py 스크립트와 스크립트는 예를 사용하여 호출됩니다 python script.py 콘솔에서.

나를 위해 일하는 간단한 방법은 다음과 같습니다.

  1. Block = False Inside Show를 사용하십시오. plt.show (block = false)
  2. 사용 또 다른 보여 주다() 결국 .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()

제 경우에는 계산할 때 여러 개의 창문이 팝업되기를 원했습니다. 참고로, 이것은 다음과 같습니다.

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 인터페이스에 대한 안내서.

글쎄, 나는 비 차단 명령을 알아내는 데 큰 어려움을 겪었지만 마침내 나는 다시 재 작업했다. "요리 책/matplotlib/애니메이션 - 선택된 플롯 요소 애니메이션"예, 스레드와 함께 작동합니다 (글로벌 변수를 통해 또는 멀티 프로세스를 통해 스레드간에 데이터를 전달합니다. Pipe) Ubuntu 10.04의 Python 2.6.5.

스크립트는 여기에서 찾을 수 있습니다. 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! 

이것이 누군가를 도울 수 있기를 바랍니다.
건배!

많은 경우에 더 편리한 이미지를 저장할 때까지 더 편리합니다 하드 드라이브의 .png 파일로. 이유는 다음과 같습니다.

장점 :

  • 당신은 그것을 열고, 그것을보고, 과정에서 언제든지 닫을 수 있습니다. 응용 프로그램이 오랫동안 실행될 때 특히 편리합니다.
  • 아무것도 나타나지 않고 창문을 열어야합니다. 이것은 많은 수치를 다룰 때 특히 편리합니다.
  • 이미지는 나중에 참조 할 수 있으며 그림 창을 닫을 때 손실되지 않습니다.

약점:

  • 내가 생각할 수있는 유일한 것은 폴더를 찾아서 이미지를 직접 열어야한다는 것입니다.

콘솔에서 일하는 경우, 즉 IPython 당신은 사용할 수 있습니다 plt.show(block=False) 다른 답변에서 지적한 바와 같이. 그러나 게으른 경우에는 다음과 같이 입력 할 수 있습니다.

plt.show(0)

동일 할 것입니다.

나는 또한 추가해야했다 plt.pause(0.001) 내 코드에 실제로 a for loop 내에서 작동하게합니다 (그렇지 않으면 첫 번째 및 마지막 플롯 만 표시됩니다).

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)

또한 오류가 있더라도 (때로는 디버깅에 플롯을 사용하는 경우) 내 플롯이 코드의 나머지 코드를 실행하고 계속 표시하기를 원했습니다. 나는이 작은 해킹을 코딩하여 with 진술은 그렇게 행동합니다.

이것은 아마도 너무 비표준이 아니며 생산 코드에는 바람직하지 않습니다. 이 코드에는 숨겨진 "gotchas"가 많을 것입니다.

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

"오류가 발생하더라도 (오류가 발생하더라도)를 열고 새 플롯을 표시 할 수 있도록 적절한 플롯을 구현할 때, 사용자 간섭이 그렇지 않으면 (배치 실행 목적으로) 스크립트가 올바르게 종료되기를 원합니다.

"스크립트의 끝! https://stackoverflow.com/questions/26704840/corner-cases-for-my-wait-for-interruption- 구현.

내 시스템에서 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)

스크립트는 여전히 실행되었지만.

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

제 생각에는이 스레드의 답변은 모든 시스템과 애니메이션과 같은 더 복잡한 상황에서 작동하지 않는 방법을 제공합니다. 강력한 방법이 발견 된 다음 스레드에서 Miktex의 답변을 살펴 보는 것이 좋습니다.Matplotlib 애니메이션이 끝날 때까지 기다리는 방법은 무엇입니까?

여러 인물을 열고 싶다면 모든 수치를 모두 열어 주면이 코드가 나에게 효과적이었습니다.

show(block=False)
draw()

OP는 드리핑에 대해 묻습니다 matplotlib 음모. 대부분의 답변은 Python 통역사 내에서 명령 실행을 가정합니다. 여기에 제시된 유스 케이스는 터미널 (예 : Bash)에서 코드 테스트에 대한 선호도입니다. file.py 실행되고 플롯이 올라가기를 원하지만 Python 스크립트가 완료되어 명령 프롬프트로 돌아갑니다.

이 독립형 파일은 사용합니다 multiprocessing 데이터를 플로팅하기위한 별도의 프로세스를 시작합니다 matplotlib. 메인 스레드는 os._exit(1) 언급 이것 게시하다. 그만큼 os._exit() 주요한 종료를 강제로 나가지 만 떠난다 matplotlib 플롯 창이 닫힐 때까지 아동 프로세스가 살아 있고 반응합니다. 전적으로 별도의 프로세스입니다.

이 접근법은 반응 형 명령 프롬프트를 제시하는 그림 창이있는 Matlab 개발 세션과 비슷합니다. 이 접근법을 사용하면 그림 창 프로세스와의 접촉을 모두 잃어 버렸지 만 개발 및 디버깅에도 괜찮습니다. 창을 닫고 계속 테스트하십시오.

multiprocessing 파이썬 전용 코드 실행을 위해 설계되어 subprocess. multiprocessing 크로스 플랫폼이므로 조정이 거의 또는 전혀없는 Windows 또는 Mac에서 잘 작동해야합니다. 기본 운영 체제를 점검 할 필요가 없습니다. 이것은 Ubuntu 18.04lts의 Linux에서 테스트되었습니다.

#!/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

사용 plt.show(block=False), 그리고 스크립트 호출이 끝날 때 plt.show().

스크립트가 완료되면 창이 닫히지 않도록합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top