How to update a plot in matplotlib?

后端 未结 7 1764
不思量自难忘°
不思量自难忘° 2020-11-22 02:11

I\'m having issues with redrawing the figure here. I allow the user to specify the units in the time scale (x-axis) and then I recalculate and call this function plots

相关标签:
7条回答
  • 2020-11-22 02:53

    This worked for me. Repeatedly calls a function updating the graph every time.

    import matplotlib.pyplot as plt
    import matplotlib.animation as anim
    
    def plot_cont(fun, xmax):
        y = []
        fig = plt.figure()
        ax = fig.add_subplot(1,1,1)
    
        def update(i):
            yi = fun()
            y.append(yi)
            x = range(len(y))
            ax.clear()
            ax.plot(x, y)
            print i, ': ', yi
    
        a = anim.FuncAnimation(fig, update, frames=xmax, repeat=False)
        plt.show()
    

    "fun" is a function that returns an integer. FuncAnimation will repeatedly call "update", it will do that "xmax" times.

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

    In case anyone comes across this article looking for what I was looking for, I found examples at

    How to visualize scalar 2D data with Matplotlib?

    and

    http://mri.brechmos.org/2009/07/automatically-update-a-figure-in-a-loop (on web.archive.org)

    then modified them to use imshow with an input stack of frames, instead of generating and using contours on the fly.


    Starting with a 3D array of images of shape (nBins, nBins, nBins), called frames.

    def animate_frames(frames):
        nBins   = frames.shape[0]
        frame   = frames[0]
        tempCS1 = plt.imshow(frame, cmap=plt.cm.gray)
        for k in range(nBins):
            frame   = frames[k]
            tempCS1 = plt.imshow(frame, cmap=plt.cm.gray)
            del tempCS1
            fig.canvas.draw()
            #time.sleep(1e-2) #unnecessary, but useful
            fig.clf()
    
    fig = plt.figure()
    ax  = fig.add_subplot(111)
    
    win = fig.canvas.manager.window
    fig.canvas.manager.window.after(100, animate_frames, frames)
    

    I also found a much simpler way to go about this whole process, albeit less robust:

    fig = plt.figure()
    
    for k in range(nBins):
        plt.clf()
        plt.imshow(frames[k],cmap=plt.cm.gray)
        fig.canvas.draw()
        time.sleep(1e-6) #unnecessary, but useful
    

    Note that both of these only seem to work with ipython --pylab=tk, a.k.a.backend = TkAgg

    Thank you for the help with everything.

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

    All of the above might be true, however for me "online-updating" of figures only works with some backends, specifically wx. You just might try to change to this, e.g. by starting ipython/pylab by ipython --pylab=wx! Good luck!

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

    This worked for me:

    from matplotlib import pyplot as plt
    from IPython.display import clear_output
    import numpy as np
    for i in range(50):
        clear_output(wait=True)
        y = np.random.random([10,1])
        plt.plot(y)
        plt.show()
    
    0 讨论(0)
  • 2020-11-22 03:09

    You can also do like the following: This will draw a 10x1 random matrix data on the plot for 50 cycles of the for loop.

    import matplotlib.pyplot as plt
    import numpy as np
    
    plt.ion()
    for i in range(50):
        y = np.random.random([10,1])
        plt.plot(y)
        plt.draw()
        plt.pause(0.0001)
        plt.clf()
    
    0 讨论(0)
  • 2020-11-22 03:10

    You essentially have two options:

    1. Do exactly what you're currently doing, but call graph1.clear() and graph2.clear() before replotting the data. This is the slowest, but most simplest and most robust option.

    2. Instead of replotting, you can just update the data of the plot objects. You'll need to make some changes in your code, but this should be much, much faster than replotting things every time. However, the shape of the data that you're plotting can't change, and if the range of your data is changing, you'll need to manually reset the x and y axis limits.

    To give an example of the second option:

    import matplotlib.pyplot as plt
    import numpy as np
    
    x = np.linspace(0, 6*np.pi, 100)
    y = np.sin(x)
    
    # You probably won't need this if you're embedding things in a tkinter plot...
    plt.ion()
    
    fig = plt.figure()
    ax = fig.add_subplot(111)
    line1, = ax.plot(x, y, 'r-') # Returns a tuple of line objects, thus the comma
    
    for phase in np.linspace(0, 10*np.pi, 500):
        line1.set_ydata(np.sin(x + phase))
        fig.canvas.draw()
        fig.canvas.flush_events()
    
    0 讨论(0)
提交回复
热议问题