Solución:
¿Hay alguna manera en la que pueda actualizar la trama simplemente agregando más puntos?[s] lo…
Hay varias formas de animar datos en matplotlib, dependiendo de la versión que tenga. ¿Has visto los ejemplos de libros de cocina de matplotlib? Además, consulte los ejemplos de animación más modernos en la documentación de matplotlib. Finalmente, la API de animación define una función FuncAnimation que anima una función en el tiempo. Esta función podría ser simplemente la función que utiliza para adquirir sus datos.
Cada método establece básicamente el data
propiedad del objeto que se está dibujando, por lo que no requiere borrar la pantalla o la figura. los data
La propiedad simplemente se puede extender, por lo que puede mantener los puntos anteriores y seguir agregando a su línea (o imagen o lo que sea que esté dibujando).
Dado que dice que la hora de llegada de sus datos es incierta, su mejor opción probablemente sea hacer algo como:
import matplotlib.pyplot as plt
import numpy
hl, = plt.plot([], [])
def update_line(hl, new_data):
hl.set_xdata(numpy.append(hl.get_xdata(), new_data))
hl.set_ydata(numpy.append(hl.get_ydata(), new_data))
plt.draw()
Luego, cuando reciba datos del puerto serie, simplemente llame update_line
.
Para hacer esto sin FuncAnimation (por ejemplo, desea ejecutar otras partes del código mientras se produce el gráfico o desea actualizar varios gráficos al mismo tiempo), llame draw
por sí solo no produce la trama (al menos con el backend qt).
Lo siguiente funciona para mí:
import matplotlib.pyplot as plt
plt.ion()
class DynamicUpdate():
#Suppose we know the x range
min_x = 0
max_x = 10
def on_launch(self):
#Set up plot
self.figure, self.ax = plt.subplots()
self.lines, = self.ax.plot([],[], 'o')
#Autoscale on unknown axis and known lims on the other
self.ax.set_autoscaley_on(True)
self.ax.set_xlim(self.min_x, self.max_x)
#Other stuff
self.ax.grid()
...
def on_running(self, xdata, ydata):
#Update data (with the new _and_ the old points)
self.lines.set_xdata(xdata)
self.lines.set_ydata(ydata)
#Need both of these in order to rescale
self.ax.relim()
self.ax.autoscale_view()
#We need to draw *and* flush
self.figure.canvas.draw()
self.figure.canvas.flush_events()
#Example
def __call__(self):
import numpy as np
import time
self.on_launch()
xdata = []
ydata = []
for x in np.arange(0,10,0.5):
xdata.append(x)
ydata.append(np.exp(-x**2)+10*np.exp(-(x-7)**2))
self.on_running(xdata, ydata)
time.sleep(1)
return xdata, ydata
d = DynamicUpdate()
d()
Aquí hay una forma que permite eliminar puntos después de un cierto número de puntos trazados:
import matplotlib.pyplot as plt
# generate axes object
ax = plt.axes()
# set limits
plt.xlim(0,10)
plt.ylim(0,10)
for i in range(10):
# add something to axes
ax.scatter([i], [i])
ax.plot([i], [i+1], 'rx')
# draw the plot
plt.draw()
plt.pause(0.01) #is necessary for the plot to update for some reason
# start removing points if you don't want all shown
if i>2:
ax.lines[0].remove()
ax.collections[0].remove()