Matplotlib - Animations



Animation is a visual technique that involves the creation of moving images through a sequence of individual frames. Each frame represents a specific moment in time, and when played consecutively at a high speed, they create the illusion of movement. For instance, a common example of an animated object is a GIF. Here is an example −

Animations Intro

The popular file formats of animations are GIFs, APNG (Animated Portable Network Graphics), mkv, mp4, and more.

Animations in Matplotlib

Matplotlib provides a dedicated module for creating animations. In this context, an animation is a series of frames, and each frame is associated with a plot on a Figure.

To integrate the animation capabilities into our working environment we can import the dedicated module by using the following command −

import matplotlib.animation as animation

Creating Animations

Creating animations in Matplotlib can be done through two different approaches. The matplotlib.animation module provides two primary classes for this purpose −

  • FuncAnimation
  • ArtistAnimation

The FuncAnimation class

The approach of Using the FuncAnimation class is an efficient way to create animations by modifying the data of a plot for each frame. It allows us to create an animation by passing a user-defined function that iteratively modifies the data of a plot. This class involves generating data for the initial frame and subsequently modifying this data for each subsequent frame.

Example

This example demonstrates the use of FuncAnimation class to animate a sine wave plot, illustrating the motion of the object. And it is also updates the X-axis values using Matplotlib animation.

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

# Creating a figure and axis
fig, ax = plt.subplots(figsize=(7, 4))

# Generating x values 
x = np.arange(0, 2*np.pi, 0.01)

# Plotting the initial sine curve
line, = ax.plot(x, np.sin(x))
ax.legend([r'$\sin(x)$'])

# Function to update the plot for each frame of the animation
def update(frame):
   line.set_ydata(np.sin(x + frame / 50))
   ax.set_xlim(left=0, right=frame)
   return line

# Creating a FuncAnimation object
ani = animation.FuncAnimation(fig=fig, func=update, frames=40, interval=30)

# Displaying the output
plt.show()
Output

The above example produces the following output −

Animations Ex1

Example

Here is another example that creates an animated 3D surface plot using FuncAnimation class.

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

# Generate data
N = 50
fps = 250
frn = 75
x = np.linspace(-2, 2, N + 1)
x, y = np.meshgrid(x, x)
zarray = np.zeros((N + 1, N + 1, frn))
f = lambda x, y, sig: 1 / np.sqrt(sig) * np.exp(-(x ** 2 + y ** 2) / sig ** 2)

# Create data array
for i in range(frn):
   zarray[:, :, i] = f(x, y, 1.5 + np.sin(i * 2 * np.pi / frn))

# Update plot function
def change_plot(frame_number, zarray, plot):
   plot[0].remove()
   plot[0] = ax.plot_surface(x, y, zarray[:, :, frame_number], cmap="afmhot_r")

# Create figure and subplot
fig = plt.figure(figsize=(7, 4))
ax = fig.add_subplot(111, projection='3d')

# Initial plot
plot = [ax.plot_surface(x, y, zarray[:, :, 0], color='0.75', rstride=1, cstride=1)]

# Set axis limits
ax.set_zlim(0, 1.1)

# Animation
ani = animation.FuncAnimation(fig, change_plot, frn, fargs=(zarray, plot), interval=1000 / fps)

# Turn off axis and grid
ax.axis('off')
ax.grid(False)

# Show plot
plt.show()
Output

The above example produces the following output −

Animations Ex5

ArtistAnimation

ArtistAnimation is a flexible approach suitable for scenarios where different artists need to be animated in a sequence. This approach involves generating a list (iterable) of artists to draw them into each frame of the animation.

Example

This example demonstrates the using of ArtistAnimation class to create the animation.

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

# Create a figure and axis
fig, ax = plt.subplots(figsize=(7,4))

# Define the function
def f(x, y):
   return np.sin(x) + np.cos(y)

# Generate x and y values for the function
x = np.linspace(0, 2 * np.pi, 180)
y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1)

# ims is a list of lists, each row is a list of artists to draw in the current frame
ims = []

# Generate frames for the animation
for i in range(60):
   x += np.pi / 10
   y += np.pi / 30
   im = ax.imshow(f(x, y), animated=True)
   if i == 0:
      ax.imshow(f(x, y))  # show an initial one first
   ims.append([im])

# Create an ArtistAnimation with the specified interval, blit, and repeat_delay
ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True, repeat_delay=1000)
# Display the animation
plt.show()
Output

The above code generates the following results −

Animations Ex2

Saving animations

Saving animation objects to disk is possible using different multimedia writers, such as Pillow, ffmpeg, and imagemagick. However, it's important to note that not all video formats are supported by every writer. There are four primary types of writers:

  • PillowWriter
  • HTMLWriter
  • Pipe-based writers
  • File-based writers

PillowWriter

It uses the Pillow library to save animations in various formats, such as GIF, APNG, and WebP.

Example

An example demonstrates animating a scatterplot and saving that as a GIF using the PillowWriter.

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

# Generate data
steps = 50
nodes = 100
positions = []
solutions = []

for i in range(steps):
   positions.append(np.random.rand(2, nodes))
   solutions.append(np.random.random(nodes))

# Create a figure and axes
fig, ax = plt.subplots(figsize=(7, 4))
marker_size = 50

# Function to update the plot for each frame of the animation
def animate(i):
   fig.clear()
   ax = fig.add_subplot(111, aspect='equal', autoscale_on=False, xlim=(0, 1), ylim=(0, 1))
   ax.set_xlim(0, 1)
   ax.set_ylim(0, 1)
   s = ax.scatter(positions[i][0], positions[i][1], s=marker_size, c=solutions[i], cmap="RdBu_r", marker="o", edgecolor='black')

plt.grid(None)

# Creating a FuncAnimation object
ani = animation.FuncAnimation(fig, animate, interval=100, frames=range(steps))

# Save the animation as a GIF using the PillowWriter
ani.save('animation.gif', writer='pillow')

If you visit the folder where the output is saved you can observe below gif file −

Output
Animation Ex3

HTMLWriter

HTMLWriter is used for creating JavaScript-based animations, supporting HTML and PNG formats. This writer is useful for embedding animations in web pages.

Pipe-based writers

These writers use external utilities like FFMpegWriter and ImageMagickWriter to create animations. They support various video formats and frames are piped to the utility, which stitches them together to create the animation.

File-based writers

File-based writers (FFMpegFileWriter and ImageMagickFileWriter) are slightly slower but offer the advantage of saving each frame before creating the final animation.

Example

The following example shows how to properly enable ffmpeg for matplotlib.animation. Here the plot is created with an animated image matrix and the animated colorbar.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from mpl_toolkits.axes_grid1 import make_axes_locatable

plt.rcParams["figure.figsize"] = [7.50, 3.50]
plt.rcParams["figure.autolayout"] = True
plt.rcParams['animation.ffmpeg_path'] = 'ffmpeg'

fig = plt.figure()
ax = fig.add_subplot(111)
div = make_axes_locatable(ax)
cax = div.append_axes('right', '5%', '5%')
data = np.random.rand(5, 5)
im = ax.imshow(data)
cb = fig.colorbar(im, cax=cax)
tx = ax.set_title('Frame 0')

cmap = ["copper", 'RdBu_r', 'Oranges', 'cividis', 'hot', 'plasma']

def animate(i):
   cax.cla()
   data = np.random.rand(5, 5)
   im = ax.imshow(data, cmap=cmap[i%len(cmap)])
   fig.colorbar(im, cax=cax)
   tx.set_text('Frame {0}'.format(i))

ani = animation.FuncAnimation(fig, animate, frames=10)
FFwriter = animation.FFMpegWriter()
ani.save('plot.mp4', writer=FFwriter)
Output

On executing the above code you will get the following output −

animations_ex4
Advertisements