Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 62 additions & 80 deletions example_scenes.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,13 @@ def construct(self):
grid = NumberPlane((-10, 10), (-5, 5))
matrix = [[1, 1], [0, 1]]
linear_transform_words = VGroup(
Text("This is what the matrix"),
IntegerMatrix(matrix),
Text("looks like")
Text("This is what the matrix"), IntegerMatrix(matrix), Text("looks like")
)
linear_transform_words.arrange(RIGHT)
linear_transform_words.to_edge(UP)
linear_transform_words.set_backstroke(width=5)

self.play(
ShowCreation(grid),
FadeTransform(intro_words, linear_transform_words)
)
self.play(ShowCreation(grid), FadeTransform(intro_words, linear_transform_words))
self.wait()
self.play(grid.animate.apply_matrix(matrix), run_time=3)
self.wait()
Expand All @@ -48,8 +43,8 @@ def construct(self):
c_grid.set_stroke(BLUE_E, 1)
c_grid.add_coordinate_labels(font_size=24)
complex_map_words = TexText("""
Or thinking of the plane as $\\mathds{C}$,\\\\
this is the map $z \\rightarrow z^2$
Or thinking of the plane as $bb(C)$,\\\\
this is the map $z rightarrow z^2$
""")
complex_map_words.to_corner(UR)
complex_map_words.set_backstroke(width=5)
Expand All @@ -70,7 +65,7 @@ def construct(self):

class AnimatingMethods(Scene):
def construct(self):
grid = Tex(R"\pi").get_grid(10, 10, height=4)
grid = Tex("pi").get_grid(10, 10, height=4)
self.add(grid)

# You can animate the application of mobject methods with the
Expand Down Expand Up @@ -101,11 +96,7 @@ def construct(self):
# which takes in functions form R^3 to R^3
self.play(
grid.animate.apply_function(
lambda p: [
p[0] + 0.5 * math.sin(p[1]),
p[1] + 0.5 * math.sin(p[0]),
p[2]
]
lambda p: [p[0] + 0.5 * math.sin(p[1]), p[1] + 0.5 * math.sin(p[0]), p[2]]
),
run_time=5,
)
Expand All @@ -122,9 +113,10 @@ def construct(self):
The most important difference between Text and TexText is that\n
you can change the font more easily, but can't use the LaTeX grammar
""",
font="Arial", font_size=24,
font="Arial",
font_size=24,
# t2c is a dict that you can choose color for different text
t2c={"Text": BLUE, "TexText": BLUE, "LaTeX": ORANGE}
t2c={"Text": BLUE, "TexText": BLUE, "LaTeX": ORANGE},
)
VGroup(text, difference).arrange(DOWN, buff=1)
self.play(Write(text))
Expand All @@ -135,15 +127,15 @@ def construct(self):
"And you can also set the font according to different words",
font="Arial",
t2f={"font": "Consolas", "words": "Consolas"},
t2c={"font": BLUE, "words": GREEN}
t2c={"font": BLUE, "words": GREEN},
)
fonts.set_width(FRAME_WIDTH - 1)
slant = Text(
"And the same as slant and weight",
font="Consolas",
t2s={"slant": ITALIC},
t2w={"weight": BOLD},
t2c={"slant": ORANGE, "weight": RED}
t2c={"slant": ORANGE, "weight": RED},
)
VGroup(fonts, slant).arrange(DOWN, buff=0.8)
self.play(FadeOut(text), FadeOut(difference, shift=DOWN))
Expand All @@ -167,7 +159,7 @@ def construct(self):
Tex("A^2 + B^2 = C^2", **kw),
Tex("A^2 = C^2 - B^2", **kw),
Tex("A^2 = (C + B)(C - B)", **kw),
Tex(R"A = \sqrt{(C + B)(C - B)}", **kw),
Tex(R"A = sqrt((C + B)(C - B))", **kw),
)
lines.arrange(DOWN, buff=LARGE_BUFF)

Expand All @@ -179,7 +171,8 @@ def construct(self):
# rearranging an equation
self.play(
TransformMatchingStrings(
lines[0].copy(), lines[1],
lines[0].copy(),
lines[1],
# matched_keys specifies which substring should
# line up. If it's not specified, the animation
# will align the longest matching substrings.
Expand All @@ -194,17 +187,12 @@ def construct(self):
),
)
self.wait()
self.play(TransformMatchingStrings(
lines[1].copy(), lines[2],
matched_keys=["A^2"]
))
self.play(TransformMatchingStrings(lines[1].copy(), lines[2], matched_keys=["A^2"]))
self.wait()
self.play(
TransformMatchingStrings(
lines[2].copy(), lines[3],
key_map={"2": R"\sqrt"},
path_arc=-30 * DEG,
),
lines[2].copy(), lines[3], key_map={"2": "sqrt"}, path_arc=-30 * DEG
)
)
self.wait(2)
self.play(LaggedStartMap(FadeOut, lines, shift=2 * RIGHT))
Expand All @@ -228,19 +216,21 @@ def construct(self):
class TexIndexing(Scene):
def construct(self):
# You can index into Tex mobject (or other StringMobjects) by substrings
equation = Tex(R"e^{\pi i} = -1", font_size=144)
equation = Tex("e^(pi i) = -1", font_size=144)

self.add(equation)
self.play(FlashAround(equation["e"]))
self.wait()
self.play(Indicate(equation[R"\pi"]))
self.play(Indicate(equation["pi"]))
self.wait()
self.play(TransformFromCopy(
equation[R"e^{\pi i}"].copy().set_opacity(0.5),
equation["-1"],
path_arc=-PI / 2,
run_time=3
))
self.play(
TransformFromCopy(
equation["e^(pi i)"].copy().set_opacity(0.5),
equation["-1"],
path_arc=-PI / 2,
run_time=3,
)
)
self.play(FadeOut(equation))

# Or regular expressions
Expand All @@ -251,29 +241,29 @@ def construct(self):
self.play(FlashAround(part))
self.wait()
self.play(FadeOut(equation))

# Indexing by substrings like this may not work when
# the order in which Latex draws symbols does not match
# the order in which they show up in the string.
# For example, here the infinity is drawn before the sigma
# so we don't get the desired behavior.
equation = Tex(R"\sum_{n = 1}^\infty \frac{1}{n^2} = \frac{\pi^2}{6}", font_size=72)
equation = Tex("sum^infinity_{n = 1} 1 / n^2 = pi^2 / 6", font_size=72)
self.play(FadeIn(equation))
self.play(equation[R"\infty"].animate.set_color(RED)) # Doesn't hit the infinity
self.play(equation["infinity"].animate.set_color(RED)) # Doesn't hit the infinity
self.wait()
self.play(FadeOut(equation))

# However you can always fix this by explicitly passing in
# a string you might want to isolate later. Also, using
# \over instead of \frac helps to avoid the issue for fractions
# frac(num, denom) instead of num / denom helps to avoid the issue for fractions
equation = Tex(
R"\sum_{n = 1}^\infty {1 \over n^2} = {\pi^2 \over 6}",
"sum^infinity_(n = 1) frac(1, n^2) = frac(pi^2, 6)",
# Explicitly mark "\infty" as a substring you might want to access
isolate=[R"\infty"],
font_size=72
isolate=["infinity"],
font_size=72,
)
self.play(FadeIn(equation))
self.play(equation[R"\infty"].animate.set_color(RED)) # Got it!
self.play(equation["infinity"].animate.set_color(RED)) # Got it!
self.wait()
self.play(FadeOut(equation))

Expand Down Expand Up @@ -320,10 +310,7 @@ def construct(self):
run_time=3,
)
self.wait()
self.play(
square.animate.set_width(2),
run_time=3
)
self.play(square.animate.set_width(2), run_time=3)
self.wait()

# In general, you can always call Mobject.add_updater, and pass in
Expand All @@ -332,9 +319,7 @@ def construct(self):
# the mobject and the amount of time since the last frame.
now = self.time
w0 = square.get_width()
square.add_updater(
lambda m: m.set_width(w0 * math.sin(self.time - now) + w0)
)
square.add_updater(lambda m: m.set_width(w0 * math.sin(self.time - now) + w0))
self.wait(4 * PI)


Expand All @@ -360,7 +345,7 @@ def construct(self):
# of them, like this.
y_axis_config=dict(
big_tick_numbers=[-2, 2],
)
),
)
# Keyword arguments of add_coordinate_labels can be used to
# configure the DecimalNumber mobjects which it creates and
Expand All @@ -375,7 +360,7 @@ def construct(self):
# you can call call axes.coords_to_point, abbreviated to
# axes.c2p, to associate a set of coordinates with a point,
# like so:
dot = Dot(fill_color=RED)
dot = Dot(color=RED)
dot.move_to(axes.c2p(0, 0))
self.play(FadeIn(dot, scale=0.5))
self.play(dot.animate.move_to(axes.c2p(3, 2)))
Expand Down Expand Up @@ -449,7 +434,7 @@ def construct(self):
# If it's a string, it treats it as a LaTeX expression. By default
# it places the label next to the graph near the right side, and
# has it match the color of the graph
sin_label = axes.get_graph_label(sin_graph, "\\sin(x)")
sin_label = axes.get_graph_label(sin_graph, "sin(x)")
relu_label = axes.get_graph_label(relu_graph, Text("ReLU"))
step_label = axes.get_graph_label(step_graph, Text("Step"), x=4)

Expand All @@ -471,16 +456,12 @@ def construct(self):

parabola = axes.get_graph(lambda x: 0.25 * x**2)
parabola.set_stroke(BLUE)
self.play(
FadeOut(step_graph),
FadeOut(step_label),
ShowCreation(parabola)
)
self.play(FadeOut(step_graph), FadeOut(step_label), ShowCreation(parabola))
self.wait()

# You can use axes.input_to_graph_point, abbreviated
# to axes.i2gp, to find a particular point on a graph
dot = Dot(fill_color=RED)
dot = Dot(color=RED)
dot.move_to(axes.i2gp(2, parabola))
self.play(FadeIn(dot, scale=0.5))

Expand Down Expand Up @@ -514,16 +495,18 @@ def construct(self):
tex.next_to(axes, UP, buff=0.5)
value = tex.make_number_changeable("4.00")


# This will tie the right hand side of our equation to
# the square of the radius of the circle
value.add_updater(lambda v: v.set_value(circle.get_radius()**2))
value.add_updater(lambda v: v.set_value(circle.get_radius() ** 2))
self.add(tex)

text = Text("""
text = Text(
"""
You can manipulate numbers
in Tex mobjects
""", font_size=30)
""",
font_size=30,
)
text.next_to(tex, RIGHT, buff=1.5)
arrow = Arrow(text, tex)
self.add(text, arrow)
Expand All @@ -539,11 +522,8 @@ def construct(self):
# returns a group of the results
exponents = tex.make_number_changeable("2", replace_all=True)
self.play(
LaggedStartMap(
FlashAround, exponents,
lag_ratio=0.2, buff=0.1, color=RED
),
exponents.animate.set_color(RED)
LaggedStartMap(FlashAround, exponents, lag_ratio=0.2, buff=0.1, color=RED),
exponents.animate.set_color(RED),
)

def func(x, y):
Expand Down Expand Up @@ -608,17 +588,14 @@ def construct(self):
for mob in surfaces[1:]:
mob.rotate(PI / 2)

self.play(
Transform(surface, surfaces[1]),
run_time=3
)
self.play(Transform(surface, surfaces[1]), run_time=3)

self.play(
Transform(surface, surfaces[2]),
# Move camera frame during the transition
self.frame.animate.increment_phi(-10 * DEG),
self.frame.animate.increment_theta(-20 * DEG),
run_time=3
run_time=3,
)
# Add ambient rotation
self.frame.add_updater(lambda m, dt: m.increment_theta(-0.1 * dt))
Expand Down Expand Up @@ -699,24 +676,29 @@ def setup(self):
self.checkbox = Checkbox()
self.color_picker = ColorSliders()
self.panel = ControlPanel(
Text("Text", font_size=24), self.textbox, Line(),
Text("Show/Hide Text", font_size=24), self.checkbox, Line(),
Text("Color of Text", font_size=24), self.color_picker
Text("Text", font_size=24),
self.textbox,
Line(),
Text("Show/Hide Text", font_size=24),
self.checkbox,
Line(),
Text("Color of Text", font_size=24),
self.color_picker,
)
self.add(self.panel)

def construct(self):
text = Text("text", font_size=96)

def text_updater(old_text):
assert(isinstance(old_text, Text))
assert isinstance(old_text, Text)
new_text = Text(self.textbox.get_value(), font_size=old_text.font_size)
# new_text.align_data_and_family(old_text)
new_text.move_to(old_text)
if self.checkbox.get_value():
new_text.set_fill(
color=self.color_picker.get_picked_color(),
opacity=self.color_picker.get_picked_opacity()
opacity=self.color_picker.get_picked_opacity(),
)
else:
new_text.set_opacity(0)
Expand Down
2 changes: 2 additions & 0 deletions manimlib/default_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ tex:
template: "default"
# The font size at which Tex("0") has a height of 1 manim unit
font_size_for_unit_height: 144
text_font: ""
math_font: ""
text:
# font: "Cambria Math"
font: "Consolas"
Expand Down
5 changes: 2 additions & 3 deletions manimlib/mobject/coordinate_systems.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,9 @@ def get_axis_label(
edge: Vect3,
direction: Vect3,
buff: float = MED_SMALL_BUFF,
ensure_on_screen: bool = False,
**kwargs
ensure_on_screen: bool = False
) -> Tex:
label = Tex(label_tex, **kwargs)
label = Tex(label_tex)
label.next_to(
axis.get_edge_center(edge), direction,
buff=buff
Expand Down
Loading