MatPlotLib's ion() and draw() not working

后端 未结 4 1627
我在风中等你
我在风中等你 2021-01-18 08:00

I am trying to plot figures in real time using a for loop. I have the following simple code:

import matplotlib.pyplot as plt

plt.ion()
plt.figure()
for i in         


        
相关标签:
4条回答
  • 2021-01-18 08:29

    Adapted for your case from : Python realtime plotting

    import matplotlib.pyplot as plt
    import numpy as np
    import time
    
    fig = plt.figure()
    ax = fig.add_subplot(111)
    
    # some X and Y data
    x = [0]
    y = [0]
    
    li, = ax.plot(x, y,'o')
    
    # draw and show it
    fig.canvas.draw()
    plt.show(block=False)
    
    # loop to update the data
    for i in range(100):
        try:
            x.append(i)
            y.append(i)
    
            # set the new data
            li.set_xdata(x)
            li.set_ydata(y)
    
            ax.relim() 
            ax.autoscale_view(True,True,True) 
    
            fig.canvas.draw()
    
            time.sleep(0.01)
        except KeyboardInterrupt:
            plt.close('all')
            break
    
    0 讨论(0)
  • 2021-01-18 08:30

    Hey I was having the same problem, I checked other questions and my issue was solved when I plugged a pause into my solution. Here's some example code that worked for me.

    import matplotlib.pyplot as plt
    import numpy as np
    plt.ion()
    x = np.arange(0, 4*np.pi, 0.1)
    y = [np.sin(i) for i in x]
    plt.plot(x, y, 'g-', linewidth=1.5, markersize=4)
    plt.pause(0.0001)         
    plt.plot(x, [i**2 for i in y], 'g-', linewidth=1.5, markersize=4)
    plt.pause(0.0001)
    plt.plot(x, [i**2*i+0.25 for i in y], 'r-', linewidth=1.5, markersize=4) 
    plt.pause(0.0001)
    

    The solution was posted here: Matplotlib ion() and subprocesses

    0 讨论(0)
  • 2021-01-18 08:35

    This solution example has worked for me on multiple machines. Try adjusting plt.pause(...)

    import matplotlib.pyplot as plt
    import numpy as np
    
    F = lambda x: np.sin(2*x)
    
    plt.ion()    
    x = np.linspace(0, 1, 200)
    plt.plot(x, F(x))
    
    
    for i in range(100):
        if 'ax' in globals(): ax.remove()
        newx = np.random.choice(x, size = 10)
        ax = plt.scatter(newx, F(newx))
        plt.pause(0.05)
    
    plt.ioff()
    plt.show()
    
    0 讨论(0)
  • 2021-01-18 08:48

    The problem - and the solution - is highly dependent on the plot.draw() function within the Python environment and back end, and may even vary in different product releases. It manifests itself in different ways depending on the environment. The problem shows up in many places on stackoverflow with some solutions working for some people and not for others.

    The gold standard on my Windows laptop is running the Python from the command line - no IDE, just plain vanilla Python3. draw() as shown in the example always works fine there.

    If I try it in Jupyter notebook on the same machine, no amount of draw(), plot.pause(), plot.show(), or any other suggestion works. I tried %matplotlib with notebook, widget and ipympl. Nothing gets drawn until complete end of cell code execution.

    Some other sources on stackoverflow suggested using figure.canvas.flush_events(). I had some success with that and investigated further.

    The best solution turned out to be to run the draw() at the figure.canvas level instead of the axes or plot level.

    You can get the figure by creating your plot with command:

    fig, graph, = plt.subplots()
    

    or, if you've already created the plot, as in the code at the top of the ticket, put the following outside the loop:

    fig = plt.gcf() #get current figure
    

    Inside the loop, instead of plt.draw(), use

    fig.canvas.draw()
    

    It's proven reliable in my Jupyter Notebook environment even when running multiple axes/plots across multiple figures. I can drop in sleep() statements and everything appears when expected.

    Your mileage may vary.

    0 讨论(0)
提交回复
热议问题