Created: 2026-07-08 Wed 15:35
We can create animations in software like blender and its dedicated workflow: .
Here we want to use a different approach by using the manim library which allows to create impressive animations.
We have a running script to run those simulations viz_graph.py.
manim is mathematical animation engineering — a Python library for creating beautiful mathematical animations for presentations.
| Feature | Purpose | |
|---|---|---|
| LaTeX Integration | Mathematical notation | AMSP |
| Scene Architecture | Modular scene organization | AMSP |
| Vector Graphics | Crisp animations for all sizes | AMSP |
| Custom Shaders | Advanced visual effects | AMSP |
| Interactive Mode | Live preview before rendering | AMSP |
| Web Export | Share via URL | AMSP |
| Audio Sync | Music synchronization | AMSP |
We install manim on ubuntu
# Ubuntu/Debian (Jetson required)
sudo apt-get update
sudo apt-get install python3-pip build-essential ffmpeg libpng-dev libjpeg-dev
python3 -m pip install manim
python3 -m pip install manim-rl
Test the application .
# Verify installation
python3 -c "from manim import *; print('Manim installed!')"
Manim installed!
# Check requirements
python3 --version # Python 3.8+
manim --version # Manim 0.17.0+
# Recommended packages
pip install numpy matplotlib pillow colorama
pip install imageio[ffmpeg]
Python 3.14.4Manim Community v0.20.1
Inside manim_animations.py we have the different classes we want to animate.
We launch a simple splash screen
manim -pql manim_animations.py IntroScene
# # Export to GIF
#manim -pql manim_animations.py -o --write_to_movie=false
manim -pql manim_animations.py SensorNetworkScene
manim -pql manim_animations.py MQTTFlowScene
manim -pql manim_animations.py BridgeArchitecture
manim -pql manim_animations.py FullAnimation
from manim import Circle, ScaleInPlace, MoveAlongPath, FadeOut, BLUE
object = Circle(color=BLUE)
self.play(Create(object))
self.play(ScaleInPlace(object, scale=2, run_time=1))
self.play(MoveAlongPath(object, object.get_center()))
self.play(FadeOut(object))
# Text animation effects
effects = [
Write, # Basic write
FadeIn, # Fade in
Create, # Create (for Dashed/Arrow)
Transform, # Transform between objects
]
for effect in effects:
self.play(effect(text_object))
from manim import *
# Create two objects
old_text = Text("Old", font_size=36)
new_text = Text("New", font_size=36)
# Animation transform
self.play(
ReplacementTransform(old_text, new_text),
run_time=2
)
# Create staggered animation
objects = VGroup(*[
Text(str(i), font_size=24)
for i in range(10)
])
objects.arrange(LEFT, buff=0.5)
# Create with lag
self.play(
*(Create(obj)
for obj in objects),
lag_ratio=0.1
)
```
from manim import *
import itertools
# Create color schemes
colors = {
'IoT': COLOR_PALETTE,
'Sensor': RED,
'Audio': GREEN,
'Network': BLUE,
}
# Generate theme
theme = VPC(colors.values())
# Use custom colors
red = RED
blue = BLUE
green = GREEN
yellow = YELLOW
purple = PURPLE
white = WHITE
black = BLACK
# Style text
text = Text(
"Blender Twin",
color=THEME_COLORS,
font_size=48
)
```
# Font settings
text = Text(
"Title",
font="Arial",
font_size=48,
font_weight=300, # Thin
shadow=False
)
# Gradient text
gradient = Text(
"Gradient",
color_gradient=[RED, BLUE],
gradient_width=WIDTH
)
# Shadow text
shadows = Text(
"Shadow",
shadow=False,
shadow_color=BLACK,
shadow_type=2
)
# Background effects
background = Square(
color=WHITE
).set_stroke(
color=BLACK,
width=0.1
)
background_with_gradient = Square(
color=WHITE
).set_fill(
color=BLUE,
opacity=0.5
)
```
from manim import *
import os
class MusicScene(Scene):
"""Scene with background music."""
def construct(self):
# Add background music
music = Sound.from_file(
"background.mp3",
fade_in=2,
fade_out=2
)
# Create scene content
title = Text(
"Blender Twin IoT",
font_size=60
)
# Add to scene
self.play(Create(title))
# Fade out
self.play(FadeOut(title))
```
# VOX file recording
from manim import *
class VoiceoverScene(Scene):
"""Scene with voiceover narration."""
def construct(self):
# Create narration
narration = VOX(
"Hello, this is the Blender Twin IoT project.",
"We are demonstrating the architecture."
)
self.play(VOX.narrate(narration))
```
# Render with high quality
manim -pql IntroScene IntroScene
# Export formats
manim -pql -q IntroScene --write_to_movies=false
manim -pql IntroScene IntroScene -o
# Create GIF animation
manim -pql IntroScene IntroScene --write_to_movie=false -g
# Export to different formats
manim -pql IntroScene IntroScene --output_format=mp4
manim -pql IntroScene IntroScene --output_format=gif
```
# Upload to YouTube/Vimeo
manim -pql IntroScene IntroScene
# Upload to YouTube
python3 -c "
from manim import *
import subprocess
subprocess.run(['ffmpeg'] + [
'-i', 'output.mp4',
'-vf', 'fps=30,scale=1280:720',
'-y', 'output.mp4'
])
"
```
from manim import *
import numpy as np
class ShaderScene(Scene):
"""Scene with custom shaders."""
def construct(self):
# Create shader material
shader = ShaderMaterial(
shader_code="""
#version 330
in vec4 vertex;
in vec4 color;
out vec4 vColor;
void main() {
vColor = color;
}
""",
vertex_shader="""
#version 330
in vec4 vertex;
out vec4 color;
void main() {
gl_Position = vertex;
color = vec4(1.0);
}
""",
frag_shader="""
#version 330
in vec4 color;
out vec4 fragColor;
void main() {
fragColor = color;
}
""",
)
# Animate shader material
self.play(Create(shader))
```
from manim import *
import random
class ParticleScene(Scene):
"""Scene with particle effects."""
def construct(self):
# Create particle system
particles = VGroup(*[
Dot(
point=np.random.random(3) * 3,
radius=random.uniform(0.5, 1),
color=BLUE
)
for _ in range(50)
])
# Animate particles
self.play(Create(particles))
self.play(
ReplaceByColor(
particles,
PARTICLE_EFFECT[1, 0.5, WHITE]
),
rate_func=ease_in
)
```
from manim import *
class MQTTFlow(Scene):
"""Demonstrate MQTT pub/sub for Blender Twin sensors."""
def construct(self):
# Create MQTT broker
broker = Text("MQTT Broker", font_size=72, color=YELLOW)
broker.to_edge(UR)
# Create MQTT topics
topics = VGroup(
Text("axoloti/audio", font_size=36),
Text("daisy/sensor", font_size=36),
Text("xiao/bat", font_size=36),
)
# Position topics
topics.arrange(DOWN, buff=0.5, aligned_edge=LEFT)
topics[0].shift(LEFT * 4)
topics[1].shift(LEFT * 4)
topics[2].shift(LEFT * 4)
# Create arrows
arrows = VGroup(*[
Arrow(UP, DOWN, color=GREEN,buff=0.2)
for i in range(3)
])
```
from manim import *
class HardwareConfig(Scene):
"""Showcase all available components."""
def construct(self):
# Title
title = Text("Blender Twin Hardware", font_size=60, color=YELLOW)
title.to_edge(UP)
self.play(Write(title))
# Component nodes
nodes = VGroup(
Text("ESP32-WROOM", font_size=80, color=RED),
Text("daisy_seed", font_size=80, color=GREEN),
Text("axoloti", font_size=80, color=BLUE),
Text("xiao", font_size=80, color=PURPLE),
)
# Configure positions
nodes[0].to_edge(DOWN)
nodes[1].to_edge(DL)
nodes[2].to_edge(UR)
nodes[3].to_edge(DR)
# Animate creation
self.play(Create(nodes[0]))
self.play(Create(nodes[1]))
self.play(Create(nodes[2]))
self.play(Create(nodes[3]))
# Connect with lines
self.play(Create(Arrow(nodes[0], nodes[1], color=YELLOW)))
self.play(Create(Arrow(nodes[0], nodes[2], color=YELLOW)))
self.play(Create(Arrow(nodes[0], nodes[3], color=YELLOW)))
# Show connections
self.wait(3)
self.play(FadeOut(title))
```
# 1. Keep animations simple
# Create clear single-message flows
self.play(Create(obj), run_time=0.5)
# 2. Use clear timing
# Slow down for reading
self.wait(1.5)
# 3. Add context
# Show what's happening
AddText(Tex("Temperature: 22.5°C"))
# 4. Test iteratively
# Preview before final render
manim -pql IntroScene IntroScene
# 5. Use appropriate fonts
text = Text("Font", font="DejaVu Sans")
# 6. Use appropriate colors
text = Text("Color", color=THEME_COLORS)
# 7. Add captions
caption = Captions(text)
self.play(Create(caption))
```
# Issue: Manim fails to render
# Solution: Check dependencies
pip install manim-legacy imageio[ffmpeg]
# Issue: Low quality rendering
# Solution: Increase quality flags
manim -pql [scene] [scene_name]
# Issue: No video output
# Solution: Render with write_to_movie flag
manim -pql [scene] --write_to_movies
# Issue: Slow rendering
# Solution: Use low quality preview
manim -pql [scene]
```
# High quality rendering (for final video)
manim -pql -q IntroScene IntroScene
# Low quality (for preview)
manim -pql IntroScene IntroScene
# Optimize for GPU
manim -v IntroScene IntroScene
# Use multiprocessing
env PYTHONPATH MANIM_RENDERER=ffmpeg
```
| Concept | Usage | |
|---|---|---|
| Scene | Animation container | AMSP |
| Play | Animation method | AMSP |
| Create | Object creation | AMSP |
| Write | Text animation | AMSP |
| Replace | Object transformation | AMSP |
| Fading | Object fade in/out | AMSP |
| Arrow | Connection lines | AMSP |
| VGroup | Object grouping | AMSP |
```
```
All animations can be used in Blender Twin presentations to: