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

前端 未结 12 1225
天命终不由人
天命终不由人 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:59

    If you want draw and not freeze your thread as more point are drawn you should use plt.pause() not time.sleep()

    im using the following code to plot a series of xy coordinates.

    import matplotlib.pyplot as plt 
    import math
    
    
    pi = 3.14159
    
    fig, ax = plt.subplots()
    
    x = []
    y = []
    
    def PointsInCircum(r,n=20):
        circle = [(math.cos(2*pi/n*x)*r,math.sin(2*pi/n*x)*r) for x in xrange(0,n+1)]
        return circle
    
    circle_list = PointsInCircum(3, 50)
    
    for t in range(len(circle_list)):
        if t == 0:
            points, = ax.plot(x, y, marker='o', linestyle='--')
            ax.set_xlim(-4, 4) 
            ax.set_ylim(-4, 4) 
        else:
            x_coord, y_coord = circle_list.pop()
            x.append(x_coord)
            y.append(y_coord)
            points.set_data(x, y)
        plt.pause(0.01)
    
    0 讨论(0)
  • 2020-11-22 02:01

    Here is a version that I got to work on my system.

    import matplotlib.pyplot as plt
    from drawnow import drawnow
    import numpy as np
    
    def makeFig():
        plt.scatter(xList,yList) # I think you meant this
    
    plt.ion() # enable interactivity
    fig=plt.figure() # make a figure
    
    xList=list()
    yList=list()
    
    for i in np.arange(50):
        y=np.random.random()
        xList.append(i)
        yList.append(y)
        drawnow(makeFig)
        #makeFig()      The drawnow(makeFig) command can be replaced
        #plt.draw()     with makeFig(); plt.draw()
        plt.pause(0.001)
    

    The drawnow(makeFig) line can be replaced with a makeFig(); plt.draw() sequence and it still works OK.

    0 讨论(0)
  • 2020-11-22 02:01

    An example use-case to plot CPU usage in real-time.

    import time
    import psutil
    import matplotlib.pyplot as plt
    
    fig = plt.figure()
    ax = fig.add_subplot(111)
    
    i = 0
    x, y = [], []
    
    while True:
        x.append(i)
        y.append(psutil.cpu_percent())
    
        ax.plot(x, y, color='b')
    
        fig.canvas.draw()
    
        ax.set_xlim(left=max(0, i - 50), right=i + 50)
        fig.show()
        plt.pause(0.05)
        i += 1
    
    0 讨论(0)
  • 2020-11-22 02:03

    The problem seems to be that you expect plt.show() to show the window and then to return. It does not do that. The program will stop at that point and only resume once you close the window. You should be able to test that: If you close the window and then another window should pop up.

    To resolve that problem just call plt.show() once after your loop. Then you get the complete plot. (But not a 'real-time plotting')

    You can try setting the keyword-argument block like this: plt.show(block=False) once at the beginning and then use .draw() to update.

    0 讨论(0)
  • 2020-11-22 02:05

    Another option is to go with bokeh. IMO, it is a good alternative at least for real-time plots. Here is a bokeh version of the code in the question:

    from bokeh.plotting import curdoc, figure
    import random
    import time
    
    def update():
        global i
        temp_y = random.random()
        r.data_source.stream({'x': [i], 'y': [temp_y]})
        i += 1
    
    i = 0
    p = figure()
    r = p.circle([], [])
    curdoc().add_root(p)
    curdoc().add_periodic_callback(update, 100)
    

    and for running it:

    pip3 install bokeh
    bokeh serve --show test.py
    

    bokeh shows the result in a web browser via websocket communications. It is especially useful when data is generated by remote headless server processes.

    0 讨论(0)
  • 2020-11-22 02:06

    Here's the working version of the code in question (requires at least version Matplotlib 1.1.0 from 2011-11-14):

    import numpy as np
    import matplotlib.pyplot as plt
    
    plt.axis([0, 10, 0, 1])
    
    for i in range(10):
        y = np.random.random()
        plt.scatter(i, y)
        plt.pause(0.05)
    
    plt.show()
    

    Note some of the changes:

    1. Call plt.pause(0.05) to both draw the new data and it runs the GUI's event loop (allowing for mouse interaction).
    0 讨论(0)
提交回复
热议问题