Initial bayes_footnote animations

This commit is contained in:
Grant Sanderson
2017-06-12 12:58:56 -07:00
parent e9032a88df
commit e2c32af05d
2 changed files with 348 additions and 9 deletions

342
eop/bayes_footnote.py Normal file
View File

@ -0,0 +1,342 @@
from helpers import *
from mobject.tex_mobject import TexMobject
from mobject import Mobject
from mobject.image_mobject import ImageMobject
from mobject.vectorized_mobject import *
from animation.animation import Animation
from animation.transform import *
from animation.simple_animations import *
from animation.playground import *
from topics.geometry import *
from topics.characters import *
from topics.functions import *
from topics.fractals import *
from topics.number_line import *
from topics.combinatorics import *
from topics.numerals import *
from topics.three_dimensions import *
from topics.objects import *
from topics.complex_numbers import *
from topics.common_scenes import *
from topics.probability import *
from scene import Scene
from scene.reconfigurable_scene import ReconfigurableScene
from scene.zoomed_scene import *
from camera import Camera
from mobject.svg_mobject import *
from mobject.tex_mobject import *
from eop.bayes import IntroducePokerHand
SICKLY_GREEN = "#9BBD37"
class Introduction(TeacherStudentsScene):
def construct(self):
self.hold_up_example()
self.write_counter_intuitive()
self.put_it_first()
self.swap_example_order()
self.other_culprit()
def hold_up_example(self):
everyone = self.get_pi_creatures()
self.teacher.change_mode("raise_right_hand")
rect = ScreenRectangle()
rect.set_stroke(YELLOW, 2)
rect.to_edge(UP)
randy = Randolph()
randy.scale(0.7)
name = TextMobject(r"""
Bayes' theorem \\
disease example
""")
name.next_to(rect.get_top(), DOWN, SMALL_BUFF)
randy.next_to(name, DOWN)
example = VGroup(rect, name, randy)
self.remove(everyone)
self.add(name, randy)
self.play(
randy.change_mode, "sick",
randy.highlight, SICKLY_GREEN
)
self.play(ShowCreation(rect))
self.play(
FadeIn(everyone),
example.scale, 0.5,
example.next_to, self.teacher.get_corner(UP+LEFT), UP,
)
self.dither(2)
self.example = example
def write_counter_intuitive(self):
bayes = TextMobject("Bayes")
arrow = TexMobject("\\leftrightarrow")
intuition = TextMobject("Intuition")
group = VGroup(bayes, arrow, intuition)
group.arrange_submobjects(RIGHT, buff = SMALL_BUFF)
group.scale(0.8)
group.next_to(self.example, UP, buff = SMALL_BUFF)
group.shift_onto_screen()
cross = VGroup(
Line(UP+LEFT, DOWN+RIGHT),
Line(UP+RIGHT, DOWN+LEFT),
)
cross.replace(arrow, stretch = True)
cross.set_stroke(RED, 6)
group.add(cross)
self.play(*map(FadeIn, [bayes, intuition]))
self.play(Write(arrow))
self.play(ShowCreation(cross))
self.change_student_modes(*["confused"]*3)
self.dither(2)
self.bayes_to_intuition = group
def put_it_first(self):
poker_example = self.get_poker_example()
music_example = self.get_music_example()
disease_group = VGroup(
self.example, self.bayes_to_intuition
)
self.play(disease_group.to_edge, LEFT)
self.change_student_modes(
*["pondering"]*3,
look_at_arg = disease_group
)
poker_example.next_to(self.example, RIGHT)
music_example.next_to(poker_example, RIGHT)
examples = VGroup(poker_example, music_example)
brace = Brace(examples, UP)
bayes_to_intuition = VGroup(*map(TextMobject, [
"Bayes", "$\\leftrightarrow$", "Intuition"
]))
bayes_to_intuition.arrange_submobjects(RIGHT, buff = SMALL_BUFF)
bayes_to_intuition.next_to(brace, UP, SMALL_BUFF)
check = TexMobject("\\checkmark")
check.highlight(GREEN)
check.next_to(bayes_to_intuition[1], UP, SMALL_BUFF)
for example in examples:
self.play(FadeIn(example))
self.dither()
self.play(GrowFromCenter(brace))
self.play(FadeIn(bayes_to_intuition))
self.play(Write(check))
self.dither(2)
self.intuitive_examples = VGroup(
examples, brace, bayes_to_intuition, check
)
def swap_example_order(self):
intuitive_examples = self.intuitive_examples
disease_group = VGroup(
self.example, self.bayes_to_intuition
)
self.play(
disease_group.next_to,
self.teacher.get_corner(UP+LEFT), UP,
disease_group.shift, LEFT,
intuitive_examples.scale, 0.7,
intuitive_examples.to_corner, UP+LEFT,
self.teacher.change_mode, "sassy"
)
def other_culprit(self):
bayes = self.bayes_to_intuition[0]
something_else = TextMobject("Something else")
something_else.highlight(YELLOW)
something_else.scale_to_fit_height(bayes.get_height())
something_else.move_to(bayes, RIGHT)
new_group = VGroup(
something_else,
*self.bayes_to_intuition[1:]
)
self.play(bayes.to_edge, UP)
self.play(Write(something_else))
self.play(new_group.next_to, self.example, UP, SMALL_BUFF)
self.change_student_modes(
"erm", "confused", "hesitant",
added_anims = [self.teacher.change_mode, "happy"]
)
self.dither(3)
#####
def get_poker_example(self):
rect = self.get_example_rect()
values = IntroducePokerHand.CONFIG["community_card_values"]
community_cards = VGroup(*map(PlayingCard, values))
community_cards.arrange_submobjects(RIGHT)
deck = VGroup(*[
PlayingCard(turned_over = True)
for x in range(5)
])
for i, card in enumerate(deck):
card.shift(i*(0.03*RIGHT + 0.015*DOWN))
deck.next_to(community_cards, LEFT)
cards = VGroup(deck, community_cards)
cards.scale_to_fit_width(rect.get_width() - 2*SMALL_BUFF)
cards.next_to(rect.get_bottom(), UP, MED_SMALL_BUFF)
probability = TexMobject(
"P(", "\\text{Flush}", "|", "\\text{High bet}", ")"
)
probability.highlight_by_tex("Flush", RED)
probability.highlight_by_tex("High bet", GREEN)
probability.scale(0.5)
probability.next_to(rect.get_top(), DOWN)
return VGroup(rect, probability, cards)
def get_music_example(self):
rect = self.get_example_rect()
musician = Randolph(mode = "soulful_musician")
musician.left_arm_range = [.36, .45]
musician.arms = musician.get_arm_copies()
guitar = musician.guitar = Guitar()
guitar.move_to(musician)
guitar.shift(0.31*RIGHT + 0.6*UP)
musician.add(guitar, musician.arms)
musician.scale_to_fit_height(0.7*rect.get_height())
musician.next_to(rect.get_bottom(), UP, SMALL_BUFF)
probability = TexMobject(
"P(", "\\text{Suck }", "|", "\\text{ Good review}", ")"
)
probability.highlight_by_tex("Suck", RED)
probability.highlight_by_tex("Good", GREEN)
probability.scale(0.5)
probability.next_to(rect.get_top(), DOWN)
return VGroup(rect, musician, probability)
def get_example_rect(self):
rect = self.example[0].copy()
rect.highlight(WHITE)
return rect
class OneInOneThousandHaveDisease(Scene):
def construct(self):
title = TextMobject("1 in 1{,}000")
title.to_edge(UP)
creature = PiCreature()
all_creatures = VGroup(*[
VGroup(*[
creature.copy()
for y in range(25)
]).arrange_submobjects(DOWN, SMALL_BUFF)
for x in range(40)
]).arrange_submobjects(RIGHT, SMALL_BUFF)
all_creatures.scale_to_fit_width(2*SPACE_WIDTH - 4)
all_creatures.next_to(title, DOWN)
randy = all_creatures[0][0]
all_creatures[0].remove(randy)
randy.change_mode("sick")
randy.highlight(SICKLY_GREEN)
randy.save_state()
randy.scale_to_fit_height(3)
randy.center()
randy.change_mode("plain")
randy.highlight(BLUE)
self.add(randy)
self.play(
randy.change_mode, "sick",
randy.highlight, SICKLY_GREEN
)
self.play(Blink(randy))
self.play(randy.restore)
self.play(
Write(title),
LaggedStart(FadeIn, all_creatures, run_time = 3)
)
self.dither()
class TestScene(Scene):
def get_result(self, creature, word, color):
arrow = self.get_test_arrow()
test_result = TextMobject(word)
test_result.highlight(color)
test_result.next_to(arrow.get_end(), RIGHT)
group = VGroup(arrow, test_result)
group.next_to(creature, RIGHT, aligned_edge = UP)
return group
def get_positive_result(self, creature):
return self.get_result(creature, "Diseased", SICKLY_GREEN)
def get_negative_result(self, creature):
return self.get_result(creature, "Healthy", GREEN)
def get_test_arrow(self):
arrow = Arrow(
LEFT, RIGHT,
color = WHITE,
)
word = TextMobject("Test")
word.scale(0.8)
word.next_to(arrow, UP, buff = 0)
arrow.add(word)
return arrow
class TestDiseaseCase(TestScene):
def construct(self):
randy = Randolph(
mode = "sick",
color = SICKLY_GREEN
)
randy.next_to(ORIGIN, LEFT)
result = self.get_positive_result(randy)
accuracy = TextMobject("100\\% Accuracy")
accuracy.next_to(VGroup(randy, result), UP, LARGE_BUFF)
self.add(randy)
self.play(FadeIn(result[0]))
self.play(Write(result[1]))
self.play(FadeIn(accuracy))
self.dither()
class TestNonDiseaseCase(TestScene):
def construct(self):
pass
class ReceivePositiveResults(TestScene):
def construct(self):
pass
class RephraseQuestion(Scene):
def construct(self):
pass

View File

@ -37,7 +37,6 @@ class TexMobject(SVGMobject):
"fill_color" : WHITE,
"should_center" : True,
"arg_separator" : " ",
"enforce_new_line_structure" : False,
"initial_scale_factor" : TEX_MOB_SCALE_FACTOR,
"organize_left_to_right" : False,
"propogate_style_to_family" : True,
@ -59,7 +58,6 @@ class TexMobject(SVGMobject):
if self.organize_left_to_right:
self.organize_submobjects_left_to_right()
def path_string_to_mobject(self, path_string):
#Overwrite superclass default to use
#specialized path_string mobject
@ -72,8 +70,6 @@ class TexMobject(SVGMobject):
def get_modified_expression(self):
result = self.arg_separator.join(self.args)
if self.enforce_new_line_structure:
result = result.replace("\n", " \\\\ \n ")
result = " ".join([self.alignment, result])
result = result.strip()
result = self.modify_special_strings(result)
@ -86,7 +82,12 @@ class TexMobject(SVGMobject):
#fraction line needs something to be over
tex += "\\,"
for t1, t2 in ("\\left", "\\right"), ("\\right", "\\left"):
if t1 in tex and t2 not in tex:
should_replace = reduce(op.and_, [
t1 in tex,
t2 not in tex,
len(tex) > len(t1) and tex[len(t1)] in "()[]\\"
])
if should_replace:
tex = tex.replace(t1, "\\big")
return tex
@ -185,7 +186,6 @@ class TextMobject(TexMobject):
CONFIG = {
"template_tex_file" : TEMPLATE_TEXT_FILE,
"initial_scale_factor" : TEXT_MOB_SCALE_FACTOR,
"enforce_new_line_structure" : True,
"alignment" : "\\centering",
}
@ -269,7 +269,6 @@ def tex_to_svg_file(expression, template_tex_file):
dvi_file = tex_to_dvi(tex_file)
return dvi_to_svg(dvi_file)
def generate_tex_file(expression, template_tex_file):
result = os.path.join(
TEX_DIR,
@ -304,8 +303,6 @@ def tex_to_dvi(tex_file):
if os.path.exists(log_file):
with open(log_file, 'r') as f:
latex_output = f.read()
if latex_output:
sys.stderr.write(latex_output)
raise Exception(
"Latex error converting to dvi. "
"See log output above or the log file: %s" % log_file)