title: “Connect The Dot Animation” format: revealjs editor: visual
Introduction
The “Connect the Dots” animation visually demonstrates three different methods of linking data points: sequentially, by forming geometric shapes, and through random connections. This animation highlights how the same data can be interpreted and visualized in multiple ways depending on the context and purpose. It’s useful for teaching core data visualization concepts, showing patterns or randomness, and emphasizing the flexibility of visual storytelling with data. By engaging viewers visually, it encourages creative thinking about structure, relationships, and meaning in datasets, making it a valuable tool in both education and data science communication.
Imports and Setup
from manim import *
import numpy as np
import random
Explanation:
from manim import *
– Imports all core Manim classes (e.g., Scene, Dot, Line, Text, etc.), providing access to animation and rendering tools.import numpy as np
– Provides numerical functions for generating data, such as ranges and random values.import random
– Python’s built-in module for random choices, used in randomized animations.
Create the Scene Class
class connectTheDots(Scene):
def construct(self):
# Animation logic goes here
Explanation:
Scene
is the base class for Manim animations.construct()
is the main method where the animation logic is defined.
Title Display
= Text("Three Methods to Connect Data Points", font_size=28, color=BLUE).to_edge(UP*0.5)
title self.play(Write(title))
self.wait(2)
Explanation:
- A title is created using
Text
, positioned near the top of the screen. self.play(Write(...))
animates the writing of the title.
Create Coordinate Grid
= NumberPlane(
ax =[-10, 10, 2],
x_range=[-3.5, 3.5, 1],
y_range={"stroke_color": GRAY, "stroke_width": 1, "stroke_opacity": 0.5}
background_line_style )
Explanation:
NumberPlane
creates a Cartesian grid.x_range
andy_range
set the grid’s extents.- The style is set for subtle grid lines.
Animate Axes Separately
= ax.get_x_axis()
x_axis = ax.get_y_axis()
y_axis
0)
x_axis.set_opacity(self.add(x_axis)
self.play(x_axis.animate.set_opacity(1), Create(x_axis), run_time=1.5)
0)
y_axis.set_opacity(self.add(y_axis)
self.play(y_axis.animate.set_opacity(1), Create(y_axis), run_time=1.5)
Explanation:
- Axes are added with initial opacity 0, then animated in.
- This allows for gradual, controlled reveal of axes.
Fade in Grid Lines
= VGroup()
grid_lines
grid_lines.add(ax.background_lines)self.play(FadeIn(grid_lines), run_time=1)
Explanation:
VGroup
groups all grid lines for collective animation.FadeIn()
smoothly displays the grid lines.
Generate Random Dots
= [np.random.uniform(-6.5, 6.5) for _ in range(20)]
xvals = [np.random.uniform(-3.5, 3.5) for _ in range(20)]
yvals = [np.random.choice([RED, GREEN, BLUE, YELLOW, MAROON, ORANGE, WHITE]) for _ in range(20)] colors
Explanation:
xvals
,yvals
: Generate random floating-point coordinates within the visible grid.colors
: Randomly select a color for each dot.
Create and Display Dots
= VGroup(*[Dot(point=[x, y, 0], color=c) for x, y, c in zip(xvals, yvals, colors)])
dots for dot in dots:
0)
dot.set_opacity(self.add(dots)
self.play(
LaggedStart(*[dot.animate.set_opacity(1) for dot in dots],
=0.4
lag_ratio
),=2.5
run_time )
Explanation:
- Dots are instantiated at each (x, y) with a random color and grouped for animation.
- They appear one after another using
LaggedStart
for a ripple effect.
Method 1: Connecting in Sequence
= Text("Connecting in Sequence", font_size=24, color=LIGHT_GRAY).to_edge(DOWN * 0.5)
subtitle1 self.play(Write(subtitle1))
= VGroup(
lines_seq *[Line(start=dots[i].get_center(), end=dots[i+1].get_center()) for i in range(len(dots) - 1)]
)self.play(
*[Create(line) for line in lines_seq], lag_ratio=0.6),
LaggedStart(=8,
run_time=rate_functions.linear
rate_func )
Explanation:
- Lines are drawn between each pair of consecutive dots, visualizing ordered or sequential data.
Method 2: Shapes
= Text("Connecting by Creating Different Shapes", font_size=24, color=LIGHT_GRAY).to_edge(DOWN*0.5)
subtitle2 self.play(Write(subtitle2))
= [
shapes 0].get_center(), dots[2].get_center(), dots[5].get_center(), dots[6].get_center()),
Polygon(dots[10].get_center(), dots[4].get_center(), dots[3].get_center(), dots[1].get_center()),
Polygon(dots[12].get_center(), dots[2].get_center(), dots[4].get_center(), dots[9].get_center()),
Polygon(dots[4].get_center(), dots[8].get_center(), dots[12].get_center()),
Polygon(dots[*[dots[i].get_center() for i in range(0, len(dots) - 2, 5)])
Polygon(
]for shape in shapes:
self.play(Create(shape), run_time=2)
self.wait(1)
self.play(FadeOut(shape))
Explanation:
- Custom polygons are created by selecting groups of dots.
- Demonstrates clustering and group relationships.
Method 3: Random Connections
= Text("Connecting Randomly", font_size=24, color=LIGHT_GRAY).to_edge(DOWN * 0.5)
subtitle3 self.play(Write(subtitle3))
= VGroup(
random_lines *[
Line(=dots[i].get_center(),
start=dots[random.randint(0, len(dots) - 1)].get_center()
endfor i in range(len(dots))
)
]
)self.play(
LaggedStart(*[Create(line) for line in random_lines],
=0.6
lag_ratio
),=8,
run_time=rate_functions.linear,
rate_func )
Explanation:
- Each dot is connected to a randomly chosen other dot, illustrating unpredictable relationships.
Final Fade Out
= VGroup(title, ax, dots, lines_seq, subtitle1)
all_content self.play(FadeOut(all_content, scale=1.5), run_time=2)
self.wait(1)
Explanation:
- All scene content fades and scales out, providing a clean ending.
Summary
Step | Purpose |
---|---|
np.random.uniform() | Controls dot coordinates |
random.randint() | Used for randomized line connections |
Text(), Dot(), Line() | Core visual components |
LaggedStart, FadeIn, FadeOut | Animation effects |
VGroup | Groups elements for animation |