Matplotlib: forzar la visualización del gráfico y luego volver al código principal

Este es un MWE de lo que busco, adaptado de esta pregunta :

from matplotlib.pyplot import plot, draw, show def make_plot(): plot([1,2,3]) draw() print 'continue computation' print('Do something before plotting.') # Now display plot in a window make_plot() answer = raw_input('Back to main and window visible? ') if answer == 'y': print('Excellent') else: print('Nope') show() 

Lo que quiero es: Llamo a la función para hacer la gráfica, aparece la ventana de la gráfica, y luego vuelvo a la solicitud para ingresar un valor (basado en la imagen que se acaba de mostrar) y continuar con el código. (La ventana se puede cerrar o permanecer allí, no me importa).

Lo que obtengo en cambio es que la ventana con el gráfico solo aparece después de que se complete el código, lo cual no es bueno.


Añadir 1

He intentado lo siguiente con los mismos resultados, la ventana de trazado aparece al final del código y no antes:

 from matplotlib.pyplot import plot, ion, draw ion() # enables interactive mode plot([1,2,3]) # result shows immediately (implicit draw()) # at the end call show to ensure window won't close. draw() answer = raw_input('Back to main and window visible? ') if answer == 'y': print('Excellent') else: print('Nope') 

Lo mismo sucede si cambio draw() para show() .


Añadir 2

He intentado el siguiente enfoque:

 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 'computation continues...' print 'Now lets wait for the graph be closed to continue...:' p.join() 

lo que resulta en un Python kernel has crashed error en Canopy con el mensaje:

 The kernel (user Python environment) has terminated with error code -6. This may be due to a bug in your code or in the kernel itself. Output captured from the kernel process is shown below. [IPKernelApp] To connect another client to this kernel, use: [IPKernelApp] --existing /tmp/tmp9cshhw.json QGtkStyle could not resolve GTK. Make sure you have installed the proper libraries. [xcb] Unknown sequence number while processing queue [xcb] Most likely this is a multi-threaded client and XInitThreads has not been called [xcb] Aborting, sorry about that. python: ../../src/xcb_io.c:274: poll_for_event: La declaración `!xcb_xlib_threads_sequence_lost' no se cumple. 

Debo mencionar que estoy ejecutando Canopy en el elementary OS que se basa en Ubuntu 12.04 .


Añadir 3

También probé la solución publicada en esta pregunta :

 import numpy from matplotlib import pyplot as plt if __name__ == '__main__': x = [1, 2, 3] plt.ion() # turn on interactive mode for loop in range(0,3): y = numpy.dot(x, loop) plt.figure() plt.plot(x,y) plt.show() _ = raw_input("Press [enter] to continue.") 

Esto muestra ventanas de trazado vacías a medida que avanza el código (es decir, el usuario pulsa [ingresar]) y solo muestra las imágenes una vez que el código finaliza.

Esta solución (también en la misma pregunta) ni siquiera muestra las ventanas de trazado:

 import numpy from matplotlib import pyplot as plt if __name__ == '__main__': x = [1, 2, 3] plt.ion() # turn on interactive mode, non-blocking `show` for loop in range(0,3): y = numpy.dot(x, loop) plt.figure() # create a new figure plt.plot(x,y) # plot the figure plt.show() # show the figure, non-blocking _ = raw_input("Press [enter] to continue.") # wait for input from the user plt.close() # close the figure to show the next one. 

Puede usar plt.show(block=False) , que elimina el locking directamente.

Para su ejemplo, esto podría leer

 from matplotlib.pyplot import plot, show def make_plot(): plot([1,2,3]) show(block=False) print('continue computation') print('Do something before plotting.') # Now display plot in a window make_plot() answer = input('Back to main and window visible? ') if answer == 'y': print('Excellent') else: print('Nope') 

Ninguna de las soluciones presentadas funciona para mí. Los probé con tres IDEs diferentes: PyCharm , Spyder y Pyzo , usando el Matplotlib 2.1 más reciente (actualmente) bajo Python 3.6.

Lo que me funciona, aunque no es óptimo, es usar un comando plt.pause :

 import matplotlib.pyplot as plt def make_plot(): plt.plot([1, 2, 3]) # plt.show(block=False) # The plot does not appear. # plt.draw() # The plot does not appear. plt.pause(0.1) # The plot properly appears. print('continue computation') print('Do something before plotting.') # Now display plot in a window make_plot() answer = input('Back to main and window visible? ') if answer == 'y': print('Excellent') else: print('Nope') 

No pude hacer que esto funcionara con Canopy (aún no al menos) pero pude hacer que el código se ejecutara como si quisiera usar el IDE de Geany . Este es el código que funciona para mí, es una modificación muy pequeña del primer bloque de código en la pregunta donde el comando show() se mueve arriba desde el final del archivo hasta justo debajo del make_plot() :

 from matplotlib.pyplot import plot, draw, show def make_plot(): plot([1,2,3]) draw() print 'Plot displayed, waiting for it to be closed.' print('Do something before plotting.') # Now display plot in a window make_plot() # This line was moved up <---- show() answer = raw_input('Back to main after plot window closed? ') if answer == 'y': print('Move on') else: print('Nope') 

No hace exactamente lo que quiero, pero está lo suficientemente cerca: muestra un gráfico al usuario, espera a que se cierre esa ventana y luego continúa con el código. Idealmente, no debería tener que esperar hasta que se cierre la ventana de trazado para continuar con el código, pero supongo que es mejor que nada.

El código en la sección Agregar 2 anterior también funciona de la misma manera y sin necesidad de modificaciones en Geany , pero prefiero este porque es más simple. Actualizaré esta respuesta Si (¿cuándo?) Obtengo que esto funciona con Canopy .