CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-matplotlib

Comprehensive Python library for creating static, animated, and interactive visualizations

Pending
Overview
Eval results
Files

animation.mddocs/

Animation and Interactivity

Creating animated plots and interactive visualizations. Matplotlib provides comprehensive animation capabilities through function-based and artist-based approaches, with support for various export formats and interactive backends.

Capabilities

Animation Base Classes

Core animation framework for creating animated visualizations.

import matplotlib.animation as manimation

class Animation:
    def __init__(self, fig, event_source=None, blit=False):
        """Base class for all animations."""
    
    def save(self, filename, writer=None, fps=None, dpi=None, codec=None,
            bitrate=None, extra_args=None, metadata=None, extra_anim=None,
            savefig_kwargs=None, *, progress_callback=None) -> None:
        """Save the animation to a file."""
    
    def to_html5_video(self, embed_limit=None) -> str:
        """Convert animation to HTML5 video."""
    
    def to_jshtml(self, fps=None, embed_frames=True, default_mode=None) -> str:
        """Generate HTML representation with JavaScript controls."""
    
    def pause(self) -> None:
        """Pause the animation."""
    
    def resume(self) -> None:
        """Resume the animation."""

class TimedAnimation(Animation):
    def __init__(self, fig, interval=200, repeat_delay=0, repeat=True,
                event_source=None, *args, **kwargs):
        """Base class for timed animations."""
    
    def _draw_frame(self, framedata) -> None:
        """Draw a single frame of the animation."""

Function-Based Animation

Animation using a function that is called repeatedly to update the plot.

class FuncAnimation(TimedAnimation):
    def __init__(self, fig, func, frames=None, init_func=None, fargs=None,
                save_count=None, *, cache_frame_data=True, **kwargs):
        """Animation by repeatedly calling a function."""
    
    def new_frame_seq(self):
        """Return a new sequence of frame information."""
    
    def new_saved_frame_seq(self):
        """Return a new sequence of saved frame information."""

# Convenience function
def FuncAnimation(fig, func, frames=None, init_func=None, fargs=None,
                 interval=200, repeat_delay=0, repeat=True, blit=False,
                 save_count=None, cache_frame_data=True) -> FuncAnimation:
    """Animate by repeatedly calling function func."""

Artist-Based Animation

Animation using a list of artists that are shown sequentially.

class ArtistAnimation(TimedAnimation):
    def __init__(self, fig, artists, interval=200, repeat_delay=0, repeat=True,
                blit=False):
        """Animation using a list of artists."""
    
    def new_frame_seq(self):
        """Return a new sequence of artists."""
    
    def new_saved_frame_seq(self):
        """Return a new sequence of saved artists."""

# Convenience function  
def ArtistAnimation(fig, artists, interval=200, repeat_delay=0, repeat=True,
                   blit=False) -> ArtistAnimation:
    """Animate by sequentially displaying a list of artists."""

Writer Classes

Classes for saving animations to various file formats.

class Writer:
    def __init__(self, fps=5, codec=None, bitrate=None, extra_args=None,
                metadata=None):
        """Base class for animation writers."""
    
    def setup(self, fig, outfile, dpi=None) -> None:
        """Setup for writing the animation."""
    
    def grab_frame(self, **kwargs) -> None:
        """Grab the current frame."""
    
    def finish(self) -> None:
        """Finish writing the animation."""

class MovieWriter(Writer):
    def __init__(self, fps=5, codec=None, bitrate=None, extra_args=None,
                metadata=None):
        """Base class for movie writers using external tools."""

class FFMpegWriter(MovieWriter):
    def __init__(self, fps=5, codec=None, bitrate=None, extra_args=None,
                metadata=None):
        """Writer using FFmpeg for video encoding."""

class ImageMagickWriter(MovieWriter):
    def __init__(self, fps=5, codec=None, bitrate=None, extra_args=None,
                metadata=None):
        """Writer using ImageMagick for GIF creation."""

class PillowWriter(Writer):
    def __init__(self, fps=5, codec=None, bitrate=None, extra_args=None,
                metadata=None):
        """Writer using Pillow for GIF creation."""

class HTMLWriter(Writer):
    def __init__(self, fps=5, codec=None, bitrate=None, extra_args=None,
                metadata=None, embed_frames=False):
        """Writer for HTML with JavaScript controls."""

Interactive Widgets

Interactive controls and widgets for plot manipulation.

from matplotlib.widgets import *

class Button:
    def __init__(self, ax, label, image=None, color='0.85', hovercolor='0.95'):
        """Clickable button widget."""
    
    def on_clicked(self, func) -> None:
        """Connect function to button click event."""

class Slider:
    def __init__(self, ax, label, valmin, valmax, valinit=0.5, valfmt=None,
                closedmin=True, closedmax=True, slidermin=None, slidermax=None,
                dragging=True, valstep=None, orientation='horizontal',
                initcolor='r', track_color='lightgrey', handle_style='round'):
        """Slider widget for continuous value selection."""
    
    def on_changed(self, func) -> None:
        """Connect function to slider value change event."""
    
    def set_val(self, val) -> None:
        """Set slider value."""

class CheckButtons:
    def __init__(self, ax, labels, actives=None):
        """Check button widget for multiple boolean selections."""
    
    def on_clicked(self, func) -> None:
        """Connect function to check button click event."""

class RadioButtons:
    def __init__(self, ax, labels, active=0, activecolor='blue'):
        """Radio button widget for single selection from multiple options."""
    
    def on_clicked(self, func) -> None:
        """Connect function to radio button selection event."""

class TextBox:
    def __init__(self, ax, label, initial='', color='.95', hovercolor='1',
                label_pad=.01, textalignment='left'):
        """Text input widget."""
    
    def on_text_change(self, func) -> None:
        """Connect function to text change event."""
    
    def on_submit(self, func) -> None:
        """Connect function to text submission event."""

Usage Examples

Basic Function Animation

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

# Set up the figure and axis
fig, ax = plt.subplots()
x = np.linspace(0, 2*np.pi, 100)
line, = ax.plot(x, np.sin(x))

ax.set_ylim(-2, 2)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_title('Animated Sine Wave')

def animate(frame):
    """Animation function called sequentially."""
    # Update the y data with a phase shift
    y = np.sin(x + frame * 0.1)
    line.set_ydata(y)
    return line,

def init():
    """Initialize animation - return the artists to be animated."""
    line.set_ydata(np.sin(x))
    return line,

# Create animation
anim = animation.FuncAnimation(fig, animate, init_func=init,
                              frames=200, interval=50, blit=True, repeat=True)

# Display the animation
plt.show()

# Save as GIF (optional)
# anim.save('sine_wave.gif', writer='pillow', fps=20)

Multiple Plot Animation

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

# Create subplots
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))

# Data setup
x = np.linspace(0, 2*np.pi, 100)
line1, = ax1.plot(x, np.sin(x), 'b-', label='sin(x)')
line2, = ax1.plot(x, np.cos(x), 'r-', label='cos(x)')
ax1.set_ylim(-2, 2)
ax1.set_title('Trigonometric Functions')
ax1.legend()
ax1.grid(True)

# Scatter plot setup
scat = ax2.scatter([], [], s=100, alpha=0.7)
ax2.set_xlim(-2, 2)
ax2.set_ylim(-2, 2)
ax2.set_title('Moving Points')
ax2.grid(True)

def animate(frame):
    """Animate both subplots."""
    # Update trigonometric plots
    phase = frame * 0.1
    line1.set_ydata(np.sin(x + phase))
    line2.set_ydata(np.cos(x + phase))
    
    # Update scatter plot
    n_points = 20
    theta = np.linspace(0, 2*np.pi, n_points) + phase
    x_scat = 1.5 * np.cos(theta)
    y_scat = 1.5 * np.sin(theta)
    
    # Update scatter plot data
    scat.set_offsets(np.column_stack((x_scat, y_scat)))
    
    return line1, line2, scat

# Create and run animation
anim = animation.FuncAnimation(fig, animate, frames=200, interval=100, blit=True)
plt.tight_layout()
plt.show()

Artist Animation Example

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

# Generate data for multiple frames
fig, ax = plt.subplots()

# Create list of artists for each frame
artists = []
for i in range(50):
    # Generate data for this frame
    x = np.linspace(0, 10, 100)
    y = np.sin(x + i * 0.2) * np.exp(-x/10)
    
    # Create line artist
    line, = ax.plot(x, y, 'b-')
    title = ax.text(0.5, 0.9, f'Frame {i+1}', transform=ax.transAxes, 
                   ha='center', fontsize=14)
    
    # Add both line and title to this frame's artists
    artists.append([line, title])

ax.set_xlim(0, 10)
ax.set_ylim(-1.5, 1.5)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.grid(True)

# Create artist animation
anim = animation.ArtistAnimation(fig, artists, interval=100, blit=True, repeat=True)
plt.show()

Interactive Animation with Widgets

import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.widgets import Slider, Button
import numpy as np

# Create figure and subplots
fig = plt.figure(figsize=(12, 8))
ax_plot = plt.subplot2grid((4, 4), (0, 0), colspan=4, rowspan=3)
ax_slider1 = plt.subplot2grid((4, 4), (3, 0), colspan=2)
ax_slider2 = plt.subplot2grid((4, 4), (3, 2), colspan=2)

# Initial parameters
x = np.linspace(0, 4*np.pi, 200)
freq_init = 1.0
amp_init = 1.0

# Create initial plot
line, = ax_plot.plot(x, amp_init * np.sin(freq_init * x), 'b-', linewidth=2)
ax_plot.set_xlim(0, 4*np.pi)
ax_plot.set_ylim(-3, 3)
ax_plot.set_xlabel('X')
ax_plot.set_ylabel('Amplitude')
ax_plot.set_title('Interactive Animated Sine Wave')
ax_plot.grid(True)

# Animation variables
anim_running = True
phase = 0

# Create sliders
slider_freq = Slider(ax_slider1, 'Frequency', 0.1, 5.0, valinit=freq_init)
slider_amp = Slider(ax_slider2, 'Amplitude', 0.1, 3.0, valinit=amp_init)

def animate(frame):
    """Animation function."""
    global phase
    if anim_running:
        phase += 0.1
        freq = slider_freq.val
        amp = slider_amp.val
        y = amp * np.sin(freq * x + phase)
        line.set_ydata(y)
    return line,

def update_freq(val):
    """Update frequency from slider."""
    pass  # Animation function will read slider value

def update_amp(val):
    """Update amplitude from slider."""
    pass  # Animation function will read slider value

# Connect sliders
slider_freq.on_changed(update_freq)
slider_amp.on_changed(update_amp)

# Create animation
anim = animation.FuncAnimation(fig, animate, frames=1000, interval=50, 
                              blit=True, repeat=True)

plt.tight_layout()
plt.show()

3D Animation

import matplotlib.pyplot as plt
import matplotlib.animation as animation
from mpl_toolkits.mplot3d import Axes3D
import numpy as np

# Create 3D plot
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')

# Generate 3D data
def generate_data(frame):
    """Generate 3D surface data for given frame."""
    x = np.linspace(-5, 5, 50)
    y = np.linspace(-5, 5, 50)
    X, Y = np.meshgrid(x, y)
    
    # Create animated wave
    t = frame * 0.1
    Z = np.sin(np.sqrt(X**2 + Y**2) - t) * np.exp(-0.1 * np.sqrt(X**2 + Y**2))
    
    return X, Y, Z

# Initial plot
X, Y, Z = generate_data(0)
surface = ax.plot_surface(X, Y, Z, cmap='viridis', alpha=0.8)

ax.set_xlim(-5, 5)
ax.set_ylim(-5, 5)
ax.set_zlim(-1, 1)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_title('3D Animated Wave')

def animate(frame):
    """Animate 3D surface."""
    ax.clear()
    
    X, Y, Z = generate_data(frame)
    surface = ax.plot_surface(X, Y, Z, cmap='viridis', alpha=0.8)
    
    ax.set_xlim(-5, 5)
    ax.set_ylim(-5, 5)
    ax.set_zlim(-1, 1)
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Z')
    ax.set_title(f'3D Animated Wave - Frame {frame}')
    
    return surface,

# Create animation
anim = animation.FuncAnimation(fig, animate, frames=100, interval=100, blit=False)
plt.show()

Saving Animations

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

# Create simple animation
fig, ax = plt.subplots()
x = np.linspace(0, 2*np.pi, 100)
line, = ax.plot(x, np.sin(x))
ax.set_ylim(-2, 2)

def animate(frame):
    y = np.sin(x + frame * 0.1)
    line.set_ydata(y)
    return line,

anim = animation.FuncAnimation(fig, animate, frames=100, interval=50, blit=True)

# Save as MP4 (requires ffmpeg)
try:
    anim.save('animation.mp4', writer='ffmpeg', fps=20, bitrate=1800)
    print("Saved as MP4")
except:
    print("FFmpeg not available")

# Save as GIF (requires Pillow or ImageMagick)
try:
    anim.save('animation.gif', writer='pillow', fps=20)
    print("Saved as GIF")
except:
    print("Pillow not available")

# Save as HTML with JavaScript controls
anim.save('animation.html', writer='html', fps=20, embed_frames=True)
print("Saved as HTML")

plt.show()

Install with Tessl CLI

npx tessl i tessl/pypi-matplotlib

docs

3d-plotting.md

animation.md

backends.md

colors-styling.md

index.md

object-oriented.md

pyplot.md

shapes.md

tile.json