Python matplotlib actualiza el diagrama de dispersión desde una función
scatter-plot (2)
Estoy tratando de actualizar automáticamente un diagrama de dispersión. La fuente de mis valores X e Y es externa, y los datos se insertan automáticamente en mi código en intervalos de tiempo no predecidos (rondas).
Solo he logrado trazar todos los datos cuando finalizó todo el proceso, mientras que estoy tratando de agregar y trazar datos constantemente en mi lienzo.
Lo que sí obtengo (al final de toda la carrera) es esto:
Mientras que, lo que busco es esto:
Una versión simplificada de mi código:
import matplotlib.pyplot as plt
def read_data():
#This function gets the values of xAxis and yAxis
xAxis = [some values] #these valuers change in each run
yAxis = [other values] #these valuers change in each run
plt.scatter(xAxis,yAxis, label = ''myPlot'', color = ''k'', s=50)
plt.xlabel(''x'')
plt.ylabel(''y'')
plt.show()
Hay varias formas de animar una trama matplotlib. A continuación, veamos dos ejemplos mínimos utilizando un diagrama de dispersión.
(a) use el modo interactivo
plt.ion()
Para que tenga lugar una animación, necesitamos un bucle de eventos.
Una forma de obtener el bucle de eventos es usar
plt.ion()
("interactivo en").
Uno debe dibujar primero la figura y luego puede actualizar la trama en un bucle.
Dentro del bucle, necesitamos dibujar el lienzo e introducir una pequeña pausa para que la ventana procese otros eventos (como las interacciones del mouse, etc.).
Sin esta pausa, la ventana se congelaría.
Finalmente llamamos a
plt.waitforbuttonpress()
para dejar que la ventana permanezca abierta incluso después de que la animación haya terminado.
import matplotlib.pyplot as plt
import numpy as np
plt.ion()
fig, ax = plt.subplots()
x, y = [],[]
sc = ax.scatter(x,y)
plt.xlim(0,10)
plt.ylim(0,10)
plt.draw()
for i in range(1000):
x.append(np.random.rand(1)*10)
y.append(np.random.rand(1)*10)
sc.set_offsets(np.c_[x,y])
fig.canvas.draw_idle()
plt.pause(0.1)
plt.waitforbuttonpress()
(b) usando
FuncAnimation
Gran parte de lo anterior se puede automatizar usando
matplotlib.animation.FuncAnimation
.
FuncAnimation se encargará del bucle y del redibujado y llamará constantemente a una función (en este caso,
animate()
) después de un intervalo de tiempo determinado.
La animación solo comenzará una vez que se
plt.show()
, ejecutándose automáticamente en el bucle de eventos de la ventana de trazado.
import matplotlib.pyplot as plt
import matplotlib.animation
import numpy as np
fig, ax = plt.subplots()
x, y = [],[]
sc = ax.scatter(x,y)
plt.xlim(0,10)
plt.ylim(0,10)
def animate(i):
x.append(np.random.rand(1)*10)
y.append(np.random.rand(1)*10)
sc.set_offsets(np.c_[x,y])
ani = matplotlib.animation.FuncAnimation(fig, animate,
frames=2, interval=100, repeat=True)
plt.show()
Por lo que entiendo, desea actualizar interactivamente su trama. Si es así, puede usar el diagrama en lugar del diagrama de dispersión y actualizar los datos de su diagrama de esta manera.
import numpy
import matplotlib.pyplot as plt
fig = plt.figure()
axe = fig.add_subplot(111)
X,Y = [],[]
sp, = axe.plot([],[],label=''toto'',ms=10,color=''k'',marker=''o'',ls='''')
fig.show()
for iter in range(5):
X.append(numpy.random.rand())
Y.append(numpy.random.rand())
sp.set_data(X,Y)
axe.set_xlim(min(X),max(X))
axe.set_ylim(min(Y),max(Y))
raw_input(''...'')
fig.canvas.draw()
Si este es el comportamiento que está buscando, solo necesita crear una función que agregue los datos de sp, y obtener en esa función los nuevos puntos que desea trazar (ya sea con la administración de E / S o cualquier proceso de comunicación que esté utilizando). Espero que ayude.