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