matplotlib
Animaciones y tramas interactivas.
Buscar..
Introducción
Con python matplotlib puedes hacer correctamente gráficos animados.
Animación básica con función de animación.
El paquete matplotlib.animation ofrece algunas clases para crear animaciones. FuncAnimation
crea animaciones llamando repetidamente a una función. Aquí usamos una función animate()
que cambia las coordenadas de un punto en el gráfico de una función sinusoidal.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
TWOPI = 2*np.pi
fig, ax = plt.subplots()
t = np.arange(0.0, TWOPI, 0.001)
s = np.sin(t)
l = plt.plot(t, s)
ax = plt.axis([0,TWOPI,-1,1])
redDot, = plt.plot([0], [np.sin(0)], 'ro')
def animate(i):
redDot.set_data(i, np.sin(i))
return redDot,
# create animation using the animate() function
myAnimation = animation.FuncAnimation(fig, animate, frames=np.arange(0.0, TWOPI, 0.1), \
interval=10, blit=True, repeat=True)
plt.show()
Guarda la animación en gif
En este ejemplo se utiliza el save
método para guardar una Animation
de objetos mediante ImageMagick.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib import rcParams
# make sure the full paths for ImageMagick and ffmpeg are configured
rcParams['animation.convert_path'] = r'C:\Program Files\ImageMagick\convert'
rcParams['animation.ffmpeg_path'] = r'C:\Program Files\ffmpeg\bin\ffmpeg.exe'
TWOPI = 2*np.pi
fig, ax = plt.subplots()
t = np.arange(0.0, TWOPI, 0.001)
s = np.sin(t)
l = plt.plot(t, s)
ax = plt.axis([0,TWOPI,-1,1])
redDot, = plt.plot([0], [np.sin(0)], 'ro')
def animate(i):
redDot.set_data(i, np.sin(i))
return redDot,
# create animation using the animate() function with no repeat
myAnimation = animation.FuncAnimation(fig, animate, frames=np.arange(0.0, TWOPI, 0.1), \
interval=10, blit=True, repeat=False)
# save animation at 30 frames per second
myAnimation.save('myAnimation.gif', writer='imagemagick', fps=30)
Controles interactivos con matplotlib.widgets
Para interactuar con parcelas, Matplotlib ofrece widgets neutros de GUI. Los widgets requieren un objeto matplotlib.axes.Axes
.
Aquí hay una demostración del widget deslizante que detalla la amplitud de una curva sinusoidal. La función de actualización es activada por el evento on_changed()
del control deslizante.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.widgets import Slider
TWOPI = 2*np.pi
fig, ax = plt.subplots()
t = np.arange(0.0, TWOPI, 0.001)
initial_amp = .5
s = initial_amp*np.sin(t)
l, = plt.plot(t, s, lw=2)
ax = plt.axis([0,TWOPI,-1,1])
axamp = plt.axes([0.25, .03, 0.50, 0.02])
# Slider
samp = Slider(axamp, 'Amp', 0, 1, valinit=initial_amp)
def update(val):
# amp is the current value of the slider
amp = samp.val
# update curve
l.set_ydata(amp*np.sin(t))
# redraw canvas while idle
fig.canvas.draw_idle()
# call update function on slider value change
samp.on_changed(update)
plt.show()
- AxesWidget
- Botón
- Botones de control
- Cursor
- ElipseSelector
- Lazo
- LassoSelector
- LockDraw
- MultiCursor
- Botones de radio
- RectangleSelector
- SpanSelector
- SubplotTool
- Manijas de herramientas
Trazar datos en vivo de la tubería con matplotlib
Esto puede ser útil cuando desea visualizar los datos entrantes en tiempo real. Estos datos podrían, por ejemplo, provenir de un microcontrolador que muestrea continuamente una señal analógica.
En este ejemplo, obtendremos nuestros datos de una canalización con nombre (también conocida como fifo). Para este ejemplo, los datos en la tubería deben ser números separados por caracteres de nueva línea, pero puede adaptarlos a su gusto.
Ejemplo de datos:
100
123.5
1589
Más información sobre tuberías con nombre.
También utilizaremos el tipo de datos deque, de las colecciones de la biblioteca estándar. Un objeto deque funciona bastante como una lista. Pero con un objeto deque es bastante fácil agregarle algo mientras se mantiene el objeto deque en una longitud fija. Esto nos permite mantener el eje x en una longitud fija en lugar de siempre crecer y aplastar la gráfica. Más información sobre objetos deque.
Elegir el backend correcto es vital para el rendimiento. Compruebe qué componentes internos funcionan en su sistema operativo y elija uno rápido. Para mí, solo qt4agg y el backend predeterminado funcionaron, pero el predeterminado fue demasiado lento. Más información sobre backends en matplotlib.
Este ejemplo se basa en el ejemplo matplotlib de trazar datos aleatorios .
Ninguno de los caracteres en este código está destinado a ser eliminado.
import matplotlib
import collections
#selecting the right backend, change qt4agg to your desired backend
matplotlib.use('qt4agg')
import matplotlib.pyplot as plt
import matplotlib.animation as animation
#command to open the pipe
datapipe = open('path to your pipe','r')
#amount of data to be displayed at once, this is the size of the x axis
#increasing this amount also makes plotting slightly slower
data_amount = 1000
#set the size of the deque object
datalist = collections.deque([0]*data_amount,data_amount)
#configure the graph itself
fig, ax = plt.subplots()
line, = ax.plot([0,]*data_amount)
#size of the y axis is set here
ax.set_ylim(0,256)
def update(data):
line.set_ydata(data)
return line,
def data_gen():
while True:
"""
We read two data points in at once, to improve speed
You can read more at once to increase speed
Or you can read just one at a time for improved animation smoothness
data from the pipe comes in as a string,
and is seperated with a newline character,
which is why we use respectively eval and rstrip.
"""
datalist.append(eval((datapipe.readline()).rstrip('\n')))
datalist.append(eval((datapipe.readline()).rstrip('\n')))
yield datalist
ani = animation.FuncAnimation(fig,update,data_gen,interval=0, blit=True)
plt.show()
Si su trama comienza a demorarse después de un tiempo, intente agregar más datos de datalist.append, para que se lean más líneas en cada fotograma. O elige un backend más rápido si puedes.
Esto funcionó con datos de 150Hz de una tubería en mi 1.7ghz i3 4005u.