Python: matplotlib - loop, clear and show different plots over the same figure

15,905

There are essentially two different ways to create animations in matplotlib

interactive mode

Turning on interactive more is done using plt.ion(). This will create a plot even though show has not yet been called. The plot can be updated by calling plt.draw() or for an animation, plt.pause().

import matplotlib.pyplot as plt

x = [1,1]
y = [1,2]

fig, (ax1,ax2) = plt.subplots(nrows=2, sharex=True, sharey=True)
line1, = ax1.plot(x)
line2, = ax2.plot(y)
ax1.set_xlim(-1,17)
ax1.set_ylim(-400,3000)
plt.ion()

for i in range(15):
    x.append(x[-1]+x[-2])
    line1.set_data(range(len(x)), x)
    y.append(y[-1]+y[-2])
    line2.set_data(range(len(y)), y)

    plt.pause(0.1)

plt.ioff()    
plt.show()

FuncAnimation

Matplotlib provides an animation submodule, which simplifies creating animations and also allows to easily save them. The same as above, using FuncAnimation would look like:

import matplotlib.pyplot as plt
import matplotlib.animation

x = [1,1]
y = [1,2]

fig, (ax1,ax2) = plt.subplots(nrows=2, sharex=True, sharey=True)
line1, = ax1.plot(x)
line2, = ax2.plot(y)
ax1.set_xlim(-1,18)
ax1.set_ylim(-400,3000)


def update(i):
    x.append(x[-1]+x[-2])
    line1.set_data(range(len(x)), x)
    y.append(y[-1]+y[-2])
    line2.set_data(range(len(y)), y)

ani = matplotlib.animation.FuncAnimation(fig, update, frames=14, repeat=False)   
plt.show()

An example to animate a sine wave with changing frequency and its power spectrum would be the following:

import matplotlib.pyplot as plt
import matplotlib.animation
import numpy as np

x = np.linspace(0,24*np.pi,512)
y = np.sin(x)

def fft(x):
    fft = np.abs(np.fft.rfft(x))
    return fft**2/(fft**2).max()

fig, (ax1,ax2) = plt.subplots(nrows=2)
line1, = ax1.plot(x,y)
line2, = ax2.plot(fft(y))
ax2.set_xlim(0,50)
ax2.set_ylim(0,1)

def update(i):
    y = np.sin((i+1)/30.*x)
    line1.set_data(x,y)
    y2 = fft(y)
    line2.set_data(range(len(y2)), y2)

ani = matplotlib.animation.FuncAnimation(fig, update, frames=60, repeat=True)  
plt.show()

enter image description here

Share:
15,905
johananj
Author by

johananj

I work on Speech Technology. Fell in love with coding couple of years back. I make music when i'm free.

Updated on June 06, 2022

Comments

  • johananj
    johananj almost 2 years

    I want to see how a plot varies with different values using a loop. I want to see it on the same plot. But i do not want to remains of the previous plot in the figure. In MATLAB this is possible by creating a figure and just plotting over the same figure. Closing it when the loop ends.

    Like,

    fh = figure();
    %for loop here
    %do something with x and y    
    subplot(211), plot(x);
    subplot(212), plot(y); 
    pause(1)
    %loop done
    close(fh);
    

    I am not able to find the equivalent of this in matplotlib. Usually all the questions are related to plotting different series on the same plot, which seems to come naturally on matplotlib, by plotting several series using plt.plot() and then showing them all finally using plt.show(). But I want to refresh the plot.

  • johananj
    johananj almost 7 years
    Yes this is fine. But i need the plot cleared for every loop. I don't need to see the old points. In your case, you are updating a line as it grows, What if for each value in the for loop, there is a totally different line. ? I want to see that. For example, I generate a sine wave and i change the frequency of it each time in the loop and I want to see the trend of the peak moving in the frequency domain. Something along those lines.
  • johananj
    johananj almost 7 years
    Yes i want this to happen automatically, using a pause command. I do not want to close it manually. It would be ideal if the same figure is cleared and the new image can be plotted in it.
  • Mr K.
    Mr K. almost 7 years
    Well a simple way to do that would be adding before the next plot a delay, using maybe time.sleep, then closing the old plot before drawing the next one.
  • ImportanceOfBeingErnest
    ImportanceOfBeingErnest almost 7 years
    You may have misunderstood the examples. They update the line data. So there are no old points shown. If the data from one step to the next changes completely, the updated line will equally change completely, always showing the actual data set to it.
  • ImportanceOfBeingErnest
    ImportanceOfBeingErnest almost 7 years
    I updated the answer with an example of what I think you are looking for when asking about the "trend peak moving".
  • johananj
    johananj almost 7 years
    Hey. Awesome. Thank You. I got it. Yes i misunderstood it. Sorry about that. Yes, updating the line data, that is what i did now and I was able to do it. I did not know about the following types before this: <class 'matplotlib.figure.Figure'>, <class 'matplotlib.axes._subplots.AxesSubplot'>, <class 'matplotlib.lines.Line2D'>. I was going through your example line by line. Good one.Thanks again.
  • johananj
    johananj almost 7 years
    Thanks for the updated answer. I did not try the animations method yet. I will go through them soon. Looks really interesting. For now, I got what I needed with the first method itself. Something along the lines of MATLAB. I 'accepted' your answer as well.