top of page
Writer's pictureVijithkumar V

Animated Graph using the matplotlib.animation.FuncAnimation()

Let's create an animated graph as you see below.


Importing the necessary modules

These are the necessary modules to perform this programming task: 1. Numpy to be imported as np, 2. pyplot class of matplotlib as plt, 3. animation class of matplotlib as animation.

import numpy as np

import matplotlib.pyplot as plt

import matplotlib.animation as animation

Generating the datapoints

We use linspace function of the Numpy library to generate an evenly-spaced array of a certain number of numerical objects. Here we have generated 100 numerical objects between 0 (including) and 10. These are the x-values.

Then for the y-value, we have generated values by passing the x-values to a sine() function of the np library.

# Some example data

x = np.linspace(0, 10, 100)

y_plot1_fourier = np.sin(x)


Setting the variables for the lower and the upper x-limit

Now, we are going to set variable that are going to be the lower and the upper x-limits. This is for the initial couple of frames, until the nth value of the x-value is greater than the upper x-limit.

x_l_plot = 0

x_u_plot = 5

Creating instances of figure and axis and setting the x-limits and y-limits

We create an instance of figure and axis by using the subplots() function of pyplot.

Then we set the x-axis limit by using the set_xlim function. Then we set the y-axis limit using the set_ylim function.

# Create a figure and axis

fig, ax = plt.subplots()

ax.set_xlim([x_l_plot, x_u_plot])

ax.set_ylim(-1.5, 1.5)

Using the plot() to plot a lineplot

Using the plot() we plot a lineplot. The x-values and the y-values are dynamically added. Therefore empty lists are added as arguments to the plot() function.

# Create a plot (line plot in this case)

line, = ax.plot([], [], label='y_plot1_fourier', c='r', linewidth=2)

Invoking the FuncAnimation function to draw animated graph.

Next we invoke the FuncAnimation function of the animation class of the matplotlib library.

The parameters are: 1. figure instance to draw the animated graph. 2. a function to be invoked such that the data are generated iteratively for each frame, and the x-limits are set dynamically. 3. frames: this is the total number of data points on the x-axis. If it is a list of data points, you can use the len(); for a numpy array, you can use the size function. For every iteration through the frames, a certain number of data-points are set to the plot(). 4. interval this is the interval between frames. A smaller value cause frame transition faster and therefore a faster animated graph. 5. Blit: when Blit is set to True, it only redraws the artists returned by the function, and it does not draw the frame. When you run the code version, where Blit is set to True, you can observe that the x-axis remains unchanged. This happens because only the artist (Line2D here) is drawn, and the entire frame is not re-drawn.

ani = animation.FuncAnimation(fig, func, frames=len(x), interval=200, blit=False)

The function parameter

Here the x-data and y-data are iteratively updated. Then axis limit is set. When the x-value becomes greater than the upper x-axis limit, the whole x-axis limit is reset: the lower bound is set to x[n] - x_u_plot, and the upper bound is x[n]. But, in the example code, as you can see, the conditional is such that when x[n] > x_u_plot - 3, the whole axis is reset; and corresponding changes have been made to the axis limit.

# Function to update the plot for each frame

def func(n):

    line.set_data(x[0:n], y_plot1_fourier[0:n])

    if x[n] > x_u_plot - 3:

        ax.set_xlim(x[n] - (x_u_plot - 3), x[n] + 3)

    else:

        ax.set_xlim(x_l_plot, x_u_plot)


    return line

The complete code


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


# Some example data
x = np.linspace(0, 10, 100)
y_plot1_fourier = np.sin(x)


x_l_plot = 0
x_u_plot = 5


# Create a figure and axis
fig, ax = plt.subplots()
ax.set_xlim([x_l_plot, x_u_plot])
ax.set_ylim(-1.5, 1.5)


# Create a plot (line plot in this case)
line, = ax.plot([], [], label='y_plot1_fourier', c='r', linewidth=2)


# Function to update the plot for each frame
def func(n):


    line.set_data(x[0:n], y_plot1_fourier[0:n])

    if x[n] > x_u_plot - 3:

        ax.set_xlim(x[n] - (x_u_plot - 3), x[n] + 3)

    else:

        ax.set_xlim(x_l_plot, x_u_plot)


    return line


# Create the animation
ani = animation.FuncAnimation(fig, func, frames=len(x), interval=200, blit=False)

plt.show()

The code version that has blit parameter set to True

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


# Some example data
x = np.linspace(0, 10, 100)
y_plot1_fourier = np.sin(x)


x_l_plot = 0
x_u_plot = 5


# Create a figure and axis
fig, ax = plt.subplots()
ax.set_xlim([x_l_plot, x_u_plot])
ax.set_ylim(-1.5, 1.5)


# Create a plot (line plot in this case)
line, = ax.plot([], [], label='y_plot1_fourier', c='r', linewidth=2)


# Function to update the plot for each frame
def func(n):


    line.set_data(x[0:n], y_plot1_fourier[0:n])

    if x[n] > x_u_plot - 3:

        ax.set_xlim(x[n] - (x_u_plot - 3), x[n] + 3)

    else:

        ax.set_xlim(x_l_plot, x_u_plot)


    return line,


# Create the animation
ani = animation.FuncAnimation(fig, func, frames=len(x), interval=200, blit=True)

plt.show()


Comments


bottom of page