proyectos ejemplos python matplotlib plot

python - ejemplos - ¿Hay una manera de separar los gráficos de matplotlib para que el cálculo pueda continuar?



django (18)

Aquí hay una actualización (python 3.6.5 en Windows 10).

Intenté todo tipo de combinaciones: lo más simple que he encontrado es usar pause(0.01) después de cada gráfico, no es necesario un show() para los gráficos intermedios, luego un solo show() al final asegura que puedas mirar en la parcela final antes de la terminación.

A modo de ejemplo, aquí hay un poco de código que utilizo para verificar la velocidad de varios tamaños de matriz: los valores trazados más altos son velocidades más altas ... hay 10 gráficos superpuestos ...

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

Después de estas instrucciones en el intérprete de Python, se abre una ventana con un gráfico:

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

Desafortunadamente, no sé cómo continuar explorando interactivamente la figura creada por show() mientras el programa realiza cálculos adicionales.

¿Es posible en absoluto? A veces, los cálculos son largos y sería útil que procedieran durante el examen de los resultados intermedios.


Bueno, tuve muchos problemas para entender los comandos de no bloqueo ... Pero finalmente, logré volver a trabajar en el ejemplo " Libro de cocina / Matplotlib / Animaciones - Animar elementos de trama seleccionados ", por lo que funciona con hilos ( y pasa datos entre hilos). a través de variables globales, oa través de un Pip multiproceso ) en Python 2.6.5 en Ubuntu 10.04.

El script se puede encontrar aquí: Animating_selected_plot_elements-thread.py - de lo contrario, se pega a continuación ( con menos comentarios ) como 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,
¡Aclamaciones!


En mi caso, quería que aparecieran varias ventanas a medida que se estaban calculando. 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()

PD. Una guía bastante útil para la interfaz OO de matplotlib .


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 ver 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 de matplotlib?


En mi sistema, show () no se bloquea, aunque quería que la secuencia de comandos esperara a que el usuario interactúe con el gráfico (y recopile datos utilizando devoluciones de llamada ''pick_event'') antes de continuar.

Para bloquear la ejecución hasta que se cierre la ventana de la trama, 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

Sin embargo, tenga en cuenta que canvas.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 guion aun corria.


En muchos casos es más conveniente hasta guardar la imagen como un archivo .png en el disco duro. Aquí es por qué:

Ventajas:

  • Puede abrirlo, echarle un vistazo y cerrarlo en cualquier momento del proceso. Esto es particularmente conveniente cuando su aplicación se ejecuta durante mucho tiempo.
  • Nada aparece y no estás obligado a tener las ventanas abiertas. Esto es particularmente conveniente cuando se trata de muchas figuras.
  • Se puede acceder a su imagen para una referencia posterior y no se pierde al cerrar la ventana de la figura.

Retirarse:

  • Lo único en lo que puedo pensar es que tendrás que ir a buscar la carpeta y abrir la imagen tú mismo.

Es mejor consultar siempre con la biblioteca que está utilizando si admite el uso de forma 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 módulo de multprocessing incluido en python. La computación 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()

Eso tiene la sobrecarga de iniciar un nuevo proceso y, a veces, es más difícil de depurar en escenarios complejos, así que prefiero la otra solución (utilizando las llamadas de API sin bloqueo de matplotlib )



Si desea abrir varias figuras, mientras mantiene todas abiertas, este código funcionó para mí:

show(block=False) draw()


Si entiendo la pregunta correctamente, usar Ipython (o Ipython QT o Ipython notebook) le permitiría trabajar de manera interactiva con el gráfico mientras que los cálculos se ubican en segundo plano. http://ipython.org/


Si está trabajando en la consola, es decir, IPython podría usar plt.show(block=False) como se plt.show(block=False) en las otras respuestas. Pero si eres perezoso puedes escribir:

plt.show(0)

Que será lo mismo.


También quise que mis gráficos se ejecuten el resto del código (y luego se sigan mostrando) incluso si hay un error (a veces uso gráficos para la depuración). Codifiqué este pequeño truco para que cualquier parcela dentro de esta declaración se comporte como tal.

Es probable que esto sea un poco no estándar y no recomendable para el código de producción. Probablemente hay muchos "errores" ocultos 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

Si / cuando implemento un correcto "mantenga los gráficos abiertos (incluso si ocurre un error) y permita que se muestren nuevos gráficos", quisiera que la secuencia de comandos se cierre 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 de espera "¡Fin del guión! / NPresione p si desea que la salida del trazado esté en pausa (tiene 5 segundos):" de https://.com/questions/26704840/corner-cases-for-my-wait-for-user-input-interruption-implementation .


También tuve que agregar plt.pause(0.001) a mi código para que realmente funcionara 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)


Tratar

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.

La documentación de show() dice:

En el modo no interactivo, muestre todas las figuras y bloquee hasta que las figuras se hayan cerrado; en el modo interactivo no tiene efecto a menos que las cifras se hayan creado antes de un cambio del modo no interactivo al modo interactivo (no recomendado). En ese caso muestra las figuras pero no bloquea.

Un solo argumento experimental de palabra clave, block , puede configurarse en True o False para anular el comportamiento de bloqueo descrito anteriormente.


Use la palabra clave ''bloque'' 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.


Use las llamadas de matplotlib que no bloquearán:

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


IMPORTANTE : Solo para aclarar algo. Supongo 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 forma simple que funciona para mí es:

  1. Use el bloque = Falso dentro del espectáculo: plt.show (bloque = Falso)
  2. Use otro show () al final de la secuencia de comandos .py.

Ejemplo de archivo 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 # the next is the last line of my script plt.show()


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