Animar cambios de cuadrícula cuadráticos (matshow)
Frecuentes
Visto 10,863 equipos
11
Tengo una cuadrícula NxN con algunos valores, que cambian cada paso de tiempo. He encontrado una manera de trazar una configuración de cuadrícula única de esto con matshow
función, pero no sé cómo actualizo el estado con cada paso de tiempo. Aquí hay un ejemplo simple:
from pylab import *
from matplotlib import pyplot
a = arange(25)
a = a.reshape(5,5)
b = 10*rand(5,5)
matshow(a-b, cmap = cm.jet)
colorbar()
show()
Este código produce la siguiente imagen:
Ahora imagina que el próximo paso de tiempo cambian algunos valores, así debería ser esta imagen. Esta es la lógica que tenía en mente:
from pylab import *
from matplotlib import pyplot
a = arange(25)
a = a.reshape(5,5)
time=10
for t in range(time):
b = 10*rand(5,5)
print b
matshow(a-b, cmap=cm.jet)
colorbar()
show()
Esto produce 10 imágenes. Me gustaría animar esto en lugar de producir imágenes individuales y, por ejemplo, me gustaría elegir un paso de tiempo entre los cambios (es decir, la velocidad de fotogramas).
Además, estoy abierto a sugerencias para diferentes funciones, si matshow
no es el camino a seguir, pero por favor mantenlo simple, soy relativamente inexperto.
2 Respuestas
18
matplotlib 1.1 tiene un módulo de animación (mira el ejemplos).
Usar animation.FuncAnimation
puedes actualizar tu trama así:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
def generate_data():
a = np.arange(25).reshape(5, 5)
b = 10 * np.random.rand(5, 5)
return a - b
def update(data):
mat.set_data(data)
return mat
def data_gen():
while True:
yield generate_data()
fig, ax = plt.subplots()
mat = ax.matshow(generate_data())
plt.colorbar(mat)
ani = animation.FuncAnimation(fig, update, data_gen, interval=500,
save_count=50)
plt.show()
Puedes guardar la animación usando:
ani.save('animation.mp4')
Yo lo guardo con
ani.save('animation.mp4', clear_temp=False)
se conservan los fotogramas y puedes crear un gif animado como el siguiente con
convert *.png animation.gif
contestado el 03 de mayo de 12 a las 16:05
1
La forma más fácil es probablemente hacer que matplotlib guarde imágenes individuales y luego hacer que otro programa o biblioteca las una en una animación. Este enfoque utiliza un módulo llamado escribir2gif pero también puedes usar mencoder, ffmpeg o cualquier otro software capaz de producir video:
from images2gif import writeGif
from pylab import *
from matplotlib import pyplot as plt
from PIL import Image
a = arange(25)
a = a.reshape(5,5)
time=10
images = []
for t in range(time):
fig = plt.figure(figsize = (5, 5))
ax = fig.add_subplot(111)
b = 10*rand(5,5)
cax = ax.matshow(a-b, cmap=cm.jet, vmin = -8, vmax = 24)
fname = 'tmp%03d.png' % t
fig.colorbar(cax)
fig.savefig(fname)
images.append(Image.open(fname))
writeGif('matanim.gif', images, duration = .2)
Aquí hay un ejemplo de cómo hacerlo desde la interfaz de pylab. No funciona tan bien ya que la representación continua se ejecuta en el mismo hilo que los controladores de pylabs gui:
from pylab import arange, cm, draw, rand
from matplotlib import pylab as plt
from time import sleep
plt.ion()
a = arange(25)
a = a.reshape(5,5)
fig = plt.figure(figsize = (5, 5))
for i in range(200):
ax = fig.add_subplot(111)
b = 10*rand(5,5)
cax = ax.matshow(a-b, cmap=cm.jet, vmin = -8, vmax = 24)
if i == 0:
fig.colorbar(cax)
draw()
sleep(0.2)
contestado el 03 de mayo de 12 a las 12:05
Gracias por su respuesta. Hay ejemplos de tramas animadas dentro de la interfaz de matplotlib, por ejemplo: scipy.org/Cookbook/Matplotlib/Animaciones ¿No hay forma de que mi ejemplo también esté animado dentro de esa interfaz? - enedeno
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas python numpy matplotlib or haz tu propia pregunta.
Gracias, eso es lo que estaba buscando. - enedeno
Debería haber preguntado esto en la pregunta, pero ¿hay alguna manera de poner una condición en ab para que la animación se detenga y solo quede la última figura (como si hiciera un diagrama estático)? Por ejemplo, si max(ab)>22? - enedeno
@bmu Me tomé la libertad de agregar algunos cuadros de su "película" como un gif animado: ¡excelente respuesta! Mirando la animación, sugeriría que la barra de colores tenga límites fijos para que no cambie durante la animación. - Enganchado
@Hooked: Traté de subir un gif animado, pero algo salió mal, así que pensé que Stackoverflow no lo permitía. Pero funciona, bien. - bmu
@enedene: Puedes detener la animación por un tiempo determinado con
time.sleep()
si se cumple una condición. Sin embargo, creo que sería difícil interactuar con el usuario si quiere continuar. - bmu