manim-mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +104 -0
- package/dist/demo.mp4 +0 -0
- package/dist/index.js +65 -0
- package/dist/mcp-app.html +142 -0
- package/dist/server.js +1492 -0
- package/package.json +67 -0
- package/references/composer/SKILL.md +154 -0
- package/references/composer/references/3b1b-series-patterns.md +217 -0
- package/references/composer/references/domain-planning-guides/calculus-planning.md +188 -0
- package/references/composer/references/domain-planning-guides/linear-algebra-planning.md +169 -0
- package/references/composer/references/domain-planning-guides/ml-planning.md +286 -0
- package/references/composer/references/domain-planning-guides/number-theory-planning.md +187 -0
- package/references/composer/references/domain-planning-guides/physics-planning.md +249 -0
- package/references/composer/references/domain-planning-guides/probability-planning.md +200 -0
- package/references/composer/references/mathematical-storytelling.md +359 -0
- package/references/composer/references/narrative-patterns.md +221 -0
- package/references/composer/references/opening-patterns.md +284 -0
- package/references/composer/references/pacing-guide.md +289 -0
- package/references/composer/references/scene-archetypes.md +534 -0
- package/references/composer/references/scene-examples.md +379 -0
- package/references/composer/references/visual-techniques.md +480 -0
- package/references/composer/templates/scenes-template.md +147 -0
- package/references/manimce/SKILL.md +166 -0
- package/references/manimce/examples/3d_visualization.py +373 -0
- package/references/manimce/examples/basic_animations.py +212 -0
- package/references/manimce/examples/graph_plotting.py +401 -0
- package/references/manimce/examples/lorenz_attractor.py +172 -0
- package/references/manimce/examples/math_visualization.py +315 -0
- package/references/manimce/examples/updater_patterns.py +369 -0
- package/references/manimce/rules/3b1b-translation.md +594 -0
- package/references/manimce/rules/3d.md +254 -0
- package/references/manimce/rules/advanced-animations.md +594 -0
- package/references/manimce/rules/animation-groups.md +212 -0
- package/references/manimce/rules/animations.md +128 -0
- package/references/manimce/rules/api-pitfalls.md +89 -0
- package/references/manimce/rules/axes.md +214 -0
- package/references/manimce/rules/camera.md +208 -0
- package/references/manimce/rules/cli.md +232 -0
- package/references/manimce/rules/color-conventions.md +444 -0
- package/references/manimce/rules/colors.md +199 -0
- package/references/manimce/rules/config.md +264 -0
- package/references/manimce/rules/creation-animations.md +158 -0
- package/references/manimce/rules/graphing.md +233 -0
- package/references/manimce/rules/grouping.md +220 -0
- package/references/manimce/rules/latex.md +202 -0
- package/references/manimce/rules/lines.md +241 -0
- package/references/manimce/rules/long-form-video.md +552 -0
- package/references/manimce/rules/mathematical-domains.md +689 -0
- package/references/manimce/rules/mobjects.md +116 -0
- package/references/manimce/rules/multi-scene-composition.md +112 -0
- package/references/manimce/rules/pedagogy.md +532 -0
- package/references/manimce/rules/physics-simulations.md +610 -0
- package/references/manimce/rules/positioning.md +211 -0
- package/references/manimce/rules/scenes.md +121 -0
- package/references/manimce/rules/shapes.md +300 -0
- package/references/manimce/rules/styling.md +177 -0
- package/references/manimce/rules/text-animations.md +222 -0
- package/references/manimce/rules/text.md +189 -0
- package/references/manimce/rules/timing.md +227 -0
- package/references/manimce/rules/transform-animations.md +157 -0
- package/references/manimce/rules/updaters.md +226 -0
- package/references/manimce/templates/basic_scene.py +64 -0
- package/references/manimce/templates/camera_scene.py +100 -0
- package/references/manimce/templates/threed_scene.py +138 -0
|
@@ -0,0 +1,534 @@
|
|
|
1
|
+
# 3Blue1Brown Scene Archetypes
|
|
2
|
+
|
|
3
|
+
Reusable scene templates extracted from 400+ 3b1b video source files. Each archetype includes the base class, typical structure, and real implementation patterns.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. TeacherStudentsScene (Classroom Dialogue)
|
|
8
|
+
|
|
9
|
+
The most-used scene archetype across the entire codebase (134 files, 851 class instances). Features one teacher (Mortimer) and three students as Pi creatures.
|
|
10
|
+
|
|
11
|
+
### Structure
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
class MyDialogueScene(TeacherStudentsScene):
|
|
15
|
+
def construct(self):
|
|
16
|
+
# Teacher introduces concept
|
|
17
|
+
self.play(
|
|
18
|
+
self.teacher.says("Here's the key idea..."),
|
|
19
|
+
self.change_students("pondering", "happy", "erm")
|
|
20
|
+
)
|
|
21
|
+
self.wait(2)
|
|
22
|
+
|
|
23
|
+
# Student asks question
|
|
24
|
+
self.play(
|
|
25
|
+
self.students[1].says(
|
|
26
|
+
"But what about...?",
|
|
27
|
+
mode="sassy"
|
|
28
|
+
),
|
|
29
|
+
self.teacher.change("guilty", self.students[1].eyes)
|
|
30
|
+
)
|
|
31
|
+
self.wait()
|
|
32
|
+
|
|
33
|
+
# Teacher responds
|
|
34
|
+
self.play(
|
|
35
|
+
self.teacher.says("Great question!", mode="raise_right_hand"),
|
|
36
|
+
self.change_students("thinking", "happy", "thinking")
|
|
37
|
+
)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### When to Use
|
|
41
|
+
|
|
42
|
+
- Emotional resets between dense mathematical sections (15-30 seconds)
|
|
43
|
+
- Acknowledging viewer confusion ("This might seem strange...")
|
|
44
|
+
- Introducing controversial or non-obvious claims
|
|
45
|
+
- Transitioning between major topics
|
|
46
|
+
- Humor and personality breaks
|
|
47
|
+
|
|
48
|
+
### Real Examples
|
|
49
|
+
|
|
50
|
+
**Moser's Circle Problem** (`_2023/moser_reboot/main.py`):
|
|
51
|
+
```python
|
|
52
|
+
class AskAboutPosition(TeacherStudentsScene):
|
|
53
|
+
def construct(self):
|
|
54
|
+
self.play(LaggedStart(
|
|
55
|
+
stds[1].says("Doesn't it depend on\nwhere the points are?", mode="sassy"),
|
|
56
|
+
stds[0].change('confused', self.screen),
|
|
57
|
+
morty.change("guilty", stds[1].eyes)
|
|
58
|
+
))
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**FFT Revelation** (`_2022/convolutions/supplements.py`):
|
|
62
|
+
```python
|
|
63
|
+
class DumbIdea(TeacherStudentsScene):
|
|
64
|
+
# Student calls the polynomial approach "idiotic"
|
|
65
|
+
# Teacher reveals "But there's a trick" -> FFT
|
|
66
|
+
# Student asks "What...is that?"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 2. OpeningQuote Scene
|
|
72
|
+
|
|
73
|
+
A formatted quote with author attribution. Standard opening for EoLA series.
|
|
74
|
+
|
|
75
|
+
### Structure
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
class OpeningQuote(Scene):
|
|
79
|
+
def construct(self):
|
|
80
|
+
words = OldTexText(R"``Quote text here.''")
|
|
81
|
+
words.set_width(2 * (FRAME_X_RADIUS - 1))
|
|
82
|
+
words.to_edge(UP)
|
|
83
|
+
words.set_color_by_tex("key phrase", GREEN)
|
|
84
|
+
|
|
85
|
+
author = OldTexText("-Author Name")
|
|
86
|
+
author.set_color(YELLOW)
|
|
87
|
+
author.next_to(words, DOWN, buff=0.5)
|
|
88
|
+
|
|
89
|
+
self.play(FadeIn(words))
|
|
90
|
+
self.wait(3)
|
|
91
|
+
self.play(Write(author, run_time=5))
|
|
92
|
+
self.wait()
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Timing
|
|
96
|
+
|
|
97
|
+
- FadeIn quote: instant to 1 second
|
|
98
|
+
- Wait for reading: 3-4 seconds
|
|
99
|
+
- Write author: 4-5 seconds (slow, dramatic)
|
|
100
|
+
- Final wait: 1-2 seconds
|
|
101
|
+
- Total: ~8-12 seconds
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## 3. Grid Transformation Scene
|
|
106
|
+
|
|
107
|
+
THE signature 3b1b visual. A NumberPlane grid is deformed by a linear transformation.
|
|
108
|
+
|
|
109
|
+
### Structure
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
class TransformationScene(InteractiveScene):
|
|
113
|
+
def construct(self):
|
|
114
|
+
# Setup
|
|
115
|
+
plane = NumberPlane()
|
|
116
|
+
i_hat = Vector(RIGHT, color=GREEN)
|
|
117
|
+
j_hat = Vector(UP, color=RED)
|
|
118
|
+
|
|
119
|
+
self.add(plane, i_hat, j_hat)
|
|
120
|
+
self.wait()
|
|
121
|
+
|
|
122
|
+
# Apply transformation
|
|
123
|
+
matrix = [[2, 1], [0, 1]] # Shear
|
|
124
|
+
self.play(
|
|
125
|
+
plane.animate.apply_matrix(matrix),
|
|
126
|
+
i_hat.animate.put_start_and_end_on(ORIGIN, matrix[0]),
|
|
127
|
+
j_hat.animate.put_start_and_end_on(ORIGIN, matrix[1]),
|
|
128
|
+
run_time=3
|
|
129
|
+
)
|
|
130
|
+
self.wait()
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Variations from the Codebase
|
|
134
|
+
|
|
135
|
+
- **Single transformation**: Apply one matrix, observe result
|
|
136
|
+
- **Composition**: Apply matrix A, then matrix B, show AB
|
|
137
|
+
- **Determinant reveal**: Color the unit square, watch its area change
|
|
138
|
+
- **Eigenvector highlight**: Some vectors stay on their line
|
|
139
|
+
- **Non-square**: Map between dimensions (3D to 2D projection)
|
|
140
|
+
|
|
141
|
+
### Color Convention
|
|
142
|
+
|
|
143
|
+
- **i-hat (basis vector 1)**: GREEN
|
|
144
|
+
- **j-hat (basis vector 2)**: RED
|
|
145
|
+
- **Arbitrary vector v**: YELLOW
|
|
146
|
+
- **Grid lines**: BLUE_D to BLUE_B
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## 4. Equation Derivation Scene
|
|
151
|
+
|
|
152
|
+
Step-by-step visual derivation of a formula, using `TransformMatchingTex` for smooth transitions.
|
|
153
|
+
|
|
154
|
+
### Structure
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
class DerivationScene(InteractiveScene):
|
|
158
|
+
def construct(self):
|
|
159
|
+
step1 = Tex(R"f(x) = \int_0^x g(t) \, dt")
|
|
160
|
+
step2 = Tex(R"\frac{d}{dx} f(x) = g(x)")
|
|
161
|
+
step3 = Tex(R"f'(x) = g(x)")
|
|
162
|
+
|
|
163
|
+
# Color code consistently
|
|
164
|
+
kw = {"t2c": {"{x}": BLUE, "{t}": YELLOW, "g": GREEN}}
|
|
165
|
+
|
|
166
|
+
self.play(Write(step1))
|
|
167
|
+
self.wait(2)
|
|
168
|
+
|
|
169
|
+
# Highlight the key part
|
|
170
|
+
self.play(Indicate(step1[...])) # highlight derivative
|
|
171
|
+
|
|
172
|
+
# Transform to next step
|
|
173
|
+
self.play(TransformMatchingTex(step1, step2))
|
|
174
|
+
self.wait(2)
|
|
175
|
+
|
|
176
|
+
self.play(TransformMatchingTex(step2, step3))
|
|
177
|
+
self.wait()
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Key Techniques
|
|
181
|
+
|
|
182
|
+
- **`TransformMatchingTex`**: Matches LaTeX substrings between equations for smooth morphing. Use `matched_keys` parameter for explicit matching.
|
|
183
|
+
- **`t2c` (text-to-color)**: Color-code variables consistently across all steps.
|
|
184
|
+
- **`Indicate()`**: Brief flash on the term being discussed.
|
|
185
|
+
- **`SurroundingRectangle`**: Box around a sub-expression before explaining it.
|
|
186
|
+
- **`Brace`**: Point to a piece with a descriptive label.
|
|
187
|
+
|
|
188
|
+
### Real Example: CLT Proof (`_2023/clt_proof/main.py`)
|
|
189
|
+
|
|
190
|
+
```python
|
|
191
|
+
self.play(TransformMatchingTex(eq1, eq2, matched_keys=[R"e^{tx}"]))
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Real Example: Laplace Commutative Diagram (`_2025/laplace/derivatives.py`)
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
ft, Fs, dft, sFs = terms = VGroup(
|
|
198
|
+
Tex(R"f({t})", **kw),
|
|
199
|
+
Tex(R"F({s})", **kw),
|
|
200
|
+
Tex(R"f'({t})", **kw),
|
|
201
|
+
Tex(R"{s}F({s}) - f(0)", **kw),
|
|
202
|
+
)
|
|
203
|
+
terms.arrange_in_grid(h_buff=2.0, v_buff=3.0, fill_rows_first=False)
|
|
204
|
+
deriv_arrow = Arrow(ft, dft)
|
|
205
|
+
laplace_arrow = Arrow(ft, Fs)
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## 5. Side-by-Side Comparison Scene
|
|
211
|
+
|
|
212
|
+
Two representations of the same concept shown simultaneously.
|
|
213
|
+
|
|
214
|
+
### Structure
|
|
215
|
+
|
|
216
|
+
```python
|
|
217
|
+
class ComparisonScene(InteractiveScene):
|
|
218
|
+
def construct(self):
|
|
219
|
+
# Split screen
|
|
220
|
+
left_group = VGroup(left_title, left_content)
|
|
221
|
+
right_group = VGroup(right_title, right_content)
|
|
222
|
+
|
|
223
|
+
left_group.to_edge(LEFT)
|
|
224
|
+
right_group.to_edge(RIGHT)
|
|
225
|
+
|
|
226
|
+
divider = Line(3 * UP, 3 * DOWN)
|
|
227
|
+
|
|
228
|
+
self.play(ShowCreation(divider))
|
|
229
|
+
self.play(FadeIn(left_group), FadeIn(right_group))
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Real Examples
|
|
233
|
+
|
|
234
|
+
- **"Your coords vs Jennifer's coords"** (EoLA Ch 10): Two coordinate systems side by side
|
|
235
|
+
- **"Fourier Land"** (`_2022/borwein/supplements.py`): Time domain on left, frequency domain on right, with teal-tinted right half
|
|
236
|
+
- **Bertrand's Paradox** (`_2021/bertrands_paradox.py`): Three methods of choosing random chords compared
|
|
237
|
+
|
|
238
|
+
### Fourier Land Split Screen Pattern
|
|
239
|
+
|
|
240
|
+
```python
|
|
241
|
+
right_rect = FullScreenRectangle()
|
|
242
|
+
right_rect.set_fill(TEAL, 0.2)
|
|
243
|
+
right_rect.stretch(0.5, 0, about_edge=RIGHT)
|
|
244
|
+
ft_label = Text("Fourier Land", font_size=60)
|
|
245
|
+
ft_label.set_fill(TEAL)
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## 6. Phase Space Scene
|
|
251
|
+
|
|
252
|
+
Show a physical system alongside its phase portrait -- the signature technique from the Differential Equations series.
|
|
253
|
+
|
|
254
|
+
### Structure
|
|
255
|
+
|
|
256
|
+
```python
|
|
257
|
+
class PhaseSpaceScene(InteractiveScene):
|
|
258
|
+
def construct(self):
|
|
259
|
+
# Left: physical system
|
|
260
|
+
pendulum = Pendulum(...)
|
|
261
|
+
|
|
262
|
+
# Right: phase portrait
|
|
263
|
+
phase_plane = NumberPlane(
|
|
264
|
+
x_range=[-PI, PI], # theta
|
|
265
|
+
y_range=[-5, 5], # omega
|
|
266
|
+
)
|
|
267
|
+
vector_field = VectorField(
|
|
268
|
+
lambda p: pendulum_vector_field_func(p),
|
|
269
|
+
)
|
|
270
|
+
stream_lines = StreamLines(
|
|
271
|
+
vector_field.func,
|
|
272
|
+
delta_x=0.5, delta_y=0.5,
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
# Link them: dot on phase space follows pendulum state
|
|
276
|
+
state_dot = Dot(color=YELLOW)
|
|
277
|
+
state_dot.add_updater(lambda m: m.move_to(
|
|
278
|
+
phase_plane.c2p(pendulum.theta, pendulum.omega)
|
|
279
|
+
))
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Real Implementation (`_2019/diffyq/part1/`)
|
|
283
|
+
|
|
284
|
+
The DiffEq series uses:
|
|
285
|
+
- `Pendulum` custom mobject with physics simulation
|
|
286
|
+
- `ThetaVsTAxes` for theta-vs-time graph
|
|
287
|
+
- `IntroduceVectorField` for phase space
|
|
288
|
+
- `PhaseSpaceOfPopulationModel` imported from `_2018/div_curl.py`
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## 7. Progressive Build Scene
|
|
293
|
+
|
|
294
|
+
Build a complex object incrementally, showing each component.
|
|
295
|
+
|
|
296
|
+
### Structure
|
|
297
|
+
|
|
298
|
+
```
|
|
299
|
+
1. Show component A alone
|
|
300
|
+
2. Add component B, explain
|
|
301
|
+
3. Add component C, explain
|
|
302
|
+
4. Show the combined result
|
|
303
|
+
5. "Each piece is simple, but together..."
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Real Examples
|
|
307
|
+
|
|
308
|
+
**Fourier Series** (DiffEq Part 4): Individual sine waves added one at a time, with running sum shown. 1 term, 3 terms, 5 terms, 50 terms...
|
|
309
|
+
|
|
310
|
+
**CLT / Gaussian Build-Up** (`_2023/clt/main.py`): `BuildUpGaussian` constructs the Gaussian formula piece by piece: first the exponential, then the 1/sqrt(2*pi), then sigma.
|
|
311
|
+
|
|
312
|
+
**Transformer Architecture** (`_2024/transformers/network_flow.py`): `HighLevelNetworkFlow` adds embedding -> attention -> MLP -> unembedding one block at a time.
|
|
313
|
+
|
|
314
|
+
**Progressive Speed-Up Pattern**:
|
|
315
|
+
```python
|
|
316
|
+
for n in range(n_sums):
|
|
317
|
+
if n < 10:
|
|
318
|
+
self.run_one_sum(animated=True)
|
|
319
|
+
else:
|
|
320
|
+
self.run_one_sum(animated=False, still_frame=True)
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## 8. Proof/Demonstration Scene
|
|
326
|
+
|
|
327
|
+
Visual proof with highlighted steps.
|
|
328
|
+
|
|
329
|
+
### Structure
|
|
330
|
+
|
|
331
|
+
```python
|
|
332
|
+
class ProofScene(InteractiveScene):
|
|
333
|
+
def construct(self):
|
|
334
|
+
# State the claim
|
|
335
|
+
claim = Tex(R"\text{Claim: } ...")
|
|
336
|
+
self.play(Write(claim))
|
|
337
|
+
|
|
338
|
+
# Visual setup
|
|
339
|
+
# ... create geometric objects ...
|
|
340
|
+
|
|
341
|
+
# Step-by-step reasoning
|
|
342
|
+
step1_label = Text("Step 1: ...", font_size=36)
|
|
343
|
+
step1_label.to_corner(UL)
|
|
344
|
+
self.play(Write(step1_label))
|
|
345
|
+
# ... animate step 1 ...
|
|
346
|
+
|
|
347
|
+
# Highlight the key insight
|
|
348
|
+
self.play(FlashAround(key_element))
|
|
349
|
+
|
|
350
|
+
# QED / conclusion
|
|
351
|
+
qed = Tex(R"\blacksquare")
|
|
352
|
+
qed.to_corner(DR)
|
|
353
|
+
self.play(Write(qed))
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Real Examples
|
|
357
|
+
|
|
358
|
+
- **Circle area via concentric rings** (EoC Ch 1): Each ring unfurled into a thin rectangle, stacked to form a triangle
|
|
359
|
+
- **Surface area of a sphere** (`_2018/sphere_area.py`, `_2022/visual_proofs/lies.py`): Sphere sliced into bands, projected
|
|
360
|
+
- **Moser's Circle Problem** (`_2023/moser_reboot/main.py`): Combinatorial counting with `choose()` function
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## 9. Simulation Scene
|
|
365
|
+
|
|
366
|
+
Real-time physics or mathematical simulation.
|
|
367
|
+
|
|
368
|
+
### Examples from Codebase
|
|
369
|
+
|
|
370
|
+
**SIR Epidemic** (`_2020/sir.py`):
|
|
371
|
+
```python
|
|
372
|
+
class SIRSimulation(VGroup):
|
|
373
|
+
# Physics-based particles with infection mechanics
|
|
374
|
+
# Susceptible=BLUE, Infected=RED, Recovered=GREEN
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
**Galton Board** (`_2023/clt/galton_board.py`):
|
|
378
|
+
```python
|
|
379
|
+
class GaltonBoard(InteractiveScene):
|
|
380
|
+
# Physical ball bouncing simulation
|
|
381
|
+
self.add_sound("clack") # Sound effects for bounces
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
**Spring-Mass System** (`_2025/laplace/shm.py`):
|
|
385
|
+
```python
|
|
386
|
+
class SrpingMassSystem(VGroup):
|
|
387
|
+
def time_step(self, delta_t, dt_size=1e-3):
|
|
388
|
+
# Euler integration with substeps
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
**Sliding Blocks** (`_2019/clacks/question.py`):
|
|
392
|
+
```python
|
|
393
|
+
class SlidingBlocks(VGroup):
|
|
394
|
+
# Two blocks, elastic collisions, count clacks
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
**Ladybug Random Walk** (`_2026/monthly_mindbenders/ladybug.py`):
|
|
398
|
+
```python
|
|
399
|
+
# Random walk on clock face
|
|
400
|
+
while len(covered_numbers) < 12:
|
|
401
|
+
step = random.choice([+1, -1])
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
## 10. Data Visualization Scene
|
|
407
|
+
|
|
408
|
+
Chart, graph, or distribution visualization.
|
|
409
|
+
|
|
410
|
+
### Key Custom Mobjects
|
|
411
|
+
|
|
412
|
+
**`ChartBars`** (`_2023/clt/main.py`):
|
|
413
|
+
```python
|
|
414
|
+
class ChartBars(VGroup):
|
|
415
|
+
# Bar chart aligned to axes
|
|
416
|
+
# Supports gradient coloring:
|
|
417
|
+
bars.set_submobject_colors_by_gradient(BLUE, GREEN)
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
**Dynamic Labels** (`make_number_changeable`):
|
|
421
|
+
```python
|
|
422
|
+
label = Tex(R"\mu = 0.00")
|
|
423
|
+
decimal = label.make_number_changeable("0.00")
|
|
424
|
+
decimal.add_updater(lambda m: m.set_value(get_mean()))
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
**`Histogram`** (`_2020/beta/helpers.py`):
|
|
428
|
+
```python
|
|
429
|
+
class Histogram(Group):
|
|
430
|
+
# Bar chart for probability distributions
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
435
|
+
## 11. 3D Surface Scene
|
|
436
|
+
|
|
437
|
+
Mathematical surface rendered in three dimensions with camera orbiting.
|
|
438
|
+
|
|
439
|
+
### Structure
|
|
440
|
+
|
|
441
|
+
```python
|
|
442
|
+
class SurfaceScene(InteractiveScene):
|
|
443
|
+
def construct(self):
|
|
444
|
+
frame = self.frame
|
|
445
|
+
frame.reorient(-40, 70, 0)
|
|
446
|
+
frame.set_field_of_view(20 * DEGREES)
|
|
447
|
+
|
|
448
|
+
surface = ParametricSurface(
|
|
449
|
+
lambda u, v: [u, v, func(u, v)],
|
|
450
|
+
u_range=(-3, 3), v_range=(-3, 3),
|
|
451
|
+
resolution=(101, 101)
|
|
452
|
+
)
|
|
453
|
+
surface.set_shading(0.1, 0.1, 0.1)
|
|
454
|
+
mesh = SurfaceMesh(surface)
|
|
455
|
+
|
|
456
|
+
self.play(FadeIn(Group(surface, mesh)))
|
|
457
|
+
self.play(frame.animate.reorient(60, 50, 0), run_time=5)
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
### Variations
|
|
461
|
+
|
|
462
|
+
- **Color by phase**: `surface.color_by_uv_function(lambda u, v: z_to_color(func(complex(u, v))))`
|
|
463
|
+
- **Clip planes**: `surface.set_clip_plane(direction, value)` for cross-sections
|
|
464
|
+
- **Textured surfaces**: `TexturedSurface(Sphere(), "EarthTextureMap")` for planets
|
|
465
|
+
- **Ambient rotation**: `frame.add_updater(lambda m, dt: m.increment_theta(-0.1 * dt))`
|
|
466
|
+
|
|
467
|
+
---
|
|
468
|
+
|
|
469
|
+
## 12. End Screen / Patron Credits
|
|
470
|
+
|
|
471
|
+
Standard ending with links and supporter acknowledgment.
|
|
472
|
+
|
|
473
|
+
### Structure
|
|
474
|
+
|
|
475
|
+
From `custom/end_screen.py`:
|
|
476
|
+
- Channel logo/banner
|
|
477
|
+
- Patron names scrolling or displayed
|
|
478
|
+
- Links to related videos
|
|
479
|
+
- Support call-to-action
|
|
480
|
+
|
|
481
|
+
---
|
|
482
|
+
|
|
483
|
+
## 13. Quiz / Interactive Reveal Scene
|
|
484
|
+
|
|
485
|
+
Present a question, let the viewer think, then reveal the answer.
|
|
486
|
+
|
|
487
|
+
### Real Example: Grover Quiz (`_2025/grover/runtime.py`)
|
|
488
|
+
|
|
489
|
+
```python
|
|
490
|
+
covers = VGroup(SurroundingRectangle(choice[2:]) for choice in choices)
|
|
491
|
+
covers.set_fill(GREY_D, 1)
|
|
492
|
+
for cover in covers:
|
|
493
|
+
cover.save_state()
|
|
494
|
+
cover.stretch(0, 0, about_edge=LEFT)
|
|
495
|
+
self.play(LaggedStartMap(Restore, covers, lag_ratio=0.25))
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
---
|
|
499
|
+
|
|
500
|
+
## 14. Taxonomy / Nested Box Scene
|
|
501
|
+
|
|
502
|
+
Categorize concepts using nested or overlapping boxes.
|
|
503
|
+
|
|
504
|
+
### Real Example: ML Taxonomy (`_2024/transformers/ml_basics.py`)
|
|
505
|
+
|
|
506
|
+
```python
|
|
507
|
+
class MLWithinDeepL(InteractiveScene):
|
|
508
|
+
def get_titled_box(self, text, color, ...):
|
|
509
|
+
title = Text(text)
|
|
510
|
+
box = Rectangle(...)
|
|
511
|
+
box.set_fill(interpolate_color(BLACK, color, opacity), 1)
|
|
512
|
+
box.set_stroke(color, 2)
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
Boxes nest: AI > Machine Learning > Deep Learning > Transformers
|
|
516
|
+
|
|
517
|
+
---
|
|
518
|
+
|
|
519
|
+
## Archetype Selection Guide
|
|
520
|
+
|
|
521
|
+
| Situation | Recommended Archetype |
|
|
522
|
+
|-----------|-----------------------|
|
|
523
|
+
| Opening a series chapter | OpeningQuote + Question-Driven |
|
|
524
|
+
| Introducing a linear algebra concept | Grid Transformation |
|
|
525
|
+
| Deriving a formula | Equation Derivation |
|
|
526
|
+
| Explaining a physics concept | Phase Space + Simulation |
|
|
527
|
+
| Building something complex | Progressive Build |
|
|
528
|
+
| Comparing two approaches | Side-by-Side Comparison |
|
|
529
|
+
| Emotional reset / humor | TeacherStudentsScene |
|
|
530
|
+
| Proving something visual | Proof/Demonstration |
|
|
531
|
+
| Showing data or distributions | Data Visualization |
|
|
532
|
+
| 3D mathematical object | 3D Surface |
|
|
533
|
+
| Testing viewer understanding | Quiz / Interactive Reveal |
|
|
534
|
+
| Categorizing concepts | Taxonomy / Nested Box |
|