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

前端 未结 12 1239
天命终不由人
天命终不由人 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条回答
  •  闹比i
    闹比i (楼主)
    2020-11-22 01:59

    If you're interested in realtime plotting, I'd recommend looking into matplotlib's animation API. In particular, using blit to avoid redrawing the background on every frame can give you substantial speed gains (~10x):

    #!/usr/bin/env python
    
    import numpy as np
    import time
    import matplotlib
    matplotlib.use('GTKAgg')
    from matplotlib import pyplot as plt
    
    
    def randomwalk(dims=(256, 256), n=20, sigma=5, alpha=0.95, seed=1):
        """ A simple random walk with memory """
    
        r, c = dims
        gen = np.random.RandomState(seed)
        pos = gen.rand(2, n) * ((r,), (c,))
        old_delta = gen.randn(2, n) * sigma
    
        while True:
            delta = (1. - alpha) * gen.randn(2, n) * sigma + alpha * old_delta
            pos += delta
            for ii in xrange(n):
                if not (0. <= pos[0, ii] < r):
                    pos[0, ii] = abs(pos[0, ii] % r)
                if not (0. <= pos[1, ii] < c):
                    pos[1, ii] = abs(pos[1, ii] % c)
            old_delta = delta
            yield pos
    
    
    def run(niter=1000, doblit=True):
        """
        Display the simulation using matplotlib, optionally using blit for speed
        """
    
        fig, ax = plt.subplots(1, 1)
        ax.set_aspect('equal')
        ax.set_xlim(0, 255)
        ax.set_ylim(0, 255)
        ax.hold(True)
        rw = randomwalk()
        x, y = rw.next()
    
        plt.show(False)
        plt.draw()
    
        if doblit:
            # cache the background
            background = fig.canvas.copy_from_bbox(ax.bbox)
    
        points = ax.plot(x, y, 'o')[0]
        tic = time.time()
    
        for ii in xrange(niter):
    
            # update the xy data
            x, y = rw.next()
            points.set_data(x, y)
    
            if doblit:
                # restore background
                fig.canvas.restore_region(background)
    
                # redraw just the points
                ax.draw_artist(points)
    
                # fill in the axes rectangle
                fig.canvas.blit(ax.bbox)
    
            else:
                # redraw everything
                fig.canvas.draw()
    
        plt.close(fig)
        print "Blit = %s, average FPS: %.2f" % (
            str(doblit), niter / (time.time() - tic))
    
    if __name__ == '__main__':
        run(doblit=False)
        run(doblit=True)
    

    Output:

    Blit = False, average FPS: 54.37
    Blit = True, average FPS: 438.27
    

提交回复
热议问题