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,212 @@
1
+ """
2
+ Basic Animation Patterns for Manim Community
3
+
4
+ This file demonstrates fundamental animation techniques adapted from 3b1b patterns.
5
+ Run with: manim -pql basic_animations.py SceneName
6
+ """
7
+
8
+ from manim import *
9
+
10
+
11
+ class ShapeCreation(Scene):
12
+ """Demonstrates various ways to create and animate shapes."""
13
+
14
+ def construct(self):
15
+ # Create shapes
16
+ circle = Circle(radius=1, color=BLUE, fill_opacity=0.5)
17
+ square = Square(side_length=2, color=RED)
18
+ triangle = Triangle(color=GREEN, fill_opacity=0.8)
19
+
20
+ # Arrange shapes
21
+ shapes = VGroup(circle, square, triangle).arrange(RIGHT, buff=1)
22
+
23
+ # Different creation animations
24
+ self.play(Create(circle)) # Draw outline progressively
25
+ self.play(DrawBorderThenFill(square)) # Border first, then fill
26
+ self.play(GrowFromCenter(triangle)) # Grow from center point
27
+
28
+ self.wait()
29
+
30
+ # Transform between shapes
31
+ self.play(Transform(circle, square.copy().shift(UP * 2)))
32
+
33
+ self.wait()
34
+
35
+
36
+ class TextAnimations(Scene):
37
+ """Demonstrates text and LaTeX animations."""
38
+
39
+ def construct(self):
40
+ # Plain text
41
+ title = Text("Manim Community", font_size=72, color=BLUE)
42
+ self.play(Write(title))
43
+ self.wait()
44
+
45
+ # Move title up
46
+ self.play(title.animate.to_edge(UP))
47
+
48
+ # LaTeX math
49
+ equation = MathTex(r"e^{i\pi} + 1 = 0", font_size=64)
50
+ self.play(Write(equation))
51
+ self.wait()
52
+
53
+ # Transform equation
54
+ expanded = MathTex(r"e^{i\pi} = -1", font_size=64)
55
+ self.play(TransformMatchingTex(equation, expanded))
56
+
57
+ self.wait()
58
+
59
+
60
+ class LaggedAnimations(Scene):
61
+ """Demonstrates staggered animations using LaggedStart patterns."""
62
+
63
+ def construct(self):
64
+ # Create a grid of dots
65
+ dots = VGroup(*[
66
+ Dot(radius=0.15, color=interpolate_color(BLUE, RED, i / 24))
67
+ for i in range(25)
68
+ ]).arrange_in_grid(rows=5, cols=5, buff=0.5)
69
+
70
+ # Staggered fade in
71
+ self.play(
72
+ LaggedStart(*[FadeIn(dot, scale=0.5) for dot in dots], lag_ratio=0.1)
73
+ )
74
+ self.wait()
75
+
76
+ # Staggered transformation using LaggedStart with animate
77
+ self.play(
78
+ LaggedStart(
79
+ *[dot.animate.scale(1.5).set_color(YELLOW) for dot in dots],
80
+ lag_ratio=0.05
81
+ )
82
+ )
83
+ self.wait()
84
+
85
+ # Wave effect using AnimationGroup with rate_func
86
+ self.play(
87
+ LaggedStart(
88
+ *[dot.animate(rate_func=there_and_back).shift(UP * 0.5) for dot in dots],
89
+ lag_ratio=0.02,
90
+ run_time=2
91
+ )
92
+ )
93
+
94
+
95
+ class AnimationComposition(Scene):
96
+ """Demonstrates combining multiple animations."""
97
+
98
+ def construct(self):
99
+ # Create objects
100
+ circle = Circle(color=BLUE, fill_opacity=0.5)
101
+ label = Text("Circle", font_size=36).next_to(circle, DOWN)
102
+
103
+ # Group them
104
+ group = VGroup(circle, label)
105
+
106
+ # Animate together
107
+ self.play(
108
+ Create(circle),
109
+ Write(label),
110
+ run_time=2
111
+ )
112
+ self.wait()
113
+
114
+ # Sequential animations with Succession
115
+ square = Square(color=RED, fill_opacity=0.5).shift(RIGHT * 3)
116
+ square_label = Text("Square", font_size=36).next_to(square, DOWN)
117
+
118
+ self.play(
119
+ Succession(
120
+ group.animate.shift(LEFT * 2),
121
+ Create(square),
122
+ Write(square_label),
123
+ lag_ratio=0.5
124
+ )
125
+ )
126
+ self.wait()
127
+
128
+
129
+ class PathAnimations(Scene):
130
+ """Demonstrates movement along paths."""
131
+
132
+ def construct(self):
133
+ # Create a path
134
+ path = VMobject()
135
+ path.set_points_smoothly([
136
+ LEFT * 3,
137
+ LEFT * 2 + UP * 2,
138
+ ORIGIN + UP,
139
+ RIGHT * 2 + UP * 2,
140
+ RIGHT * 3,
141
+ ])
142
+ path.set_color(GREY)
143
+
144
+ # Create moving object
145
+ dot = Dot(color=RED, radius=0.2)
146
+ dot.move_to(path.get_start())
147
+
148
+ self.add(path)
149
+ self.play(Create(path))
150
+
151
+ # Move along path
152
+ self.play(MoveAlongPath(dot, path), run_time=3, rate_func=smooth)
153
+
154
+ self.wait()
155
+
156
+
157
+ class ColorTransitions(Scene):
158
+ """Demonstrates color manipulation and gradients."""
159
+
160
+ def construct(self):
161
+ # Color gradient on shapes
162
+ squares = VGroup(*[
163
+ Square(side_length=0.8, fill_opacity=0.8)
164
+ for _ in range(7)
165
+ ]).arrange(RIGHT, buff=0.2)
166
+
167
+ # Apply gradient colors
168
+ colors = [RED, ORANGE, YELLOW, GREEN, BLUE, PURPLE, PINK]
169
+ for square, color in zip(squares, colors):
170
+ square.set_fill(color)
171
+ square.set_stroke(WHITE, width=2)
172
+
173
+ self.play(LaggedStartMap(GrowFromCenter, squares, lag_ratio=0.1))
174
+ self.wait()
175
+
176
+ # Animate color change
177
+ self.play(
178
+ *[square.animate.set_fill(interpolate_color(BLUE, RED, i / 6))
179
+ for i, square in enumerate(squares)],
180
+ run_time=2
181
+ )
182
+ self.wait()
183
+
184
+
185
+ class GroupOperations(Scene):
186
+ """Demonstrates VGroup operations and arrangements."""
187
+
188
+ def construct(self):
189
+ # Create VGroup
190
+ shapes = VGroup(
191
+ Circle(color=RED),
192
+ Square(color=GREEN),
193
+ Triangle(color=BLUE),
194
+ )
195
+
196
+ # Arrange horizontally
197
+ shapes.arrange(RIGHT, buff=1)
198
+ self.play(Create(shapes))
199
+ self.wait()
200
+
201
+ # Scale entire group
202
+ self.play(shapes.animate.scale(0.5))
203
+ self.wait()
204
+
205
+ # Arrange vertically
206
+ self.play(shapes.animate.arrange(DOWN, buff=0.5))
207
+ self.wait()
208
+
209
+ # Apply operation to all
210
+ self.play(shapes.animate.set_fill(YELLOW, opacity=0.5))
211
+
212
+ self.wait()
@@ -0,0 +1,401 @@
1
+ """
2
+ Graph and Function Plotting Patterns for Manim Community
3
+
4
+ Demonstrates Axes, NumberPlane, function plotting, and coordinate systems.
5
+ Adapted from 3b1b patterns for ManimCE.
6
+
7
+ Run with: manim -pql graph_plotting.py SceneName
8
+ """
9
+
10
+ from manim import *
11
+ import numpy as np
12
+
13
+
14
+ class BasicAxes(Scene):
15
+ """Basic axes setup and labeling."""
16
+
17
+ def construct(self):
18
+ # Create axes
19
+ axes = Axes(
20
+ x_range=[-3, 3, 1],
21
+ y_range=[-2, 2, 1],
22
+ x_length=8,
23
+ y_length=5,
24
+ axis_config={
25
+ "include_tip": True,
26
+ "include_numbers": True,
27
+ },
28
+ )
29
+
30
+ # Labels
31
+ x_label = axes.get_x_axis_label("x")
32
+ y_label = axes.get_y_axis_label("y")
33
+
34
+ self.play(Create(axes), Write(x_label), Write(y_label))
35
+ self.wait()
36
+
37
+
38
+ class FunctionPlotting(Scene):
39
+ """Plotting functions on axes."""
40
+
41
+ def construct(self):
42
+ axes = Axes(
43
+ x_range=[-3, 3, 1],
44
+ y_range=[-1, 9, 2],
45
+ x_length=8,
46
+ y_length=5,
47
+ axis_config={"include_numbers": True},
48
+ )
49
+
50
+ # Plot y = x^2
51
+ parabola = axes.plot(
52
+ lambda x: x ** 2,
53
+ color=BLUE,
54
+ x_range=[-3, 3]
55
+ )
56
+
57
+ # Label
58
+ label = MathTex(r"y = x^2", color=BLUE)
59
+ label.next_to(parabola, UR)
60
+
61
+ self.play(Create(axes))
62
+ self.play(Create(parabola), Write(label))
63
+ self.wait()
64
+
65
+
66
+ class MultipleFunctions(Scene):
67
+ """Multiple functions on same axes."""
68
+
69
+ def construct(self):
70
+ axes = Axes(
71
+ x_range=[-2 * PI, 2 * PI, PI / 2],
72
+ y_range=[-1.5, 1.5, 0.5],
73
+ x_length=10,
74
+ y_length=4,
75
+ )
76
+
77
+ # Plot sine and cosine
78
+ sine = axes.plot(np.sin, color=BLUE, x_range=[-2 * PI, 2 * PI])
79
+ cosine = axes.plot(np.cos, color=RED, x_range=[-2 * PI, 2 * PI])
80
+
81
+ # Labels
82
+ sin_label = MathTex(r"\sin(x)", color=BLUE).to_corner(UR)
83
+ cos_label = MathTex(r"\cos(x)", color=RED).next_to(sin_label, DOWN)
84
+
85
+ self.play(Create(axes))
86
+ self.play(Create(sine), Write(sin_label))
87
+ self.play(Create(cosine), Write(cos_label))
88
+ self.wait()
89
+
90
+
91
+ class AreaUnderCurve(Scene):
92
+ """Visualizing area under a curve (integration)."""
93
+
94
+ def construct(self):
95
+ axes = Axes(
96
+ x_range=[0, 5, 1],
97
+ y_range=[0, 10, 2],
98
+ x_length=8,
99
+ y_length=5,
100
+ )
101
+
102
+ # Function
103
+ func = axes.plot(lambda x: 0.5 * x ** 2, color=BLUE, x_range=[0, 4])
104
+
105
+ # Area under curve from x=1 to x=3
106
+ area = axes.get_area(
107
+ func,
108
+ x_range=[1, 3],
109
+ color=BLUE,
110
+ opacity=0.3
111
+ )
112
+
113
+ # Integral notation
114
+ integral = MathTex(
115
+ r"\int_1^3 \frac{x^2}{2} \, dx",
116
+ font_size=48
117
+ ).to_corner(UR)
118
+
119
+ self.play(Create(axes))
120
+ self.play(Create(func))
121
+ self.play(FadeIn(area))
122
+ self.play(Write(integral))
123
+ self.wait()
124
+
125
+
126
+ class NumberPlaneExample(Scene):
127
+ """Using NumberPlane for coordinate grid."""
128
+
129
+ def construct(self):
130
+ # Create number plane
131
+ plane = NumberPlane(
132
+ x_range=[-7, 7, 1],
133
+ y_range=[-4, 4, 1],
134
+ background_line_style={
135
+ "stroke_color": BLUE_D,
136
+ "stroke_width": 1,
137
+ "stroke_opacity": 0.5,
138
+ }
139
+ )
140
+
141
+ # Plot a point
142
+ point = Dot(plane.c2p(2, 3), color=RED, radius=0.15)
143
+ point_label = MathTex("(2, 3)", color=RED).next_to(point, UR, buff=0.1)
144
+
145
+ # Vector from origin to point
146
+ vector = Arrow(
147
+ plane.c2p(0, 0),
148
+ plane.c2p(2, 3),
149
+ buff=0,
150
+ color=YELLOW
151
+ )
152
+
153
+ self.play(Create(plane))
154
+ self.play(GrowArrow(vector))
155
+ self.play(FadeIn(point), Write(point_label))
156
+ self.wait()
157
+
158
+
159
+ class ParametricCurve(Scene):
160
+ """Plotting parametric curves."""
161
+
162
+ def construct(self):
163
+ axes = Axes(
164
+ x_range=[-4, 4, 1],
165
+ y_range=[-4, 4, 1],
166
+ x_length=7,
167
+ y_length=7,
168
+ )
169
+
170
+ # Parametric curve (circle)
171
+ circle = axes.plot_parametric_curve(
172
+ lambda t: np.array([2 * np.cos(t), 2 * np.sin(t), 0]),
173
+ t_range=[0, 2 * PI],
174
+ color=BLUE
175
+ )
176
+
177
+ # Lissajous curve
178
+ lissajous = axes.plot_parametric_curve(
179
+ lambda t: np.array([2 * np.sin(3 * t), 2 * np.sin(2 * t), 0]),
180
+ t_range=[0, 2 * PI],
181
+ color=RED
182
+ )
183
+
184
+ self.play(Create(axes))
185
+ self.play(Create(circle))
186
+ self.wait()
187
+ self.play(Transform(circle, lissajous))
188
+ self.wait()
189
+
190
+
191
+ class TangentLine(Scene):
192
+ """Showing tangent line to a curve."""
193
+
194
+ def construct(self):
195
+ axes = Axes(
196
+ x_range=[-1, 4, 1],
197
+ y_range=[-1, 10, 2],
198
+ x_length=8,
199
+ y_length=5,
200
+ )
201
+
202
+ # Function y = x^2
203
+ func = axes.plot(lambda x: x ** 2, color=BLUE, x_range=[0, 3])
204
+
205
+ # Point of tangency at x = 2
206
+ x_val = 2
207
+ point = Dot(axes.c2p(x_val, x_val ** 2), color=RED)
208
+
209
+ # Tangent line: derivative of x^2 is 2x, at x=2 slope is 4
210
+ tangent = axes.plot(
211
+ lambda x: 4 * (x - 2) + 4, # Point-slope form
212
+ color=YELLOW,
213
+ x_range=[0.5, 3.5]
214
+ )
215
+
216
+ # Label
217
+ slope_label = MathTex(r"m = 2x = 4", color=YELLOW).to_corner(UR)
218
+
219
+ self.play(Create(axes))
220
+ self.play(Create(func))
221
+ self.play(FadeIn(point))
222
+ self.play(Create(tangent), Write(slope_label))
223
+ self.wait()
224
+
225
+
226
+ class AnimatedGraph(Scene):
227
+ """Animating a function parameter change."""
228
+
229
+ def construct(self):
230
+ axes = Axes(
231
+ x_range=[-3, 3, 1],
232
+ y_range=[-2, 2, 1],
233
+ x_length=8,
234
+ y_length=5,
235
+ )
236
+
237
+ # Amplitude tracker
238
+ amplitude = ValueTracker(1)
239
+
240
+ # Graph that updates with amplitude
241
+ graph = always_redraw(
242
+ lambda: axes.plot(
243
+ lambda x: amplitude.get_value() * np.sin(x),
244
+ color=BLUE,
245
+ x_range=[-3, 3]
246
+ )
247
+ )
248
+
249
+ # Amplitude display
250
+ amp_text = always_redraw(
251
+ lambda: MathTex(
252
+ f"A = {amplitude.get_value():.1f}"
253
+ ).to_corner(UR)
254
+ )
255
+
256
+ self.add(axes, graph, amp_text)
257
+
258
+ # Animate amplitude change
259
+ self.play(amplitude.animate.set_value(2), run_time=2)
260
+ self.play(amplitude.animate.set_value(0.5), run_time=2)
261
+ self.play(amplitude.animate.set_value(1.5), run_time=1)
262
+ self.wait()
263
+
264
+
265
+ class RiemannSum(Scene):
266
+ """Visualizing Riemann sums for integration."""
267
+
268
+ def construct(self):
269
+ axes = Axes(
270
+ x_range=[0, 5, 1],
271
+ y_range=[0, 5, 1],
272
+ x_length=8,
273
+ y_length=5,
274
+ )
275
+
276
+ # Function
277
+ func = axes.plot(lambda x: 0.2 * x ** 2, color=BLUE, x_range=[0, 4])
278
+
279
+ self.play(Create(axes), Create(func))
280
+ self.wait()
281
+
282
+ # Riemann rectangles
283
+ dx_values = [1, 0.5, 0.25]
284
+
285
+ for dx in dx_values:
286
+ rects = axes.get_riemann_rectangles(
287
+ func,
288
+ x_range=[1, 3],
289
+ dx=dx,
290
+ color=BLUE,
291
+ fill_opacity=0.5,
292
+ stroke_width=1,
293
+ )
294
+
295
+ if dx == 1:
296
+ self.play(Create(rects))
297
+ else:
298
+ self.play(Transform(rects, rects))
299
+
300
+ self.wait()
301
+
302
+
303
+ class ImplicitFunction(Scene):
304
+ """Plotting implicit functions (level curves)."""
305
+
306
+ def construct(self):
307
+ axes = Axes(
308
+ x_range=[-4, 4, 1],
309
+ y_range=[-4, 4, 1],
310
+ x_length=7,
311
+ y_length=7,
312
+ )
313
+
314
+ # Circle x^2 + y^2 = 4 as parametric
315
+ circle = axes.plot_parametric_curve(
316
+ lambda t: np.array([2 * np.cos(t), 2 * np.sin(t), 0]),
317
+ t_range=[0, 2 * PI],
318
+ color=BLUE
319
+ )
320
+
321
+ # Equation label
322
+ equation = MathTex(r"x^2 + y^2 = 4", color=BLUE).to_corner(UR)
323
+
324
+ self.play(Create(axes))
325
+ self.play(Create(circle), Write(equation))
326
+ self.wait()
327
+
328
+
329
+ class CoordinateLabeling(Scene):
330
+ """Advanced coordinate labeling techniques."""
331
+
332
+ def construct(self):
333
+ axes = Axes(
334
+ x_range=[-1, 5, 1],
335
+ y_range=[-1, 5, 1],
336
+ x_length=7,
337
+ y_length=7,
338
+ axis_config={"include_numbers": True},
339
+ )
340
+
341
+ # Function
342
+ func = axes.plot(lambda x: np.sqrt(x), color=BLUE, x_range=[0, 4])
343
+
344
+ # Highlight a specific point
345
+ x_val = 2
346
+ y_val = np.sqrt(2)
347
+
348
+ point = Dot(axes.c2p(x_val, y_val), color=RED)
349
+
350
+ # Dashed lines to axes
351
+ h_line = DashedLine(
352
+ axes.c2p(0, y_val),
353
+ axes.c2p(x_val, y_val),
354
+ color=GREY
355
+ )
356
+ v_line = DashedLine(
357
+ axes.c2p(x_val, 0),
358
+ axes.c2p(x_val, y_val),
359
+ color=GREY
360
+ )
361
+
362
+ # Labels
363
+ x_label = MathTex("2").next_to(axes.c2p(x_val, 0), DOWN)
364
+ y_label = MathTex(r"\sqrt{2}").next_to(axes.c2p(0, y_val), LEFT)
365
+
366
+ self.play(Create(axes))
367
+ self.play(Create(func))
368
+ self.play(Create(v_line), Create(h_line))
369
+ self.play(FadeIn(point), Write(x_label), Write(y_label))
370
+ self.wait()
371
+
372
+
373
+ class PolarPlot(Scene):
374
+ """Plotting in polar coordinates."""
375
+
376
+ def construct(self):
377
+ # Polar axes
378
+ polar_plane = PolarPlane(
379
+ radius_max=3,
380
+ size=6,
381
+ )
382
+
383
+ # Polar curve: r = 1 + sin(theta) (cardioid)
384
+ cardioid = polar_plane.plot_polar_graph(
385
+ lambda theta: 1 + np.sin(theta),
386
+ theta_range=[0, 2 * PI],
387
+ color=BLUE
388
+ )
389
+
390
+ # Rose curve: r = 2*cos(3*theta)
391
+ rose = polar_plane.plot_polar_graph(
392
+ lambda theta: 2 * np.cos(3 * theta),
393
+ theta_range=[0, PI],
394
+ color=RED
395
+ )
396
+
397
+ self.play(Create(polar_plane))
398
+ self.play(Create(cardioid))
399
+ self.wait()
400
+ self.play(Transform(cardioid, rose))
401
+ self.wait()