How do I plot in real-time in a while loop using matplotlib?

前端 未结 12 1373
天命终不由人
天命终不由人 2020-11-22 01:08

I am trying to plot some data from a camera in real time using OpenCV. However, the real-time plotting (using matplotlib) doesn\'t seem to be working.

I\'ve isolated

12条回答
  •  刺人心
    刺人心 (楼主)
    2020-11-22 01:52

    The top (and many other) answers were built upon plt.pause(), but that was an old way of animating the plot in matplotlib. It is not only slow, but also causes focus to be grabbed upon each update (I had a hard time stopping the plotting python process).

    TL;DR: you may want to use matplotlib.animation (as mentioned in documentation).

    After digging around various answers and pieces of code, this in fact proved to be a smooth way of drawing incoming data infinitely for me.

    Here is my code for a quick start. It plots current time with a random number in [0, 100) every 200ms infinitely, while also handling auto rescaling of the view:

    from datetime import datetime
    from matplotlib import pyplot
    from matplotlib.animation import FuncAnimation
    from random import randrange
    
    x_data, y_data = [], []
    
    figure = pyplot.figure()
    line, = pyplot.plot_date(x_data, y_data, '-')
    
    def update(frame):
        x_data.append(datetime.now())
        y_data.append(randrange(0, 100))
        line.set_data(x_data, y_data)
        figure.gca().relim()
        figure.gca().autoscale_view()
        return line,
    
    animation = FuncAnimation(figure, update, interval=200)
    
    pyplot.show()
    

    You can also explore blit for even better performance as in FuncAnimation documentation.

    An example from the blit documentation:

    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.animation import FuncAnimation
    
    fig, ax = plt.subplots()
    xdata, ydata = [], []
    ln, = plt.plot([], [], 'ro')
    
    def init():
        ax.set_xlim(0, 2*np.pi)
        ax.set_ylim(-1, 1)
        return ln,
    
    def update(frame):
        xdata.append(frame)
        ydata.append(np.sin(frame))
        ln.set_data(xdata, ydata)
        return ln,
    
    ani = FuncAnimation(fig, update, frames=np.linspace(0, 2*np.pi, 128),
                        init_func=init, blit=True)
    plt.show()
    

提交回复
热议问题