¿Cómo actualizar la ventana imshow () de matplotlib interactivamente?

Estoy trabajando en algún algoritmo de visión computacional y me gustaría mostrar cómo cambia una matriz numpy en cada paso.

Lo que funciona ahora es que si tengo un simple imshow( array ) al final de mi código, la ventana muestra y muestra la imagen final.

Sin embargo, lo que me gustaría hacer es actualizar y mostrar la ventana de imshow a medida que la imagen cambia en cada iteración.

Así que por ejemplo me gustaría hacer:

 import numpy as np import matplotlib.pyplot as plt import time array = np.zeros( (100, 100), np.uint8 ) for i in xrange( 0, 100 ): for j in xrange( 0, 50 ): array[j, i] = 1 #_show_updated_window_briefly_ plt.imshow( array ) time.sleep(0.1) 

El problema es que de esta manera, la ventana de Matplotlib no se activa, solo una vez que se completa todo el cálculo.

He intentado nativo matplotlib y pyplot, pero los resultados son los mismos. Para trazar comandos encontré un interruptor .ion() , pero aquí no parece funcionar.

Q1. ¿Cuál es la mejor manera de mostrar continuamente las actualizaciones de una matriz numpy (en realidad, una imagen en escala de grises uint8)?

Q2. ¿Es posible hacer esto con una función de animación, como en el ejemplo de imagen dinámica ? Me gustaría llamar a una función dentro de un bucle, por lo tanto, no sé cómo lograr esto con una función de animación.

No necesitas llamar al imshow todo el tiempo. Es mucho más rápido usar el método set_data del objeto:

 myobj = imshow(first_image) for pixel in pixels: addpixel(pixel) myobj.set_data(segmentedimg) draw() 

El draw() debe asegurarse de que el backend actualiza la imagen.

ACTUALIZACIÓN: su pregunta fue modificada significativamente. En tales casos es mejor hacer otra pregunta. Aquí hay una manera de lidiar con su segunda pregunta:

La animación de Matplotlib solo trata con una dimensión creciente (tiempo), por lo que su doble bucle no funcionará. Necesita convertir sus índices a un solo índice. Aquí hay un ejemplo:

 import numpy as np from matplotlib import pyplot as plt from matplotlib import animation nx = 150 ny = 50 fig = plt.figure() data = np.zeros((nx, ny)) im = plt.imshow(data, cmap='gist_gray_r', vmin=0, vmax=1) def init(): im.set_data(np.zeros((nx, ny))) def animate(i): xi = i // ny yi = i % ny data[xi, yi] = 1 im.set_data(data) return im anim = animation.FuncAnimation(fig, animate, init_func=init, frames=nx * ny, interval=50) 

Implementé un script práctico que se adapta a tus necesidades. Pruébalo aquí

Un ejemplo que dibuja una onda sinusoidal dinámica:

 import numpy as np def redraw_fn(f, axes): amp = float(f) / 3000 f0 = 3 t = np.arange(0.0, 1.0, 0.001) s = amp * np.sin(2 * np.pi * f0 * t) if not redraw_fn.initialized: redraw_fn.l, = axes.plot(t, s, lw=2, color='red') redraw_fn.initialized = True else: redraw_fn.l.set_ydata(s) redraw_fn.initialized = False videofig(100, redraw_fn)