¿Hay una manera de separar las gráficas de matplotlib para que el cálculo pueda continuar?
Después de estas instrucciones en el intérprete de Python se obtiene una ventana con un gráfico:
from matplotlib.pyplot import *
plot([1,2,3])
show()
# other code
Desafortunadamente, no se como continuar explorando interactivamente la figura creada por show()
mientras el programa hace más cálculos.
Es posible en absoluto? A veces los cálculos son largos y ayudaría si procedieran durante el examen de los resultados intermedios.
18 answers
Usa las llamadas de matplotlib
que no bloquearán:
Usando 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()
Usando el modo interactivo:
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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-26 23:09:47
Use la palabra clave 'block' para anular el comportamiento de bloqueo, por ejemplo,
from matplotlib.pyplot import show, plot
plot(1)
show(block=False)
# your code
Para continuar su código.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-26 16:35:45
Es mejor verificar siempre con la biblioteca que está utilizando si admite el uso de una manera no bloqueante.
Pero si desea una solución más genérica, o si no hay otra manera, puede ejecutar cualquier cosa que bloquee en un proceso separado utilizando el multprocessing
módulo incluido en python. El cómputo continuará:
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()
Que tiene la sobrecarga de lanzar un nuevo proceso, y a veces es más difícil de depurar en escenarios complejos, por lo que preferiría la otra solución (usando matplotlib
' s llamadas API sin bloqueo )
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:38
Intenta
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.
El show()
la documentación dice:
En modo no interactivo, mostrar todas las figuras y bloquear hasta que las figuras se han cerrado; en modo interactivo no tiene ningún efecto a menos que las figuras se crearon antes de un cambio de modo no interactivo a interactivo (no recomendado). En ese caso muestra las figuras pero no bloquea.
Un argumento de palabra clave experimental,
block
, se puede establecer enTrue
oFalse
para anular el bloqueo comportamiento descrito anteriormente.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-02 10:29:47
Es posible que desee leer este documento en la documentación de matplotlib
, titulado:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-19 17:00:04
En mi caso, quería tener varias ventanas emergentes a medida que se están computando. Para referencia, este es el camino:
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. Una guía bastante útil para la interfaz OO de matplotlib.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-11 22:13:17
Bueno, tuve grandes problemas para averiguar los comandos que no bloquean... Pero finalmente, logré volver a trabajar el ejemplo "Cookbook/Matplotlib/Animations - Animating selected plot elements", por lo que funciona con subprocesos ( y pasa datos entre subprocesos a través de variables globales o a través de un multiproceso Pipe
) en Python 2.6.5 en Ubuntu 10.04.
El script se puede encontrar aquí: Animating_selected_plot_elements-thread.py - de lo contrario pegado a continuación ( con menos comentarios ) para referencia:
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!
Espero que esto ayude a alguien,
¡Salud!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-10 21:55:48
Si está trabajando en la consola, es decir, IPython
podría usar plt.show(block=False)
como se indica en las otras respuestas. Pero si eres perezoso, puedes escribir:
plt.show(0)
Que será lo mismo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-18 11:11:44
IMPORTANTE : Solo para dejar algo claro. Asumo que los comandos están dentro de un script .py
y el script se llama usando, por ejemplo, python script.py
desde la consola.
Una manera simple que funciona para mí es:
- Use el bloque = False dentro de show : plt.show (block = False)
- Use otroshow() al final del script .py.
Ejemplo de script.py
archivo:
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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-12 23:08:20
En muchos casos es más conveniente guardar la imagen como a .archivo png en el disco duro. He aquí por qué:
Ventajas:
- Puede abrirlo, echarle un vistazo y cerrarlo en cualquier momento del proceso. Esto es particularmente conveniente cuando su aplicación se está ejecutando durante mucho tiempo tiempo.
- Nada aparece y no estás obligado a tener las ventanas abiertas. Esto es particularmente conveniente cuando se trata de muchas figuras.
- Tu imagen es accesible para referencia posterior y no se pierde al cerrar la ventana de la figura.
Inconveniente:
- Lo único que se me ocurre es que tendrás que ir a buscar la carpeta y abrir la imagen tú mismo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-18 18:21:54
Yo también quería mi maquina para mostrar ejecutar el resto del código (y luego mostrar) incluso si hay un error (yo a veces uso de parcelas para la depuración). Codifiqué este pequeño truco para que cualquier parcela dentro de esta declaración with
se comporte como tal.
Esto es probablemente un poco no estándar y no recomendable para el código de producción. Probablemente hay muchas "trampas" ocultas en este código.
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 permitir que se muestren nuevas gráficas", me gustaría que el script saliera correctamente si ninguna interferencia del usuario le indica lo contrario (para fines de ejecución por lotes).
Puedo usar algo así como una pregunta de tiempo fuera "¡Fin del script! \nPress p si desea que la salida de trazado se detenga (tiene 5 segundos): "desde 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:32
En mi sistema, show() no se bloquea, aunque quería que el script esperara a que el usuario interactuara con el gráfico (y recopilara datos usando 'pick_event' callbacks) antes de continuar.
Para bloquear la ejecución hasta que se cierre la ventana del gráfico, utilicé lo siguiente:
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
Tenga en cuenta, sin embargo, que el lienzo.start_event_loop_default() produjo la siguiente advertencia:
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)
Aunque el script todavía se ejecutaba.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-17 05:06:56
También tuve que agregar plt.pause(0.001)
a mi código para que realmente funcione dentro de un bucle for (de lo contrario solo mostraría la primera y la última gráfica):
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/ajaxhispano.com/template/agent.layouts/content.php on line 61
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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-06 14:49:02
En mi opinión, las respuestas en este hilo proporcionan métodos que no funcionan para todos los sistemas y en situaciones más complejas como las animaciones. Sugiero echar un vistazo a la respuesta de MikeTex en el siguiente hilo, donde se ha encontrado un método robusto: ¿Cómo esperar hasta que termine la animación matplotlib?
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:24
Si entiendo la pregunta correctamente, usando Ipython (o Ipython QT o Ipython notebook) le permitiría trabajar interactivamente con el gráfico mientras los cálculos van uno en segundo plano. 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-24 04:18:42
Si desea abrir varias figuras, mientras las mantiene abiertas, este código funcionó para mí:
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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-16 15:11:08
Aquí hay una actualización (python 3.6.5 en Windows 10).
Probé todo tipo de combinaciones - la más simple que he encontrado es solo usar pause(0.01)
después de cada parcela - no hay necesidad de un show()
para las parcelas intermedias - entonces un solo show()
al final se asegura de que pueda mirar la parcela final antes de la terminación.
Como ejemplo, aquí hay un poco de código que uso para verificar la velocidad de varios tamaños de matriz: los valores trazados más altos son velocidades más altas... hay 10 parcelas superpuestas...
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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-27 01:47:58