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.
Files changed (64) hide show
  1. package/README.md +104 -0
  2. package/dist/demo.mp4 +0 -0
  3. package/dist/index.js +65 -0
  4. package/dist/mcp-app.html +142 -0
  5. package/dist/server.js +1492 -0
  6. package/package.json +67 -0
  7. package/references/composer/SKILL.md +154 -0
  8. package/references/composer/references/3b1b-series-patterns.md +217 -0
  9. package/references/composer/references/domain-planning-guides/calculus-planning.md +188 -0
  10. package/references/composer/references/domain-planning-guides/linear-algebra-planning.md +169 -0
  11. package/references/composer/references/domain-planning-guides/ml-planning.md +286 -0
  12. package/references/composer/references/domain-planning-guides/number-theory-planning.md +187 -0
  13. package/references/composer/references/domain-planning-guides/physics-planning.md +249 -0
  14. package/references/composer/references/domain-planning-guides/probability-planning.md +200 -0
  15. package/references/composer/references/mathematical-storytelling.md +359 -0
  16. package/references/composer/references/narrative-patterns.md +221 -0
  17. package/references/composer/references/opening-patterns.md +284 -0
  18. package/references/composer/references/pacing-guide.md +289 -0
  19. package/references/composer/references/scene-archetypes.md +534 -0
  20. package/references/composer/references/scene-examples.md +379 -0
  21. package/references/composer/references/visual-techniques.md +480 -0
  22. package/references/composer/templates/scenes-template.md +147 -0
  23. package/references/manimce/SKILL.md +166 -0
  24. package/references/manimce/examples/3d_visualization.py +373 -0
  25. package/references/manimce/examples/basic_animations.py +212 -0
  26. package/references/manimce/examples/graph_plotting.py +401 -0
  27. package/references/manimce/examples/lorenz_attractor.py +172 -0
  28. package/references/manimce/examples/math_visualization.py +315 -0
  29. package/references/manimce/examples/updater_patterns.py +369 -0
  30. package/references/manimce/rules/3b1b-translation.md +594 -0
  31. package/references/manimce/rules/3d.md +254 -0
  32. package/references/manimce/rules/advanced-animations.md +594 -0
  33. package/references/manimce/rules/animation-groups.md +212 -0
  34. package/references/manimce/rules/animations.md +128 -0
  35. package/references/manimce/rules/api-pitfalls.md +89 -0
  36. package/references/manimce/rules/axes.md +214 -0
  37. package/references/manimce/rules/camera.md +208 -0
  38. package/references/manimce/rules/cli.md +232 -0
  39. package/references/manimce/rules/color-conventions.md +444 -0
  40. package/references/manimce/rules/colors.md +199 -0
  41. package/references/manimce/rules/config.md +264 -0
  42. package/references/manimce/rules/creation-animations.md +158 -0
  43. package/references/manimce/rules/graphing.md +233 -0
  44. package/references/manimce/rules/grouping.md +220 -0
  45. package/references/manimce/rules/latex.md +202 -0
  46. package/references/manimce/rules/lines.md +241 -0
  47. package/references/manimce/rules/long-form-video.md +552 -0
  48. package/references/manimce/rules/mathematical-domains.md +689 -0
  49. package/references/manimce/rules/mobjects.md +116 -0
  50. package/references/manimce/rules/multi-scene-composition.md +112 -0
  51. package/references/manimce/rules/pedagogy.md +532 -0
  52. package/references/manimce/rules/physics-simulations.md +610 -0
  53. package/references/manimce/rules/positioning.md +211 -0
  54. package/references/manimce/rules/scenes.md +121 -0
  55. package/references/manimce/rules/shapes.md +300 -0
  56. package/references/manimce/rules/styling.md +177 -0
  57. package/references/manimce/rules/text-animations.md +222 -0
  58. package/references/manimce/rules/text.md +189 -0
  59. package/references/manimce/rules/timing.md +227 -0
  60. package/references/manimce/rules/transform-animations.md +157 -0
  61. package/references/manimce/rules/updaters.md +226 -0
  62. package/references/manimce/templates/basic_scene.py +64 -0
  63. package/references/manimce/templates/camera_scene.py +100 -0
  64. package/references/manimce/templates/threed_scene.py +138 -0
@@ -0,0 +1,689 @@
1
+ ---
2
+ name: mathematical-domains
3
+ description: Domain-specific patterns for visualizing different branches of mathematics in ManimCE, based on 3b1b's actual video code
4
+ metadata:
5
+ tags: linear-algebra, calculus, probability, complex-analysis, number-theory, topology, neural-networks, quantum, math
6
+ ---
7
+
8
+ # Mathematical Domain-Specific Patterns
9
+
10
+ Patterns extracted from specific 3b1b video series: Essence of Linear Algebra, Essence of Calculus, probability videos, complex analysis, prime spirals, topology, transformers series, and quantum computing.
11
+
12
+ ## Linear Algebra
13
+
14
+ From `_2016/eola/` (chapters 0-11) and `_2024/linalg/eigenlecture.py`.
15
+
16
+ ### Basis Vectors (Green i-hat, Red j-hat)
17
+
18
+ The canonical 3b1b convention: i-hat is GREEN, j-hat is RED, k-hat is BLUE.
19
+
20
+ ```python
21
+ from manim import *
22
+
23
+ X_COLOR = GREEN
24
+ Y_COLOR = RED
25
+ Z_COLOR = BLUE
26
+
27
+ class BasisVectors(Scene):
28
+ """Standard EoLA basis vector setup."""
29
+
30
+ def construct(self):
31
+ plane = NumberPlane()
32
+ plane.set_stroke(BLUE_D, 1, opacity=0.4)
33
+
34
+ # Basis vectors with labels
35
+ i_hat = Vector([1, 0], color=X_COLOR, stroke_width=5)
36
+ j_hat = Vector([0, 1], color=Y_COLOR, stroke_width=5)
37
+
38
+ i_label = MathTex(r"\hat{\imath}", color=X_COLOR, font_size=36)
39
+ i_label.next_to(i_hat.get_end(), DOWN + RIGHT, buff=0.1)
40
+ j_label = MathTex(r"\hat{\jmath}", color=Y_COLOR, font_size=36)
41
+ j_label.next_to(j_hat.get_end(), UP + LEFT, buff=0.1)
42
+
43
+ self.play(Create(plane), run_time=2)
44
+ self.play(
45
+ GrowArrow(i_hat), Write(i_label),
46
+ GrowArrow(j_hat), Write(j_label),
47
+ )
48
+ self.wait()
49
+ ```
50
+
51
+ ### Grid Transformations (Linear Map Visualization)
52
+
53
+ ```python
54
+ class LinearTransformation(Scene):
55
+ """Apply a linear transformation to the grid -- EoLA signature."""
56
+
57
+ def construct(self):
58
+ plane = NumberPlane()
59
+ i_hat = Vector([1, 0], color=X_COLOR)
60
+ j_hat = Vector([0, 1], color=Y_COLOR)
61
+
62
+ self.add(plane, i_hat, j_hat)
63
+ self.wait()
64
+
65
+ # The transformation matrix
66
+ matrix = [[1, 1], [-1, 1]] # Rotation + scaling
67
+
68
+ # Apply transformation to the plane and basis vectors
69
+ self.play(
70
+ ApplyMatrix(matrix, plane),
71
+ ApplyMatrix(matrix, i_hat),
72
+ ApplyMatrix(matrix, j_hat),
73
+ run_time=3,
74
+ )
75
+ self.wait()
76
+
77
+ # Show where basis vectors land
78
+ new_i_coords = MathTex(
79
+ r"\hat{\imath} \to", r"\begin{bmatrix} 1 \\ -1 \end{bmatrix}",
80
+ tex_to_color_map={r"\hat{\imath}": X_COLOR},
81
+ ).to_corner(UL)
82
+ new_j_coords = MathTex(
83
+ r"\hat{\jmath} \to", r"\begin{bmatrix} 1 \\ 1 \end{bmatrix}",
84
+ tex_to_color_map={r"\hat{\jmath}": Y_COLOR},
85
+ ).next_to(new_i_coords, DOWN, aligned_edge=LEFT)
86
+
87
+ self.play(Write(new_i_coords), Write(new_j_coords))
88
+ self.wait(2)
89
+ ```
90
+
91
+ ### Determinant Visualization
92
+
93
+ ```python
94
+ class DeterminantVisualization(Scene):
95
+ """Visualize determinant as area scaling factor."""
96
+
97
+ def construct(self):
98
+ plane = NumberPlane().set_opacity(0.3)
99
+ self.add(plane)
100
+
101
+ # Unit square
102
+ unit_square = Polygon(
103
+ ORIGIN, RIGHT, RIGHT + UP, UP,
104
+ fill_color=YELLOW, fill_opacity=0.3,
105
+ stroke_color=YELLOW, stroke_width=2,
106
+ )
107
+ area_label = MathTex(r"\text{Area} = 1", font_size=30)
108
+ area_label.move_to(unit_square)
109
+
110
+ self.play(DrawBorderThenFill(unit_square), Write(area_label))
111
+ self.wait()
112
+
113
+ # Transform
114
+ matrix = [[2, 1], [0, 3]]
115
+ det_value = matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]
116
+
117
+ self.play(
118
+ ApplyMatrix(matrix, unit_square),
119
+ ApplyMatrix(matrix, plane),
120
+ run_time=2,
121
+ )
122
+
123
+ new_label = MathTex(
124
+ rf"\text{{Area}} = {det_value}",
125
+ font_size=30, color=YELLOW,
126
+ )
127
+ new_label.move_to(unit_square)
128
+ self.play(Transform(area_label, new_label))
129
+
130
+ # Show det formula
131
+ det_formula = MathTex(
132
+ rf"\det \begin{{bmatrix}} 2 & 1 \\ 0 & 3 \end{{bmatrix}} = {det_value}",
133
+ ).to_edge(UP)
134
+ self.play(Write(det_formula))
135
+ self.wait(2)
136
+ ```
137
+
138
+ ### Eigenvalue Tracing
139
+
140
+ From `_2024/linalg/eigenlecture.py` -- using `t2c` for color-coded eigenvalue equations.
141
+
142
+ ```python
143
+ class EigenvalueEquation(Scene):
144
+ """Color-coded eigenvalue equation in the 3b1b style."""
145
+
146
+ def construct(self):
147
+ eq = MathTex(
148
+ r"A", r"\vec{v}", r"=", r"\lambda", r"\vec{v}",
149
+ tex_to_color_map={
150
+ r"\vec{v}": YELLOW,
151
+ r"\lambda": TEAL,
152
+ },
153
+ )
154
+ eq.scale(1.5)
155
+ self.play(Write(eq))
156
+ self.wait()
157
+
158
+ # Rearrange to characteristic equation
159
+ char_eq = MathTex(
160
+ r"\det(", r"A", r"-", r"\lambda", r"I", r") = 0",
161
+ tex_to_color_map={r"\lambda": TEAL},
162
+ )
163
+ char_eq.scale(1.2)
164
+ char_eq.next_to(eq, DOWN, buff=1.0)
165
+ self.play(Write(char_eq, run_time=2))
166
+ self.wait(2)
167
+ ```
168
+
169
+ ## Calculus
170
+
171
+ From `_2017/` Essence of Calculus and related videos.
172
+
173
+ ### Riemann Rectangles
174
+
175
+ ```python
176
+ class RiemannRectangles(Scene):
177
+ """Progressive refinement of Riemann sums."""
178
+
179
+ def construct(self):
180
+ axes = Axes(
181
+ x_range=[0, 5, 1], y_range=[0, 5, 1],
182
+ x_length=8, y_length=5,
183
+ )
184
+ graph = axes.plot(lambda x: 0.2 * x**2, color=YELLOW)
185
+ graph_label = axes.get_graph_label(graph, r"f(x) = 0.2x^2")
186
+
187
+ self.play(Create(axes), Create(graph), Write(graph_label))
188
+ self.wait()
189
+
190
+ # Show progressively finer rectangles
191
+ for n_rects in [4, 8, 20, 50]:
192
+ rects = axes.get_riemann_rectangles(
193
+ graph,
194
+ x_range=[0, 4],
195
+ dx=4.0 / n_rects,
196
+ fill_opacity=0.5,
197
+ stroke_width=1,
198
+ stroke_color=WHITE,
199
+ )
200
+ rects.set_color_by_gradient(BLUE, GREEN)
201
+
202
+ if n_rects == 4:
203
+ self.play(Create(rects), run_time=1.5)
204
+ else:
205
+ self.play(Transform(rects_prev, rects), run_time=1)
206
+
207
+ rects_prev = rects
208
+ n_label = MathTex(f"n = {n_rects}", font_size=36)
209
+ n_label.to_corner(UR)
210
+ self.play(Write(n_label), run_time=0.5)
211
+ self.wait(0.5)
212
+ self.remove(n_label)
213
+
214
+ self.wait(2)
215
+ ```
216
+
217
+ ### Secant Line to Tangent Line
218
+
219
+ ```python
220
+ class SecantToTangent(Scene):
221
+ """The derivative as limit of secant slopes."""
222
+
223
+ def construct(self):
224
+ axes = Axes(x_range=[-1, 5], y_range=[-1, 6], x_length=8, y_length=5)
225
+ graph = axes.plot(lambda x: 0.3 * x**2, color=YELLOW)
226
+ self.add(axes, graph)
227
+
228
+ # Fixed point
229
+ x0 = 2
230
+ dot_a = Dot(axes.i2gp(x0, graph), color=WHITE)
231
+ a_label = MathTex("a", font_size=30).next_to(dot_a, DL, buff=0.1)
232
+ self.play(FadeIn(dot_a), Write(a_label))
233
+
234
+ # Secant line that approaches tangent
235
+ dx_tracker = ValueTracker(2.0)
236
+
237
+ def get_secant_line():
238
+ dx = dx_tracker.get_value()
239
+ x1 = x0 + dx
240
+ p0 = axes.i2gp(x0, graph)
241
+ p1 = axes.i2gp(x1, graph)
242
+ slope = (p1[1] - p0[1]) / (p1[0] - p0[0]) if p1[0] != p0[0] else 0
243
+ line = axes.get_secant_slope_group(
244
+ x0, graph, dx=dx,
245
+ secant_line_color=BLUE,
246
+ secant_line_length=5,
247
+ )
248
+ return line
249
+
250
+ secant = always_redraw(get_secant_line)
251
+ self.add(secant)
252
+
253
+ # Animate dx shrinking
254
+ self.play(dx_tracker.animate.set_value(0.01), run_time=5, rate_func=smooth)
255
+ self.wait()
256
+
257
+ # Label as derivative
258
+ tangent_label = MathTex(
259
+ r"\text{slope} = f'(a)", font_size=36, color=BLUE,
260
+ ).to_corner(UR)
261
+ self.play(Write(tangent_label))
262
+ self.wait(2)
263
+ ```
264
+
265
+ ### Taylor Approximation
266
+
267
+ ```python
268
+ class TaylorApproximation(Scene):
269
+ """Progressive Taylor polynomial approximation."""
270
+
271
+ def construct(self):
272
+ axes = Axes(x_range=[-3, 3], y_range=[-2, 4], x_length=10, y_length=6)
273
+ original = axes.plot(np.exp, color=YELLOW, x_range=[-3, 1.5])
274
+ original_label = MathTex(r"e^x", color=YELLOW, font_size=36)
275
+ original_label.next_to(original, UR)
276
+
277
+ self.play(Create(axes), Create(original), Write(original_label))
278
+ self.wait()
279
+
280
+ # Taylor polynomials of increasing order
281
+ taylor_funcs = [
282
+ lambda x: 1,
283
+ lambda x: 1 + x,
284
+ lambda x: 1 + x + x**2 / 2,
285
+ lambda x: 1 + x + x**2 / 2 + x**3 / 6,
286
+ lambda x: 1 + x + x**2 / 2 + x**3 / 6 + x**4 / 24,
287
+ ]
288
+ colors = [RED, GREEN, BLUE, PURPLE, ORANGE]
289
+
290
+ prev_approx = None
291
+ for n, (func, color) in enumerate(zip(taylor_funcs, colors)):
292
+ approx = axes.plot(func, color=color, x_range=[-3, 3])
293
+ label = MathTex(f"n = {n}", font_size=30, color=color)
294
+ label.to_corner(UR).shift(n * 0.4 * DOWN)
295
+
296
+ if prev_approx is None:
297
+ self.play(Create(approx), Write(label))
298
+ else:
299
+ self.play(
300
+ Transform(prev_approx, approx),
301
+ Write(label),
302
+ )
303
+ prev_approx = approx
304
+ self.wait(0.5)
305
+
306
+ self.wait(2)
307
+ ```
308
+
309
+ ## Probability
310
+
311
+ From `_2019/bayes/`, `_2023/clt/`, `_2022/convolutions/`, and `_2018/eop/`.
312
+
313
+ ### Bar Charts for Distributions
314
+
315
+ ```python
316
+ class DistributionChart(Scene):
317
+ """Bar chart for probability distributions -- from CLT video."""
318
+
319
+ def construct(self):
320
+ axes = Axes(
321
+ x_range=[0, 6, 1], y_range=[0, 0.5, 0.1],
322
+ x_length=6, y_length=4,
323
+ axis_config={"include_tip": False},
324
+ )
325
+ axes.y_axis.add_numbers(font_size=20, num_decimal_places=1)
326
+
327
+ # Dice distribution
328
+ dist = [1/6] * 6
329
+ bars = VGroup()
330
+ for i, p in enumerate(dist):
331
+ bar = Rectangle(
332
+ width=0.7 * axes.x_axis.get_unit_size(),
333
+ height=p * axes.y_axis.get_unit_size(),
334
+ fill_color=BLUE_D, fill_opacity=0.8,
335
+ stroke_color=WHITE, stroke_width=1,
336
+ )
337
+ bar.move_to(axes.c2p(i + 0.5, 0), DOWN)
338
+ bars.add(bar)
339
+ bars.set_color_by_gradient(BLUE, TEAL)
340
+
341
+ # Dice face labels
342
+ dice_labels = VGroup(*[
343
+ MathTex(str(n), font_size=24).next_to(axes.c2p(n - 0.5, 0), DOWN, SMALL_BUFF)
344
+ for n in range(1, 7)
345
+ ])
346
+
347
+ self.play(Create(axes))
348
+ self.play(
349
+ LaggedStartMap(GrowFromEdge, bars, edge=DOWN, lag_ratio=0.15),
350
+ Write(dice_labels),
351
+ )
352
+ self.wait(2)
353
+ ```
354
+
355
+ ### Bayes Diagram
356
+
357
+ ```python
358
+ class BayesDiagram(Scene):
359
+ """Visual Bayes' theorem -- area-based probability."""
360
+
361
+ def construct(self):
362
+ # Full rectangle = total probability space
363
+ full_rect = Rectangle(width=8, height=4, stroke_color=WHITE)
364
+ full_rect.set_fill(BLUE_E, opacity=0.3)
365
+
366
+ # Split by prior P(H)
367
+ prior = 0.01 # e.g., disease prevalence
368
+ divider_x = full_rect.get_left()[0] + prior * full_rect.width
369
+ v_line = Line(
370
+ [divider_x, full_rect.get_bottom()[1], 0],
371
+ [divider_x, full_rect.get_top()[1], 0],
372
+ color=YELLOW, stroke_width=3,
373
+ )
374
+
375
+ # H region
376
+ h_rect = Rectangle(
377
+ width=prior * full_rect.width,
378
+ height=full_rect.height,
379
+ fill_color=GREEN, fill_opacity=0.5,
380
+ stroke_color=WHITE,
381
+ )
382
+ h_rect.align_to(full_rect, LEFT + DOWN)
383
+
384
+ h_label = MathTex(r"P(H)", font_size=30, color=GREEN)
385
+ h_label.next_to(h_rect, UP)
386
+
387
+ not_h_label = MathTex(r"P(\neg H)", font_size=30, color=RED)
388
+ not_h_label.next_to(full_rect, UP).shift(2 * RIGHT)
389
+
390
+ self.play(DrawBorderThenFill(full_rect))
391
+ self.play(Create(v_line), DrawBorderThenFill(h_rect))
392
+ self.play(Write(h_label), Write(not_h_label))
393
+ self.wait(2)
394
+ ```
395
+
396
+ ## Complex Analysis
397
+
398
+ From `_2018/holomorphic.py`, `_2016/zeta.py`, `_2025/zeta/play.py`, and `_2025/laplace/`.
399
+
400
+ ### Complex Plane Transformations
401
+
402
+ ```python
403
+ class ComplexTransformation(Scene):
404
+ """Visualize a complex function as a transformation of the plane."""
405
+
406
+ def construct(self):
407
+ plane = ComplexPlane(
408
+ x_range=[-3, 3], y_range=[-3, 3],
409
+ background_line_style={"stroke_opacity": 0.4},
410
+ )
411
+ plane.add_coordinate_labels(font_size=20)
412
+ self.add(plane)
413
+
414
+ # Label
415
+ func_label = MathTex(r"f(z) = z^2", font_size=40)
416
+ func_label.to_corner(UL)
417
+ func_label.set_backstroke(width=3)
418
+ self.play(Write(func_label))
419
+ self.wait()
420
+
421
+ # Apply the transformation
422
+ self.play(
423
+ plane.animate.apply_complex_function(lambda z: z**2),
424
+ run_time=3,
425
+ )
426
+ self.wait(2)
427
+ ```
428
+
429
+ ### Partial Sum Paths (Zeta Function Pattern)
430
+
431
+ From `_2025/zeta/play.py`:
432
+
433
+ ```python
434
+ class ZetaPartialSums(Scene):
435
+ """Visualize partial sums of a complex series as a spiral path."""
436
+
437
+ def construct(self):
438
+ plane = ComplexPlane(
439
+ x_range=[-3, 3], y_range=[-3, 3],
440
+ x_length=8, y_length=8,
441
+ )
442
+ plane.add_coordinate_labels(font_size=16)
443
+ self.add(plane)
444
+
445
+ # Partial sums of 1/n^s
446
+ s = complex(0.5, 14.134) # Near first zeta zero
447
+ partial_sums = [0]
448
+ for n in range(1, 100):
449
+ partial_sums.append(partial_sums[-1] + 1 / n**s)
450
+
451
+ # Convert to points on the plane
452
+ points = [plane.n2p(z) for z in partial_sums]
453
+
454
+ # Draw the path
455
+ path = VMobject()
456
+ path.set_points_smoothly(points)
457
+ path.set_stroke(YELLOW, 2)
458
+
459
+ # Starting dot
460
+ start_dot = Dot(points[0], color=GREEN)
461
+ end_dot = Dot(points[-1], color=RED)
462
+
463
+ self.play(FadeIn(start_dot))
464
+ self.play(Create(path), run_time=5)
465
+ self.play(FadeIn(end_dot))
466
+ self.wait(2)
467
+ ```
468
+
469
+ ## Number Theory
470
+
471
+ From `_2019/spirals.py` -- prime number spirals.
472
+
473
+ ```python
474
+ class PrimeSpiral(Scene):
475
+ """Ulam-like prime spiral visualization."""
476
+
477
+ def construct(self):
478
+ # Generate dots for integers 1 to N
479
+ N = 5000
480
+ dots = VGroup()
481
+ prime_dots = VGroup()
482
+
483
+ for n in range(1, N):
484
+ # Polar coordinates: angle = n, radius = sqrt(n)
485
+ angle = n
486
+ radius = np.sqrt(n) * 0.05
487
+ point = radius * np.array([np.cos(angle), np.sin(angle), 0])
488
+ dot = Dot(point, radius=0.02)
489
+
490
+ if self._is_prime(n):
491
+ dot.set_color(TEAL)
492
+ prime_dots.add(dot)
493
+ else:
494
+ dot.set_color(GREY_D)
495
+ dot.set_opacity(0.2)
496
+ dots.add(dot)
497
+
498
+ self.play(
499
+ LaggedStartMap(FadeIn, dots, lag_ratio=0.001),
500
+ run_time=5,
501
+ )
502
+ self.wait(2)
503
+
504
+ @staticmethod
505
+ def _is_prime(n):
506
+ if n < 2:
507
+ return False
508
+ for k in range(2, int(np.sqrt(n)) + 1):
509
+ if n % k == 0:
510
+ return False
511
+ return True
512
+ ```
513
+
514
+ ## Topology
515
+
516
+ From `_2020/surface_play.py`, `_2024/inscribed_rect/`.
517
+
518
+ ### 3D Surface Construction
519
+
520
+ ```python
521
+ class SurfaceVisualization(ThreeDScene):
522
+ """Torus, sphere, and Mobius strip -- from surface_play.py."""
523
+
524
+ def construct(self):
525
+ self.set_camera_orientation(phi=70 * DEGREES, theta=-45 * DEGREES)
526
+
527
+ # Torus
528
+ torus = Surface(
529
+ lambda u, v: np.array([
530
+ (3 + np.cos(v)) * np.cos(u),
531
+ (3 + np.cos(v)) * np.sin(u),
532
+ np.sin(v),
533
+ ]),
534
+ u_range=[0, TAU],
535
+ v_range=[0, TAU],
536
+ resolution=(30, 20),
537
+ )
538
+ torus.set_fill_by_checkerboard(BLUE_D, BLUE_E, opacity=0.8)
539
+ torus.scale(0.5)
540
+
541
+ self.play(Create(torus), run_time=3)
542
+ self.begin_ambient_camera_rotation(rate=0.2)
543
+ self.wait(5)
544
+ ```
545
+
546
+ ## Neural Networks / Machine Learning
547
+
548
+ From `_2024/transformers/` (attention, embedding, mlp, helpers).
549
+
550
+ ### Weight Matrix Visualization
551
+
552
+ ```python
553
+ class WeightMatrixViz(Scene):
554
+ """Heatmap-style weight matrix -- from transformers helpers."""
555
+
556
+ def construct(self):
557
+ # Create matrix with color-coded entries
558
+ n_rows, n_cols = 6, 8
559
+ values = np.random.randn(n_rows, n_cols)
560
+
561
+ entries = VGroup()
562
+ cell_size = 0.5
563
+ for i in range(n_rows):
564
+ for j in range(n_cols):
565
+ val = values[i, j]
566
+ # value_to_color: positive=BLUE, negative=RED
567
+ alpha = min(abs(val) / 3, 1)
568
+ if val >= 0:
569
+ color = interpolate_color(BLUE_E, BLUE_B, alpha)
570
+ else:
571
+ color = interpolate_color(RED_E, RED_B, alpha)
572
+
573
+ cell = Square(side_length=cell_size)
574
+ cell.set_fill(color, opacity=0.8)
575
+ cell.set_stroke(WHITE, 0.5)
576
+ cell.move_to([j * cell_size, -i * cell_size, 0])
577
+ entries.add(cell)
578
+
579
+ entries.center()
580
+
581
+ # Brackets
582
+ left_bracket = MathTex(r"\left[", font_size=72)
583
+ right_bracket = MathTex(r"\right]", font_size=72)
584
+ left_bracket.next_to(entries, LEFT, buff=0.1)
585
+ right_bracket.next_to(entries, RIGHT, buff=0.1)
586
+
587
+ matrix_group = VGroup(left_bracket, entries, right_bracket)
588
+
589
+ label = MathTex(r"W_Q", font_size=36, color=YELLOW)
590
+ label.next_to(matrix_group, UP)
591
+
592
+ self.play(
593
+ FadeIn(entries, lag_ratio=0.01),
594
+ Write(left_bracket), Write(right_bracket),
595
+ Write(label),
596
+ run_time=2,
597
+ )
598
+ self.wait(2)
599
+ ```
600
+
601
+ ### Attention Arcs (from transformers/attention.py)
602
+
603
+ ```python
604
+ class AttentionArcs(Scene):
605
+ """Visualize attention patterns between words -- from 3b1b's transformer series."""
606
+
607
+ def construct(self):
608
+ words = ["a", "fluffy", "blue", "creature", "roamed"]
609
+ word_mobs = VGroup(*[Text(w, font_size=30) for w in words])
610
+ word_mobs.arrange(RIGHT, buff=0.6)
611
+ word_mobs.shift(UP)
612
+
613
+ # Word rectangles
614
+ rects = VGroup(*[
615
+ SurroundingRectangle(w, buff=0.1, stroke_color=GREY, stroke_width=1)
616
+ for w in word_mobs
617
+ ])
618
+
619
+ self.play(
620
+ LaggedStartMap(FadeIn, word_mobs, shift=0.5 * UP, lag_ratio=0.25)
621
+ )
622
+ self.play(FadeIn(rects))
623
+ self.wait()
624
+
625
+ # Attention arcs: adjectives attend to their nouns
626
+ connections = [(1, 3), (2, 3)] # "fluffy"->creature, "blue"->creature
627
+ arcs = VGroup()
628
+ for src, tgt in connections:
629
+ arc = Arrow(
630
+ word_mobs[src].get_top(),
631
+ word_mobs[tgt].get_top(),
632
+ path_arc=-150 * DEGREES,
633
+ buff=0.1,
634
+ stroke_color=GREY_B,
635
+ stroke_width=2,
636
+ )
637
+ arcs.add(arc)
638
+
639
+ self.play(LaggedStartMap(Create, arcs, lag_ratio=0.3, run_time=1.5))
640
+ self.wait(2)
641
+ ```
642
+
643
+ ### Embedding Vectors
644
+
645
+ ```python
646
+ class EmbeddingVisualization(Scene):
647
+ """Token embedding as a column of colored numbers."""
648
+
649
+ def construct(self):
650
+ # Create a numeric embedding display
651
+ values = np.random.randn(10)
652
+ entries = VGroup()
653
+ for val in values:
654
+ alpha = min(abs(val) / 2, 1)
655
+ color = interpolate_color(BLUE_E, BLUE_B, alpha) if val >= 0 else \
656
+ interpolate_color(RED_E, RED_B, alpha)
657
+ dec = DecimalNumber(val, num_decimal_places=2, font_size=24)
658
+ dec.set_color(color)
659
+ entries.add(dec)
660
+
661
+ entries.arrange(DOWN, buff=0.15)
662
+
663
+ # Brackets
664
+ left_b = MathTex(r"\left[", font_size=60).next_to(entries, LEFT, buff=0.1)
665
+ right_b = MathTex(r"\right]", font_size=60).next_to(entries, RIGHT, buff=0.1)
666
+
667
+ embedding = VGroup(left_b, entries, right_b)
668
+
669
+ # Label
670
+ word = Text("creature", font_size=30)
671
+ word.next_to(embedding, UP, buff=0.5)
672
+ arrow = Arrow(word.get_bottom(), embedding.get_top(), buff=0.1)
673
+
674
+ self.play(Write(word))
675
+ self.play(GrowArrow(arrow))
676
+ self.play(FadeIn(embedding, shift=0.5 * DOWN))
677
+ self.wait(2)
678
+ ```
679
+
680
+ ## Best Practices by Domain
681
+
682
+ 1. **Linear Algebra**: Always use GREEN for x/i-hat, RED for y/j-hat, BLUE for z/k-hat
683
+ 2. **Calculus**: Show the geometric meaning alongside every formula
684
+ 3. **Probability**: Use bar charts with gradient coloring (BLUE to TEAL)
685
+ 4. **Complex Analysis**: Use ComplexPlane with `apply_complex_function()` for transformations
686
+ 5. **Number Theory**: Polar coordinate layouts reveal hidden structure
687
+ 6. **Topology**: Use ThreeDScene with ambient camera rotation for surfaces
688
+ 7. **Neural Networks**: Color-code matrix entries by value (positive=BLUE, negative=RED)
689
+ 8. **Across all domains**: Use `tex_to_color_map` / `t2c` for consistent color-coded equations