Como plotar dados em tempo real usando o Matplotlib

  1. Função FuncAnimation()
  2. canvas.draw() Junto com canvas_flush_events()
  3. Gráfico de dispersão em tempo real

Para plotar dados em tempo real usando Matplotlib, ou fazer uma animação em Matplotlib, atualizamos constantemente as variáveis a serem plotadas por iteração em loop e depois plotamos os valores atualizados. Para visualizar o gráfico atualizado em tempo real através de animação, utilizamos vários métodos como FuncAnimation() function, canvas.draw() juntamente com canvas_flush_events().

Função FuncAnimation()

Podemos atualizar a trama em tempo real atualizando as variáveis x e y e depois exibindo atualizações através de animação utilizando matplotlib.animation.FuncAnimation.

Sintaxe:

matplotlib.animation.FuncAnimation(fig, 
                                   func, 
                                   frames=None,
                                   init_func=None, 
                                   fargs=None,
                                   save_count=None, 
                                   *, 
                                   cache_frame_data=True,
                                   **kwargs)

Código:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

x = []
y = []

figure, ax = plt.subplots(figsize=(4,3))
line, = ax.plot(x, y)
plt.axis([0, 4*np.pi, -1, 1])

def func_animate(i):
    x = np.linspace(0, 4*np.pi, 1000)
    y = np.sin(2 * (x - 0.1 * i))
    
    line.set_data(x, y)
    
    return line,

ani = FuncAnimation(figure,
                    func_animate,
                    frames=10,
                    interval=50)

ani.save(r'animation.gif', fps=10)

plt.show()

plotar em tempo real utilizando a função FuncAnimation.png

ani = FuncAnimation(figure,
                    func_animate,
                    frames=10,
                    interval=50)

figura é o objeto de figura cuja trama será atualizada.

func_animate é a função a ser chamada em cada quadro. Seu primeiro argumento vem do próximo valor frames.

frames=10 é igual a range(10). Valores de 0 a 9 são passados para o func_animate em cada frame. Também poderíamos atribuir um interalbe a frames, como uma lista [0, 1, 3, 7, 12].

interval é o atraso entre os quadros na unidade de ms.

ani.save('animation.gif', fps=10)

Poderíamos salvar a animação para um gif ou mp4 com os parâmetros como fps e dpi.

canvas.draw() Junto com canvas_flush_events()

Podemos atualizar o gráfico em tempo real atualizando as variáveis x e y com set_xdata() e set_ydata() e então exibindo atualizações através de animação utilizando canvas.draw(), que é um método baseado em Javascript.

import numpy as np
import time
import matplotlib.pyplot as plt

x = np.linspace(0, 10, 100)
y = np.cos(x)

plt.ion()

figure, ax = plt.subplots(figsize=(8,6))
line1, = ax.plot(x, y)

plt.title("Dynamic Plot of sinx",fontsize=25)

plt.xlabel("X",fontsize=18)
plt.ylabel("sinX",fontsize=18)

for p in range(100):
    updated_y = np.cos(x-0.05*p)
    
    line1.set_xdata(x)
    line1.set_ydata(updated_y)
    
    figure.canvas.draw()
    
    figure.canvas.flush_events()
    time.sleep(0.1)

Traçado em tempo real em Matplotlib utilizando o canvas_draw

Aqui os valores de x e y são atualizados repetidamente e a trama também é atualizada em tempo real.

plt.ion() ativa o modo interativo. A trama não será atualizada se não for chamada.

canvas.flush_events() é um método baseado em Javascript para limpar figuras em cada iteração, para que figuras sucessivas não se sobreponham.

Gráfico de dispersão em tempo real

Entretanto, para fazer uma dispersão em tempo real, podemos apenas atualizar os valores de x e y e adicionar pontos de dispersão em cada iteração. Neste caso, não precisamos limpar cada figura, pois um gráfico de dispersão geralmente representa um ponto distinto no plano e os pontos têm muito poucas chances de sobreposição.

import numpy as np
import matplotlib.pyplot as plt
x=0
for i in range(100):
    x=x+0.04
    y = np.sin(x)
    plt.scatter(x, y)
    plt.title("Real Time plot")
    plt.xlabel("x")
    plt.ylabel("sinx")
    plt.pause(0.05)

plt.show()

gráfico de dispersão em tempo real