Czy istnieje sposób na odłączenie Wykresów matplotlib, aby obliczenia mogły być kontynuowane?
Po tych instrukcjach w interpreterze Pythona pojawia się okno z wykresem:
from matplotlib.pyplot import *
plot([1,2,3])
show()
# other code
Niestety, Nie wiem, jak dalej interaktywnie badać figurę stworzoną przez show()
podczas gdy program wykonuje dalsze obliczenia.
18 answers
Użyj wywołań matplotlib
, które nie blokują:
Używając 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()
Używanie trybu interaktywnego:
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()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-26 23:09:47
Użyj słowa kluczowego 'block', aby nadpisać zachowanie blokowania, np.
from matplotlib.pyplot import show, plot
plot(1)
show(block=False)
# your code
Aby kontynuować kod.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-26 16:35:45
Lepiej zawsze sprawdzić bibliotekę, której używasz, jeśli obsługuje ona użycie w sposób nieblokujący.
Ale jeśli chcesz bardziej ogólnego rozwiązania, lub jeśli nie ma innego sposobu, możesz uruchomić wszystko, co blokuje oddzielony proces za pomocą multprocessing
Moduł zawarty w Pythonie. Obliczenia będą kontynuowane:
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()
To ma na głowie uruchomienie nowego procesu i czasami jest trudniejsze do debugowania w złożonych scenariuszach, więc wolałbym inne rozwiązanie (użycie matplotlib
' S nieblokujące wywołania API )
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:38
Spróbuj
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.
The show()
Dokumentacja mówi:
W trybie nieinteraktywnym Wyświetlaj wszystkie figury i blokuj je do momentu zamknięcia; w trybie interaktywnym nie ma to wpływu, chyba że figury zostały utworzone przed zmianą z trybu nieinteraktywnego na interaktywny (nie zaleca się). W takim przypadku wyświetla dane, ale nie blokuje.
Pojedynczy eksperymentalny argument słowa kluczowego,
block
, może być ustawiony naTrue
lubFalse
, aby nadpisać blokowanie zachowanie opisane powyżej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-02 10:29:47
Możesz przeczytać ten dokument w dokumentacji matplotlib
, zatytułowanej:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-19 17:00:04
W moim przypadku chciałem mieć kilka okien wyskakujących podczas ich obliczania. Dla odniesienia, jest to sposób:
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. Bardzo przydatny przewodnik po interfejsie oo matplotlib .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-11 22:13:17
Cóż, miałem wielki problem z odgadnięciem komend nieblokujących... W końcu udało mi się przerobić przykład " Cookbook / Matplotlib / Animations-animowanie wybranych elementów wykresu ", więc działa z wątkami ( i przekazuje dane między wątkami albo poprzez zmienne globalne, albo przez wieloprocesor Pipe
) na Pythonie 2.6.5 na Ubuntu 10.04.
Skrypt można znaleźć tutaj: Animating_selected_plot_elements-thread.py - inaczej wklejone poniżej ( z mniejszą komentarze ) dla odniesienia:
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!
Mam nadzieję, że to komuś pomoże,
Zdrowie!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-10 21:55:48
Jeśli pracujesz w konsoli, tj. IPython
możesz użyć plt.show(block=False)
, Jak wskazano w innych odpowiedziach. Ale jeśli jesteś leniwy możesz po prostu wpisać:
plt.show(0)
Który będzie taki sam.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-18 11:11:44
Ważne: żeby coś wyjaśnić. Zakładam, że polecenia znajdują się wewnątrz skryptu .py
i skrypt jest wywoływany przy użyciu np. python script.py
z konsoli.
Prosty sposób, który działa dla mnie to:
- użyj block = False Inside show: plt.show (block = False)
- użyj innego show () na końcu skryptu .py.
Przykład script.py
Plik:
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
# the next is the last line of my script
plt.show()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-12 23:08:20
W wielu przypadkach jest to wygodniejsze do zapisania obrazu jako .plik png na dysku twardym. Oto dlaczego:
Zalety:
- Możesz go otworzyć, obejrzeć i zamknąć w każdej chwili. Jest to szczególnie wygodne, gdy aplikacja działa przez długi czas
czas.
- nic nie wyskakuje i nie musisz mieć otwartych okien. Jest to szczególnie wygodne, gdy masz do czynienia z wieloma postaciami.
- Twój wizerunek jest dostępny do późniejszego wykorzystania i nie jest tracony podczas zamykania okna rysunku.
Wada:
- jedyne, co przychodzi mi do głowy, to to, że będziesz musiał znaleźć folder i otworzyć obraz samodzielnie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-18 18:21:54
Chciałem również, aby moje wykresy wyświetlały resztę kodu (a następnie wyświetlały), nawet jeśli wystąpi błąd (czasami używam Wykresów do debugowania). Zaszyfrowałem ten mały hacking, aby wszelkie wątki w tym with
oświadczeniu zachowywały się tak samo.
Jest to prawdopodobnie zbyt niestandardowe i niewskazane dla kodu produkcyjnego. Prawdopodobnie w tym kodzie jest sporo ukrytych "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
If / when I implementing a proper " keep the plots open (even if an error is) and Zezwalaj na wyświetlanie nowych wykresów", chciałbym, aby skrypt poprawnie zakończył działanie, jeśli żadna ingerencja użytkownika nie mówi inaczej(dla celów wykonywania wsadowego).
Mogę użyć czegoś takiego jak przerwa-pytanie " koniec skryptu! \nPress p Jeśli chcesz, aby wynik wykresu został wstrzymany (masz 5 sekund): "od https://stackoverflow.com/questions/26704840/corner-cases-for-my-wait-for-user-input-interruption-implementation.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:32
W moim systemie show () nie blokuje, chociaż chciałem, aby skrypt czekał na interakcję użytkownika z grafem (i zbierał dane za pomocą wywołań zwrotnych' pick_event') przed kontynuowaniem.
Aby zablokować wykonanie do czasu zamknięcia okna wykresu, użyłem następującego:
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
Zwróć jednak uwagę, że płótno.start_event_loop_default () wygenerowało następujące ostrzeżenie:
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)
Chociaż skrypt nadal działał.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-17 05:06:56
Musiałem również dodać plt.pause(0.001)
do mojego kodu, aby naprawdę działał wewnątrz pętli for (w przeciwnym razie pokazywałby tylko pierwszy i ostatni Wykres):
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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-09 14:16:16
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-06 14:49:02
Moim zdaniem odpowiedzi w tym wątku dostarczają metod, które nie działają na każdym systemie i w bardziej złożonych sytuacjach, takich jak animacje. Proponuję rzucić okiem na odpowiedź MikeTex w poniższym wątku, gdzie znaleziono solidną metodę: Jak poczekać do zakończenia animacji matplotlib?
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:24
Jeśli dobrze rozumiem pytanie, używając Ipython (lub IPython QT lub IPython notebook) pozwala na interaktywną pracę z wykresem, podczas gdy obliczenia idą w tle. http://ipython.org/
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-24 04:18:42
Jeśli chcesz otworzyć wiele figur, zachowując je wszystkie otwarte, ten kod zadziałał dla mnie:
show(block=False)
draw()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-16 15:11:08
Oto aktualizacja (python 3.6.5 na Windows 10).
Próbowałem różnych kombinacji-najprostszą, jaką znalazłem, jest użycie pause(0.01)
po każdym wykresie - nie ma potrzeby stosowania show()
dla pośrednich Wykresów - wtedy pojedynczy show()
na końcu zapewnia, że możesz spojrzeć na końcowy wykres przed zakończeniem.
Jako przykład, oto fragment kodu, którego używam do sprawdzania prędkości dla różnych rozmiarów tablic - wyższe wartości wykresu to wyższe prędkości... istnieje 10 nakładanych działek...
from pylab import *
import matplotlib.pyplot as plt
from time import *
ttot=clock();
mmax=6;npts=20;nplts=10;
x=[int(a+0.5) for a in 10**linspace(0,mmax,npts)]
for nrun in range(nplts):
j=0;aa=1;bb=1;b=1;
tim=zeros(npts)
for n in x:
aa=rand(n);bb=aa;b=aa;
if n<100:m=10000
elif n<5000:m=1000
elif n<20000:m=100
else:m=100
tt=clock()
for ii in range(1,m+1):
b=aa*bb+aa
tt1=clock()-tt
tim[j]=tt1/n/m
j=j+1
print(n,2/(tt1/n/m)/1e6);
plt.semilogx(x,2/tim/1e6)
pause(0.01)
print(clock()-ttot)
show()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-27 01:47:58