Saltar al contenido

Gráfica de actualización dinámica en matplotlib

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()
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *