# This is the source code for the Manim presentation that Per gave at the # syscop group retreat on Feb 15-17, 2023 # Note: There are much better ways to learn Manim on-line than reading this code! # To run this, you need first need to install Manim Comunity Edition, and manim-slides. # First render the slides with the command # manim per_manim_presentation.py -ql TalkOutline WhatIs HowTo ExampleOutline TexTransformExample TexTransformCode # (The -ql flag means render lower quality, which is faster. Omit it for higher quality.) # Then start the slide show with # manim-slides TalkOutline WhatIs HowTo ExampleOutline TexTransformExample TexTransformCode from manim import * from manim_slides import Slide # There's a bug in manim-slides where it does not render the last frame of the previous animation # on my system. Adding a short "wait" before each "pause" pause as a work-around. def wpause(s): s.wait(0.1) s.pause() class TalkOutline(Slide): def construct(self): title = Tex("An introduction to Manim") self.play(Write(title)) wpause(self) sections = VGroup(Tex("-- What is Manim?"), Tex("-- How do we use it?")) sections.arrange(DOWN, buff=1) self.play(title.animate.scale(1.2).move_to(UP * 2.2), runtime=0.5) for s in sections: self.play(Write(s), run_time=1.0) wpause(self) self.play(FadeOut(VGroup(title, sections), scale=0.9), run_time=0.5) wpause(self) class WhatIs(Slide): def construct(self): title = Tex("What", " is ", "Manim", "?") title2 = Tex("Manim", " is ") self.play(Write(title)) wpause(self) #self.play(title.animate.scale(1.2).move_to(UP * 3), runtime=0.5) title2.scale(1.2).move_to(UP * 3) self.play(TransformMatchingTex(title, title2, path_arc = 30*DEGREES), run_time=1.0) sections = VGroup(Tex("an animation engine for explanatory Math videos"), Tex("created by Grant Sanderson (3Blue1Brown)"), Tex("which uses Python instead of PowerPoint,"), Tex("is open source, has great support for \\LaTeX,"), Tex("and a large community.")) sections.arrange(DOWN, buff=0.5).move_to(DOWN * 0.5) for s in sections: self.play(Write(s, run_time=1)) wpause(self) self.play(FadeOut(VGroup(title2, sections), scale=0.9), run_time=0.5) wpause(self) class HowTo(Slide): def construct(self): title = Tex("How to use Manim?") self.play(Write(title)) wpause(self) self.play(title.animate.scale(1.2).move_to(UP * 3), runtime=0.5) sections = VGroup(Tex("Write Python code"), Tex("that creates the graphics,"), Tex("then write some more code,"), Tex("to control the animation."), Tex("Then (optionally) add voiceover.")) sections.arrange(DOWN, buff=0.5).move_to(DOWN * 0.5) for (i,s) in enumerate(sections): self.play(Write(s, run_time=1)) if i in {1, 3, 4}: wpause(self) self.play(FadeOut(VGroup(title, sections), scale=0.9), run_time=0.5) wpause(self) outlinecode = r''' from manim import * from manim_slides import Slide class TalkOutline(Slide): def construct(self): title = Tex("A Manim Tutorial") self.play(Write(title)) wpause(self) sections = VGroup(Tex("-- What is Manim?"), Tex("-- How can we use it?")).arrange(DOWN, buff=1) self.play(title.animate.scale(1.2).move_to(UP*2.2), runtime=0.5) for s in sections: self.play(Write(s)) wpause(self) self.play(FadeOut(VGroup(title, sections), scale=0.9), run_time=0.5) ''' class ExampleOutline(Slide): def construct(self): rendered_code = Code(code=outlinecode, tab_width=4, background="window", language="Python", font="Monospace").scale(0.75) self.play(Create(rendered_code, run_time=12)) wpause(self) self.play(FadeOut(rendered_code, scale=0.9), run_time=0.2) wpause(self) # This example is adapted from the TexTransformExample code found at # https://3b1b.github.io/manim/getting_started/example_scenes.html class TexTransformExample(Slide): def construct(self): play_kw = {"run_time": 2} title = Tex("\\LaTeX~~Transformation").scale(1.2) to_isolate = ["B", "C", "=", "(", ")"] lines = VGroup( MathTex("A^2", "+", "B^2", "=", "C^2"), MathTex("A^2", "=", "C^2", "-", "B^2"), MathTex("A^2 = (C + B)(C - B)", substrings_to_isolate=["A^2", *to_isolate]), MathTex("A = \\sqrt{(C + B)(C - B)}", substrings_to_isolate=["A", *to_isolate]) ) lines.arrange(DOWN, buff=1) tlines = VGroup(title, lines) tlines.arrange(DOWN, buff=1.2) for line in lines: line.set_color_by_tex_to_color_map({ "A": BLUE, "B": TEAL, "C": GREEN, }) self.play(FadeIn(title), run_time=0.2, scale=0.8) wpause(self) self.play(Write(lines[0], run_time=5.0, lag_ratio=1.2)) wpause(self) l0copy = lines[0].copy() self.play(l0copy.animate.align_to(lines[1], UP), run_time=1.0) self.play( TransformMatchingTex( l0copy, lines[1], path_arc = 90*DEGREES, transform_mismatches = True ), run_time=2.0 ) wpause(self) self.play( TransformMatchingTex( lines[1].copy(), lines[2], key_map={ "C^2": "C", "B^2": "B", } ), **play_kw ) wpause(self) new_line2 = MathTex("A^2 = (C + B)(C - B)", substrings_to_isolate=["A", *to_isolate]) new_line2.replace(lines[2]) new_line2.match_style(lines[2]) self.play( TransformMatchingTex( new_line2, lines[3], transform_mismatches=True, ), **play_kw ) wpause(self) self.play(FadeOut(tlines, scale=0.8), run_time=0.2) wpause(self) texcode = r''' to_isolate = ["B", "C", "=", "(", ")"] lines = VGroup( MathTex("A^2", "+", "B^2", "=", "C^2"), MathTex("A^2", "=", "C^2", "-", "B^2"), MathTex("A^2 = (C + B)(C - B)", substrings_to_isolate=["A^2", *to_isolate]), MathTex("A = \\sqrt{(C + B)(C - B)}", substrings_to_isolate=["A", *to_isolate]) ) lines.arrange(DOWN, buff=1) for line in lines: line.set_color_by_tex_to_color_map({ "A": BLUE, "B": TEAL, "C": GREEN, }) self.play(Write(lines[0], run_time=5.0, lag_ratio=1.2)) wpause(self) l0copy = lines[0].copy() self.play(l0copy.animate.align_to(lines[1], UP), run_time=1.0) self.play( TransformMatchingTex( l0copy, lines[1], path_arc = 90*DEGREES, transform_mismatches = True ), run_time=2.0 ) ... ''' class TexTransformCode(Slide): def construct(self): rendered_code = Code(code=texcode, tab_width=4, background="window", language="Python", font="Monospace").scale(0.7) self.play(Create(rendered_code, run_time=18)) wpause(self) self.play(FadeOut(rendered_code, scale=0.8), run_time=1.0) wpause(self)