diff --git a/active_projects/eop/chapter1/all_sequences.py b/active_projects/eop/chapter1/all_sequences.py index 3a9d7e70..6e90e674 100644 --- a/active_projects/eop/chapter1/all_sequences.py +++ b/active_projects/eop/chapter1/all_sequences.py @@ -3,7 +3,7 @@ from active_projects.eop.reusable_imports import * class ShuffleThroughAllSequences(Scene): CONFIG = { - "nb_coins" : 14, + "nb_coins" : 20, "run_time" : 5, "fps" : int(1.0/PRODUCTION_QUALITY_FRAME_DURATION), "coin_size" : 0.5, @@ -31,7 +31,8 @@ class ShuffleThroughAllSequences(Scene): radius = self.coin_size * 0.5, spacing = self.coin_spacing) - self.add(idle_part, left_idle_part) + #self.add(idle_part, left_idle_part) + self.add(left_idle_part) last_coin_seq = VGroup() for i in range(2**nb_relevant_coins): @@ -46,7 +47,7 @@ class ShuffleThroughAllSequences(Scene): spacing = self.coin_spacing) coin_seq.next_to(idle_part, LEFT, buff = self.coin_spacing - self.coin_size) left_idle_part.next_to(coin_seq, LEFT, buff = self.coin_spacing - self.coin_size) - all_coins = VGroup(left_idle_part, coin_seq, idle_part) + all_coins = VGroup(left_idle_part, coin_seq) #, idle_part) all_coins.center() self.remove(last_coin_seq) self.add(coin_seq) diff --git a/active_projects/eop/chapter1/area_model_bayes.py b/active_projects/eop/chapter1/area_model_bayes.py index 1dae8d35..fe6a284d 100644 --- a/active_projects/eop/chapter1/area_model_bayes.py +++ b/active_projects/eop/chapter1/area_model_bayes.py @@ -203,7 +203,7 @@ class IllustrateAreaModelBayes(Scene): # solve formula for P(B|A) - rearranged_formula = TexMobject(["P(B\mid A)", "=", "{P(A\\text{ and }B) \over P(A)}"]) + rearranged_formula = TexMobject("P(B\mid A)", "=", "{P(A\\text{ and }B) \over P(A)}") rearranged_formula.move_to(indep_formula) self.wait() diff --git a/active_projects/eop/chapter1/brick_row_scene.py b/active_projects/eop/chapter1/brick_row_scene.py index b11a66ca..521d2b05 100644 --- a/active_projects/eop/chapter1/brick_row_scene.py +++ b/active_projects/eop/chapter1/brick_row_scene.py @@ -152,7 +152,7 @@ class BrickRowScene(PiCreatureScene): def merge_tallies(self, row, target_pos = UP): - + r = row.subdiv_level if np.all(target_pos == DOWN): @@ -218,7 +218,8 @@ class BrickRowScene(PiCreatureScene): def construct(self): - + self.force_skipping() + randy = self.get_primary_pi_creature() randy = randy.scale(0.5).move_to(3*DOWN + 6*LEFT) #self.add(randy) @@ -312,31 +313,57 @@ class BrickRowScene(PiCreatureScene): new_tails[i].shift(COIN_SEQUENCE_SPACING * DOWN) self.play(FadeIn(new_tails)) - decimal_tallies = VGroup() - # introduce notion of tallies - for (i, rect) in enumerate(self.row.get_rects_for_level(2)): - tally = DecimalTally(2-i, i) - tally.next_to(rect, UP) - decimal_tallies.add(tally) - self.play(FadeIn(tally)) - self.wait() - self.add_foreground_mobject(single_flip_labels) self.add_foreground_mobject(new_heads) self.add_foreground_mobject(single_flip_labels_copy) self.add_foreground_mobject(new_tails) - # show individual outcomes - outcomes = self.row.get_outcome_rects_for_level(2, with_labels = False) + # get individual outcomes + outcomes = self.row.get_outcome_rects_for_level(2, with_labels = False, + inset = True) + grouped_outcomes = VGroup(outcomes[0], outcomes[1:3], outcomes[3]) + decimal_tallies = VGroup() + # introduce notion of tallies + rects = self.row.get_rects_for_level(2) + rect = rects[0] + tally = DecimalTally(2,0) + tally.next_to(rect, UP) + decimal_tallies.add(tally) self.play( - LaggedStart(FadeIn, outcomes) + FadeIn(tally), + FadeIn(grouped_outcomes[0]) ) self.wait() + + rect = rects[1] + tally = DecimalTally(1,1) + tally.next_to(rect, UP) + decimal_tallies.add(tally) self.play( - LaggedStart(FadeOut, outcomes), + FadeIn(tally), + FadeOut(grouped_outcomes[0]), + FadeIn(grouped_outcomes[1]) ) + self.wait() + + rect = rects[2] + tally = DecimalTally(0,2) + tally.next_to(rect, UP) + decimal_tallies.add(tally) + self.play( + FadeIn(tally), + FadeOut(grouped_outcomes[1]), + FadeIn(grouped_outcomes[2]) + ) + self.wait() + + self.play( + FadeOut(grouped_outcomes[2]) + ) + self.wait() + self.wait() self.play( FadeOut(single_flip_labels), @@ -346,7 +373,6 @@ class BrickRowScene(PiCreatureScene): ) self.wait() - self.tallies = VGroup() for (i, rect) in enumerate(self.row.get_rects_for_level(2)): tally = TallyStack(2-i, i, show_decimals = False) @@ -386,7 +412,8 @@ class BrickRowScene(PiCreatureScene): # CALLBACK TO SEQUENCES # # # # # # # # # # # # # # - outcomes = self.row.get_outcome_rects_for_level(2, with_labels = True) + outcomes = self.row.get_outcome_rects_for_level(2, with_labels = True, + inset = True) subdivs = self.row.get_sequence_subdivs_for_level(2) self.play( FadeIn(outcomes), @@ -396,7 +423,8 @@ class BrickRowScene(PiCreatureScene): self.wait() - rect_to_dice = outcomes[1] + rect_to_dice = self.row.get_outcome_rects_for_level(2, with_labels = False, + inset = False)[1] N = 10 dice_width = rect_to_dice.get_width()/N dice_height = rect_to_dice.get_height()/N @@ -419,9 +447,8 @@ class BrickRowScene(PiCreatureScene): self.play( LaggedStart(FadeIn, all_dice), - FadeOut(rect_to_dice.label) + FadeOut(outcomes[1]) ) - self.wait() table = Ellipse(width = 1.5, height = 1) @@ -455,7 +482,6 @@ class BrickRowScene(PiCreatureScene): run_time = 0.05) ) - self.wait() self.play( @@ -513,14 +539,17 @@ class BrickRowScene(PiCreatureScene): self.clear() self.add(randy, self.row, old_row) self.add_foreground_mobject(self.tallies) + self.add_foreground_mobject(self.tallies_copy) self.play( self.row.fade, 0.7, old_row.fade, 0.7, FadeOut(self.tallies), + FadeOut(self.tallies_copy), ) + # # # # # # # # # # # # # # # # # # SHOW SPLITTING WITH OUTCOMES # # # # # # # # # # # # # # # # # # @@ -685,36 +714,35 @@ class BrickRowScene(PiCreatureScene): #rate_func = there_and_back_with_pause, run_time = 5)) self.wait() + + braces = VGroup(*[Brace(rect, UP) for rect in self.row.rects]) + counts = [choose(3, i) for i in range(4)] + probs = VGroup(*[TexMobject("{" + str(k) + "\over 8}") for k in counts]) + for (brace, prob) in zip(braces, probs): + prob.next_to(brace, UP) + + + self.play( + LaggedStart(ShowCreation, braces), + LaggedStart(Write, probs) + ) + self.wait() self.play(LaggedStart( FadeOut, outcomes, #rate_func = there_and_back_with_pause, - run_time = 5)) - - self.wait() - self.play(FadeIn(self.tallies)) - - brace1 = Brace(self.row.rects[2], UP) - brace2 = Brace(self.row.rects[3], UP) - p1 = TexMobject("{3\over 8}").next_to(brace1, UP) - p2 = TexMobject("{1\over 8}").next_to(brace2, UP) - + run_time = 5), + ) self.play( - ShowCreation(brace1), - ShowCreation(brace2), - Write(p1), - Write(p2), + FadeIn(self.tallies) ) self.wait() self.play( - FadeOut(brace1), - FadeOut(brace2), - FadeOut(p1), - FadeOut(p2), + FadeOut(braces), + FadeOut(probs) ) self.wait() - - + # put visuals for other probability distribtuions here @@ -762,6 +790,9 @@ class BrickRowScene(PiCreatureScene): self.wait() self.row = self.merge_rects_by_subdiv(self.row) + + + self.revert_to_original_skipping_status() self.wait() @@ -805,23 +836,16 @@ class BrickRowScene(PiCreatureScene): index = 0 old_tally_sizes = [choose(n,i) for i in range(n + 1)] new_tally_sizes = [choose(n + 1,i) for i in range(n + 2)] + for i in range(n + 2): size = new_tally_sizes[i] grouped_target_outcomes.add(VGroup(target_outcomes[index:index + size])) index += size - self.play( - Transform(grouped_outcomes[k][0],grouped_target_outcomes[k][0][old_tally_sizes[k - 1]:]) - ) - - self.play( - Transform(grouped_outcomes_copy[k][0],grouped_target_outcomes[k + 1][0][:old_tally_sizes[k]]) - ) - old_tally_sizes.append(0) # makes the edge cases work properly - - # split the other tallies - for i in range(k) + range(k + 1, n + 1): + + # split all tallies + for i in range(n + 1): self.play( Transform(grouped_outcomes[i][0], grouped_target_outcomes[i][0][old_tally_sizes[i - 1]:] @@ -830,7 +854,7 @@ class BrickRowScene(PiCreatureScene): grouped_target_outcomes[i + 1][0][:old_tally_sizes[i]] ) ) - + return self.wait() @@ -894,6 +918,7 @@ class BrickRowScene(PiCreatureScene): self.play(FadeOut(new_tallies)) self.clear() + self.row = BrickRow(3) self.add(randy, self.row) @@ -923,6 +948,227 @@ class BrickRowScene(PiCreatureScene): +class ShowProbsInBrickRow3(BrickRowScene): + + def construct(self): + + randy = self.get_primary_pi_creature() + randy = randy.scale(0.5).move_to(3*DOWN + 6*LEFT) + #self.add(randy) + self.row = BrickRow(3, height = 2, width = 10) + self.wait() + + self.add(self.row) + + tallies = VGroup() + for (i, rect) in enumerate(self.row.get_rects_for_level(3)): + tally = TallyStack(3-i, i, show_decimals = False) + tally.move_to(rect) + tallies.add(tally) + + self.add(tallies) + self.wait(6) + + braces = VGroup(*[Brace(rect, UP) for rect in self.row.rects]) + counts = [choose(3, i) for i in range(4)] + probs = VGroup(*[TexMobject("{" + str(k) + "\over 8}") for k in counts]) + for (brace, prob) in zip(braces, probs): + prob.next_to(brace, UP) + + self.wait() + self.play( + LaggedStart(ShowCreation, braces, run_time = 3), + LaggedStart(Write, probs, run_time = 3) + ) + self.wait() + + self.play(FadeOut(braces),FadeOut(probs)) + + + + +class ShowOutcomesInBrickRow4(BrickRowScene): + + def construct(self): + + randy = self.get_primary_pi_creature() + randy = randy.scale(0.5).move_to(3*DOWN + 6*LEFT) + #self.add(randy) + self.row = BrickRow(3, height = 2, width = 10) + + previous_row = self.row.copy() + v = 1.25 * self.row.height * UP + self.play( + previous_row.shift, v, + ) + + self.add(self.row) + self.add(previous_row) + + + + + self.wait() + previous_outcomes = previous_row.get_outcome_rects_for_level(3, + with_labels = True, inset = True) + + previous_outcomes_copy = previous_outcomes.copy() + + + + self.play( + LaggedStart(FadeIn, previous_outcomes), + LaggedStart(FadeIn, previous_outcomes_copy), + ) + + self.wait() + + new_outcomes = self.row.get_outcome_rects_for_level(4, + with_labels = True, inset = True) + # remove each last coin + + + new_outcomes_left = VGroup( + new_outcomes[0], + new_outcomes[2], + new_outcomes[3], + new_outcomes[4], + new_outcomes[8], + new_outcomes[9], + new_outcomes[10], + new_outcomes[14] + ) + new_outcomes_right = VGroup( + new_outcomes[1], + new_outcomes[5], + new_outcomes[6], + new_outcomes[7], + new_outcomes[11], + new_outcomes[12], + new_outcomes[13], + new_outcomes[15] + ) + heads_labels = VGroup(*[outcome.label[-1] for outcome in new_outcomes_left]) + tails_labels = VGroup(*[outcome.label[-1] for outcome in new_outcomes_right]) + heads_labels.save_state() + tails_labels.save_state() + for outcome in new_outcomes: + outcome.label[-1].fade(1) + + run_time = 0.5 + self.play(Transform(previous_outcomes[0], new_outcomes_left[0], run_time = run_time)) + self.play(Transform(previous_outcomes[1:4], new_outcomes_left[1:4], run_time = run_time)) + self.play(Transform(previous_outcomes[4:7], new_outcomes_left[4:7], run_time = run_time)) + self.play(Transform(previous_outcomes[7], new_outcomes_left[7], run_time = run_time)) + + + self.play(heads_labels.restore) + + + self.play(Transform(previous_outcomes_copy[0], new_outcomes_right[0], run_time = run_time)) + self.play(Transform(previous_outcomes_copy[1:4], new_outcomes_right[1:4], run_time = run_time)) + self.play(Transform(previous_outcomes_copy[4:7], new_outcomes_right[4:7], run_time = run_time)) + self.play(Transform(previous_outcomes_copy[7], new_outcomes_right[7], run_time = run_time)) + + + self.play(tails_labels.restore) + + + self.wait() + + anims = [FadeOut(previous_outcomes),FadeOut(previous_outcomes_copy)] + + for outcome in new_outcomes_left: + anims.append(FadeOut(outcome.label[-1])) + for outcome in new_outcomes_right: + anims.append(FadeOut(outcome.label[-1])) + + self.play(*anims) + + self.wait() + + + + + +class SplitTalliesIntoBrickRow4(BrickRowScene): + + def construct(self): + + randy = self.get_primary_pi_creature() + randy = randy.scale(0.5).move_to(3*DOWN + 6*LEFT) + #self.add(randy) + self.row = BrickRow(3, height = 2, width = 10) + + previous_row = self.row.copy() + v = 1.25 * self.row.height * UP + self.play( + previous_row.shift, v, + ) + + tallies = VGroup() + for (i, rect) in enumerate(previous_row.get_rects_for_level(3)): + tally = TallyStack(3-i, i, show_decimals = True) + tally.move_to(rect) + tallies.add(tally) + + moving_tallies_left = tallies.copy() + moving_tallies_right = tallies.copy() + + self.add(self.row, previous_row) + self.add_foreground_mobject(tallies) + self.add_foreground_mobject(moving_tallies_left) + self.add_foreground_mobject(moving_tallies_right) + + + self.play(SplitRectsInBrickWall(self.row)) + + anims = [] + for (tally, rect) in zip(moving_tallies_left, previous_row.rects): + anims.append(tally.move_to) + anims.append(rect.get_center() + rect.get_width() * 0.25 * LEFT) + + self.play(*anims) + + new_tallies_left = VGroup() + for (i, tally) in enumerate(moving_tallies_left): + new_tally = TallyStack(4-i,i, with_labels = True) + new_tally.move_to(tally) + new_tallies_left.add(new_tally) + + self.play(Transform(moving_tallies_left, new_tallies_left)) + + anims = [] + for (tally, rect) in zip(moving_tallies_right, previous_row.rects): + anims.append(tally.move_to) + anims.append(rect.get_center() + rect.get_width() * 0.25 * RIGHT) + + self.play(*anims) + + new_tallies_right = VGroup() + for (i, tally) in enumerate(moving_tallies_right): + new_tally = TallyStack(3-i,i+1, with_labels = True) + new_tally.move_to(tally) + new_tallies_right.add(new_tally) + + self.play(Transform(moving_tallies_right, new_tallies_right)) + + + hypothetical_new_row = BrickRow(4, height = 2, width = 10) + anims = [] + for (tally, rect) in zip(moving_tallies_left[1:], hypothetical_new_row.rects[1:-1]): + anims.append(tally.move_to) + anims.append(rect) + for (tally, rect) in zip(moving_tallies_right[:-1], hypothetical_new_row.rects[1:-1]): + anims.append(tally.move_to) + anims.append(rect) + self.play(*anims) + self.wait() + self.row = self.merge_rects_by_subdiv(self.row) + self.wait() + self.row = self.merge_rects_by_coloring(self.row) + self.wait() + diff --git a/active_projects/eop/chapter1/entire_brick_wall.py b/active_projects/eop/chapter1/entire_brick_wall.py index 90c52e29..033cfbae 100644 --- a/active_projects/eop/chapter1/entire_brick_wall.py +++ b/active_projects/eop/chapter1/entire_brick_wall.py @@ -3,7 +3,12 @@ from big_ol_pile_of_manim_imports import * from active_projects.eop.reusable_imports import * from active_projects.eop.chapter1.brick_row_scene import BrickRowScene -class EntireBrickWall(BrickRowScene): +class EntireBrickWall(BrickRowScene, MovingCameraScene): + + def setup(self): + super(BrickRowScene, self).setup() + super(PiCreatureScene, self).setup() + def construct(self): @@ -45,7 +50,6 @@ class EntireBrickWall(BrickRowScene): rows.submobjects[-1] = self.merge_rects_by_coloring(rows[-1]) - # draw indices under the last row for the number of tails tails_counters = VGroup() for (i, rect) in enumerate(rows[-1].rects): @@ -83,6 +87,7 @@ class EntireBrickWall(BrickRowScene): last_row_rect = SurroundingRectangle(rows[-1], buff = 0) last_row_rect.set_stroke(color = YELLOW, width = 6) + rows.save_state() self.play( rows.fade, 0.9, ShowCreation(last_row_rect) @@ -102,24 +107,40 @@ class EntireBrickWall(BrickRowScene): highlighted_brick(row = 20, nb_tails = i) for i in range(20) ] - + self.wait() self.play( FadeIn(highlighted_bricks[10]) ) - + self.wait() self.play( FadeOut(highlighted_bricks[10]), FadeIn(highlighted_bricks[9]), FadeIn(highlighted_bricks[11]), ) - + self.wait() self.play( FadeOut(highlighted_bricks[9]), FadeOut(highlighted_bricks[11]), FadeIn(highlighted_bricks[8]), FadeIn(highlighted_bricks[12]), ) - + self.wait() + self.play( + FadeOut(highlighted_bricks[8]), + FadeOut(highlighted_bricks[12]), + FadeOut(last_row_rect), + rows.restore, + ) + self.wait() + new_frame = self.camera_frame.copy() + new_frame.scale(0.0001).move_to(rows.get_corner(DR)) + + self.play( + Transform(self.camera_frame, new_frame, + run_time = 9, + rate_func = exponential_decay + ) + ) diff --git a/active_projects/eop/chapter1/intro.py b/active_projects/eop/chapter1/intro.py index 39a924d3..9689fa51 100644 --- a/active_projects/eop/chapter1/intro.py +++ b/active_projects/eop/chapter1/intro.py @@ -42,8 +42,9 @@ class Introduction(TeacherStudentsScene): self.wait() - - self.get_teacher().change_mode("raise_right_hand") + self.play( + self.get_teacher().change_mode,"raise_right_hand" + ) self.wait() self.wait(30) diff --git a/active_projects/eop/chapter1/morph_brick_row_into_histogram.py b/active_projects/eop/chapter1/morph_brick_row_into_histogram.py index be3f744e..ff5e8304 100644 --- a/active_projects/eop/chapter1/morph_brick_row_into_histogram.py +++ b/active_projects/eop/chapter1/morph_brick_row_into_histogram.py @@ -41,17 +41,20 @@ class GenericMorphBrickRowIntoHistogram(Scene): for rect in self.row.rects: rect.set_stroke(color = WHITE, width = 3) - self.play(self.row.rects.space_out_submobjects, {"factor" : 1.3}) - + self.wait() + self.play( + self.row.rects.space_out_submobjects, {"factor" : 1.3}, + FadeOut(tallies) + ) + self.wait() anims = [] for brick in self.row.rects: anims.append(brick.rotate) anims.append(TAU/4) - if self.show_tallies: - anims.append(FadeOut(tallies)) self.play(*anims) + self.wait() anims = [] for (i,brick) in enumerate(self.row.rects): @@ -59,6 +62,7 @@ class GenericMorphBrickRowIntoHistogram(Scene): anims.append(self.bar_anchors[i]) anims.append({"direction" : UP, "buff" : 0}) self.play(*anims) + self.wait() self.bars.create_outline() anims = [ @@ -68,6 +72,8 @@ class GenericMorphBrickRowIntoHistogram(Scene): anims.append(FadeIn(self.bars.outline)) self.play(*anims) + self.wait() + class MorphBrickRowIntoHistogram3(GenericMorphBrickRowIntoHistogram): @@ -83,6 +89,8 @@ class MorphBrickRowIntoHistogram3(GenericMorphBrickRowIntoHistogram): def construct(self): + + super(MorphBrickRowIntoHistogram3,self).construct() @@ -115,12 +123,14 @@ class MorphBrickRowIntoHistogram3(GenericMorphBrickRowIntoHistogram): if i != 0: y_guide.add(y_guide_label) y_guides.add(y_guide) + self.wait() self.play( FadeIn(y_guides), Animation(self.bars.outline), Animation(self.bars) ) + self.wait() self.play( FadeIn(x_axis), @@ -137,10 +147,12 @@ class MorphBrickRowIntoHistogram3(GenericMorphBrickRowIntoHistogram): total_area_group = VGroup(total_area_text, area_decimal) total_area_group.move_to(2.7 * UP) + self.wait() self.play( FadeIn(total_area_text), ) + self.wait() cumulative_areas = [0.125, 0.5, 0.875, 1] covering_rects = self.bars.copy() @@ -165,6 +177,7 @@ class MorphBrickRowIntoHistogram3(GenericMorphBrickRowIntoHistogram): FadeOut(covering_rects), ShowCreation(total_area_rect) ) + self.wait() @@ -194,12 +207,14 @@ class MorphBrickRowIntoHistogram20(GenericMorphBrickRowIntoHistogram): nb_tails_label = TextMobject("\# of tails") nb_tails_label.move_to(5 * RIGHT + 2.5 * DOWN) + self.wait() self.play( FadeIn(x_axis), FadeIn(x_labels), FadeIn(nb_tails_label) ) + self.wait() # draw y-guides @@ -221,6 +236,7 @@ class MorphBrickRowIntoHistogram20(GenericMorphBrickRowIntoHistogram): self.bring_to_back(y_guides) self.play(FadeIn(y_guides), Animation(self.bars)) + self.wait() histogram_width = self.bars.get_width() histogram_height = self.bars.get_height() @@ -247,6 +263,7 @@ class MorphBrickRowIntoHistogram20(GenericMorphBrickRowIntoHistogram): anims.append(ORIGIN) self.play(*anims) + self.wait() anims = [] for (guide, i, h) in zip(y_guides, prob_grid, y_guide_heights): @@ -265,6 +282,7 @@ class MorphBrickRowIntoHistogram20(GenericMorphBrickRowIntoHistogram): anims.append(self.bars.get_bottom()) self.play(*anims) + self.wait() class MorphBrickRowIntoHistogram100(MorphBrickRowIntoHistogram20): CONFIG = { diff --git a/active_projects/eop/chapter1/prob_dist_visuals.py b/active_projects/eop/chapter1/prob_dist_visuals.py index 1292d7b4..513c94c2 100644 --- a/active_projects/eop/chapter1/prob_dist_visuals.py +++ b/active_projects/eop/chapter1/prob_dist_visuals.py @@ -17,19 +17,9 @@ class ProbabilityDistributions(PiCreatureScene): run_time = 3 - text = TextMobject("Probability distributions", color = YELLOW) - text.to_edge(UP) - text_rect = SurroundingRectangle(text, buff = MED_SMALL_BUFF) - - self.play( - FadeIn(text), - ShowCreation(text_rect) - ) - - # WEATHER FORECAST - + unit_rect = Rectangle( height = 3, width = 3 ).shift(DOWN) @@ -48,9 +38,9 @@ class ProbabilityDistributions(PiCreatureScene): sun_rect.set_fill(color = YELLOW, opacity = opacity) sun_rect.set_stroke(width = 0) - self.play(FadeIn(VGroup(unit_rect, rain_rect, sun_rect))) + self.add(unit_rect, rain_rect, sun_rect) - rain = SVGMobject(file_name = "rain").scale(0.35) + rain = SVGMobject(file_name = "rain").scale(0.25) sun = SVGMobject(file_name = "sun").scale(0.35) rain.flip().move_to(rain_rect) @@ -58,6 +48,7 @@ class ProbabilityDistributions(PiCreatureScene): self.add(rain, sun) + text_scale = 0.7 brace_rain = Brace(rain_rect, UP) @@ -76,72 +67,73 @@ class ProbabilityDistributions(PiCreatureScene): self.add(brace_rain, p_rain_whole_label, brace_sun, p_sun_whole_label) + self.wait(6) - new_p_rain = 0.68 - new_p_sun = 1 - new_p_rain + # new_p_rain = 0.68 + # new_p_sun = 1 - new_p_rain - new_rain_rect = unit_rect.copy().stretch(new_p_rain, 0) - new_rain_rect.align_to(unit_rect, LEFT) - new_rain_rect.set_fill(color = BLUE, opacity = opacity) - new_rain_rect.set_stroke(width = 0) + # new_rain_rect = unit_rect.copy().stretch(new_p_rain, 0) + # new_rain_rect.align_to(unit_rect, LEFT) + # new_rain_rect.set_fill(color = BLUE, opacity = opacity) + # new_rain_rect.set_stroke(width = 0) - new_sun_rect = unit_rect.copy().stretch(new_p_sun, 0) - new_sun_rect.next_to(new_rain_rect, RIGHT, buff = 0) - new_sun_rect.set_fill(color = YELLOW, opacity = opacity) - new_sun_rect.set_stroke(width = 0) + # new_sun_rect = unit_rect.copy().stretch(new_p_sun, 0) + # new_sun_rect.next_to(new_rain_rect, RIGHT, buff = 0) + # new_sun_rect.set_fill(color = YELLOW, opacity = opacity) + # new_sun_rect.set_stroke(width = 0) - new_rain = SVGMobject(file_name = "rain").scale(0.35) - new_sun = SVGMobject(file_name = "sun").scale(0.35) + # new_rain = SVGMobject(file_name = "rain").scale(0.35) + # new_sun = SVGMobject(file_name = "sun").scale(0.35) - new_rain.flip().move_to(new_rain_rect) - new_sun.move_to(new_sun_rect) + # new_rain.flip().move_to(new_rain_rect) + # new_sun.move_to(new_sun_rect) - new_brace_rain = Brace(new_rain_rect, UP) - new_p_rain_label = TextMobject("$P($rain$)=$").scale(text_scale) - new_p_rain_decimal = DecimalNumber(new_p_rain).scale(text_scale) - new_p_rain_decimal.next_to(new_p_rain_label) - new_p_rain_whole_label = VGroup(new_p_rain_label, new_p_rain_decimal) - new_p_rain_whole_label.next_to(new_brace_rain, UP) + # new_brace_rain = Brace(new_rain_rect, UP) + # new_p_rain_label = TextMobject("$P($rain$)=$").scale(text_scale) + # new_p_rain_decimal = DecimalNumber(new_p_rain).scale(text_scale) + # new_p_rain_decimal.next_to(new_p_rain_label) + # new_p_rain_whole_label = VGroup(new_p_rain_label, new_p_rain_decimal) + # new_p_rain_whole_label.next_to(new_brace_rain, UP) - new_brace_sun = Brace(new_sun_rect, DOWN) - new_p_sun_label = TextMobject("$P($sunshine$)=$").scale(text_scale) - new_p_sun_decimal = DecimalNumber(new_p_sun).scale(text_scale) - new_p_sun_decimal.next_to(new_p_sun_label) - new_p_sun_whole_label = VGroup(new_p_sun_label, new_p_sun_decimal) - new_p_sun_whole_label.next_to(new_brace_sun, DOWN) + # new_brace_sun = Brace(new_sun_rect, DOWN) + # new_p_sun_label = TextMobject("$P($sunshine$)=$").scale(text_scale) + # new_p_sun_decimal = DecimalNumber(new_p_sun).scale(text_scale) + # new_p_sun_decimal.next_to(new_p_sun_label) + # new_p_sun_whole_label = VGroup(new_p_sun_label, new_p_sun_decimal) + # new_p_sun_whole_label.next_to(new_brace_sun, DOWN) - def rain_update_func(alpha): - return alpha * new_p_rain + (1 - alpha) * p_rain + # def rain_update_func(alpha): + # return alpha * new_p_rain + (1 - alpha) * p_rain - def sun_update_func(alpha): - return 1 - rain_update_func(alpha) + # def sun_update_func(alpha): + # return 1 - rain_update_func(alpha) - update_p_rain = ChangingDecimal( - p_rain_decimal, rain_update_func, - tracked_mobject = p_rain_label, - run_time = run_time - ) - update_p_sun = ChangingDecimal( - p_sun_decimal, sun_update_func, - tracked_mobject = p_sun_label, - run_time = run_time - ) + # update_p_rain = ChangingDecimal( + # p_rain_decimal, rain_update_func, + # tracked_mobject = p_rain_label, + # run_time = run_time + # ) + # update_p_sun = ChangingDecimal( + # p_sun_decimal, sun_update_func, + # tracked_mobject = p_sun_label, + # run_time = run_time + # ) - self.play( - Transform(rain_rect, new_rain_rect, run_time = run_time), - Transform(sun_rect, new_sun_rect, run_time = run_time), - Transform(rain, new_rain, run_time = run_time), - Transform(sun, new_sun, run_time = run_time), - Transform(brace_rain, new_brace_rain, run_time = run_time), - Transform(brace_sun, new_brace_sun, run_time = run_time), - Transform(p_rain_label, new_p_rain_label, run_time = run_time), - Transform(p_sun_label, new_p_sun_label, run_time = run_time), - update_p_rain, - update_p_sun - ) + # self.play( + # Transform(rain_rect, new_rain_rect, run_time = run_time), + # Transform(sun_rect, new_sun_rect, run_time = run_time), + # Transform(rain, new_rain, run_time = run_time), + # Transform(sun, new_sun, run_time = run_time), + # Transform(brace_rain, new_brace_rain, run_time = run_time), + # Transform(brace_sun, new_brace_sun, run_time = run_time), + # Transform(p_rain_label, new_p_rain_label, run_time = run_time), + # Transform(p_sun_label, new_p_sun_label, run_time = run_time), + # update_p_rain, + # update_p_sun + # ) @@ -164,51 +156,7 @@ class ProbabilityDistributions(PiCreatureScene): FadeOut(p_sun_whole_label), ) - - - - -# COIN FLIP - - - coin_flip_rect = BrickRow(3, height = 2, width = 10) - - for (i, brick) in enumerate(coin_flip_rect.rects): - tally = TallyStack(3 - i, i) - tally.move_to(brick) - coin_flip_rect.add(tally) - - coin_flip_rect.scale(0.8).shift(2*RIGHT) - self.play(FadeIn(coin_flip_rect)) - - counts = [1, 3, 3, 1] - braces = VGroup() - labels = VGroup() - for (rect, count) in zip(coin_flip_rect.rects, counts): - label = TexMobject("{" + str(count) + "\over 8}").scale(0.5) - brace = Brace(rect, DOWN) - label.next_to(brace, DOWN) - braces.add(brace) - labels.add(label) - - self.play( - LaggedStart(ShowCreation, braces, lag_ratio = lag_ratio, run_time = run_time), - LaggedStart(Write, labels, lag_ratio = lag_ratio, run_time = run_time) - ) - - coin_flip_rect.add(braces, labels) - - coin_flip_rect.target = coin_flip_rect.copy().scale(0.6) - coin_flip_rect.target.to_corner(UR, buff = MED_LARGE_BUFF) - coin_flip_rect.target.shift(DOWN) - - self.play( - MoveToTarget(coin_flip_rect) - ) - self.play( - FadeOut(braces), - FadeOut(labels) - ) + self.wait(3) # DOUBLE DICE THROW @@ -241,24 +189,25 @@ class ProbabilityDistributions(PiCreatureScene): for k in range(5 - i) ])) - self.play( - FadeIn(dice_unit_rect), - FadeIn(dice_table.rows) - ) + # self.play( + # FadeIn(dice_unit_rect), + # FadeIn(dice_table.rows) + # ) for (cell, label) in zip(dice_table.cells, dice_table.labels): cell.add(label) + # self.play( + # LaggedStart(FadeIn, dice_table_grouped_cells, + # lag_ratio = lag_ratio, run_time = run_time) + # ) self.play( - LaggedStart(FadeIn, dice_table_grouped_cells, - lag_ratio = lag_ratio, run_time = run_time) + FadeIn(dice_table_grouped_cells), + FadeIn(dice_unit_rect), + FadeIn(dice_table.rows) ) - self.wait() - self.play( - FadeOut(dice_table.rows), - FadeOut(dice_unit_rect), - ) + self.wait(3) self.play( @@ -266,3 +215,104 @@ class ProbabilityDistributions(PiCreatureScene): rate_func=there_and_back_with_pause, run_time=run_time ) + dice_table.add(dice_unit_rect) + dice_table_target = dice_table.copy() + dice_table_target.scale(0.5).to_corner(UR, buff = LARGE_BUFF) + dice_table_target.shift(0.4*UP) + + self.play(Transform(dice_table, dice_table_target)) + + self.play( + FadeOut(dice_table.rows), + FadeOut(dice_unit_rect), + ) + + self.wait(3) + +# TITLE + + text = TextMobject("Probability distributions", color = YELLOW) + text.to_edge(UP) + text_rect = SurroundingRectangle(text, buff = MED_SMALL_BUFF) + + self.play( + FadeIn(text), + ShowCreation(text_rect) + ) + + self.wait(3) + + +# COIN FLIP + + + brick_row = BrickRow(3, height = 2, width = 10) + coin_flip_rect = VGroup(brick_row) + + tallies = VGroup() + for (i, brick) in enumerate(brick_row.rects): + tally = TallyStack(3 - i, i) + tally.move_to(brick) + tallies.add(tally) + coin_flip_rect.add(tallies) + + coin_flip_rect.scale(0.65).shift(RIGHT) + self.play(FadeIn(coin_flip_rect)) + + counts = [1, 3, 3, 1] + braces = VGroup() + labels = VGroup() + for (rect, count) in zip(brick_row.rects, counts): + label = TexMobject("{" + str(count) + "\over 8}").scale(0.5) + brace = Brace(rect, DOWN) + label.next_to(brace, DOWN) + braces.add(brace) + labels.add(label) + + self.play( + FadeIn(braces), + FadeIn(labels) + ) + + coin_flip_rect.add(braces, labels) + + + self.wait(6) + + outcomes = brick_row.get_outcome_rects_for_level(3, with_labels = True, + inset = True) + outcomes.scale(0.65) + outcomes.move_to(brick_row.get_center()) + outcome_braces = VGroup(*[ + Brace(outcome, DOWN) for outcome in outcomes + ]) + outcome_labels = VGroup(*[ + TexMobject("{1\over 8}").scale(0.5).next_to(brace, DOWN) + for brace in outcome_braces + ]) + + self.play( + FadeOut(tallies), + FadeIn(outcomes), + FadeOut(braces), + FadeOut(labels), + FadeIn(outcome_braces), + FadeIn(outcome_labels) + ) + + + self.wait(10) + + + + + + + + + + + + + + diff --git a/active_projects/eop/chapter1/quiz_result.py b/active_projects/eop/chapter1/quiz_result.py index 3488efea..c6a85b30 100644 --- a/active_projects/eop/chapter1/quiz_result.py +++ b/active_projects/eop/chapter1/quiz_result.py @@ -71,9 +71,11 @@ class QuizResult(PiCreatureScene): all_quizzes.add(quiz_copy) master_quiz = get_example_quiz() - self.play(ShowCreation(master_quiz)) + self.play(ShowCreation(master_quiz), run_time = 2) + self.wait() self.play(Transform(master_quiz, all_quizzes[0])) - + self.wait() + self.play(LaggedStart(FadeIn,all_quizzes)) grades_mob = VGroup() @@ -83,6 +85,7 @@ class QuizResult(PiCreatureScene): grades_mob.add(grade_mob) self.remove(master_quiz) + self.wait() self.play( FadeOut(all_quizzes), FadeIn(grades_mob) @@ -99,13 +102,53 @@ class QuizResult(PiCreatureScene): slot.scale(0.5).move_to(quiz) students_points_mob.add(slot) + self.wait() self.play( #all_students.fade, 0, FadeOut(grades_mob), FadeIn(students_points_mob) ) + all_students.save_state() + students_points_mob.save_state() + self.wait() + randy = all_students[0] + morty = all_students[nb_students_y] + all_other_students = VGroup(*all_students) + all_other_students.remove(randy, morty) + randy_points = students_points_mob[0] + morty_points = students_points_mob[nb_students_y] + all_other_points = VGroup(*students_points_mob) + all_other_points.remove(randy_points, morty_points) + self.play( + all_other_students.fade, 0.8, + all_other_points.fade, 0.8, + ) + self.wait() + scale = 1.5 + self.play(randy_points.scale,scale) + self.play(randy_points.scale,1.0/scale, morty_points.scale,scale) + self.play(morty_points.scale,1.0/scale) + self.wait() + self.play( + all_students.restore, + students_points_mob.restore, + ) + + self.wait() + anims = [] + for points in students_points_mob: + anims.append(points.scale) + anims.append(scale) + self.play(*anims) + + self.wait() + anims = [] + for points in students_points_mob: + anims.append(points.scale) + anims.append(1.0/scale) + self.play(*anims) anims = [] anchor_point = 3 * DOWN + 1 * LEFT @@ -114,6 +157,7 @@ class QuizResult(PiCreatureScene): anims.append(anchor_point + grade * RIGHT + grades_count * UP) anims.append(FadeOut(students_points_mob)) + self.wait() self.play(*anims) grade_labels = VGroup() @@ -125,6 +169,7 @@ class QuizResult(PiCreatureScene): out_of_label = TextMobject("out of 3", color = highlight_color) out_of_label.next_to(grade_labels, RIGHT, buff = MED_LARGE_BUFF) grade_labels.add(out_of_label) + self.wait() self.play(Write(grade_labels)) grade_hist = Histogram( @@ -138,6 +183,7 @@ class QuizResult(PiCreatureScene): ) grade_hist.move_to(all_students) + self.wait() self.play( FadeIn(grade_hist), FadeOut(all_students) @@ -145,12 +191,13 @@ class QuizResult(PiCreatureScene): nb_students_label = TextMobject("\# of students", color = highlight_color) - nb_students_label.move_to(5 * LEFT + 2 * UP) + nb_students_label.move_to(5 * RIGHT + 1 * UP) arrows = VGroup(*[ - Arrow(nb_students_label.get_right(), grade_hist.bars[i].get_center(), + Arrow(nb_students_label.get_left(), grade_hist.bars[i].get_center(), color = highlight_color) for i in range(4) ]) + self.wait() self.play(Write(nb_students_label), LaggedStart(GrowArrow,arrows)) percentage_label = TextMobject("\% of students", color = highlight_color) @@ -167,6 +214,7 @@ class QuizResult(PiCreatureScene): new_label.move_to(label) anims.append(Transform(label, new_label)) anims.append(ReplacementTransform(nb_students_label, percentage_label)) + self.wait() self.play(*anims) self.remove(all_quizzes) @@ -177,10 +225,12 @@ class QuizResult(PiCreatureScene): pi.move_to(x * RIGHT + y * UP) all_students.scale(0.8) all_students.to_corner(DOWN + LEFT) + self.wait() self.play(FadeIn(all_students)) prob_label = TextMobject("probability", color = highlight_color) prob_label.move_to(percentage_label) + self.wait() self.play( all_students[8].set_color, MAROON_E, #all_students[:8].fade, 0.6, @@ -188,6 +238,7 @@ class QuizResult(PiCreatureScene): ReplacementTransform(percentage_label, prob_label) ) + self.wait() self.play( FadeOut(prob_label), FadeOut(arrows) @@ -210,6 +261,7 @@ class QuizResult(PiCreatureScene): rate_func = linear ) + self.wait() for i in range(3): self.play(flash_hist, flash_class) self.remove(flash_hist.prototype_cell) diff --git a/active_projects/eop/chapter1/show_proportion.py b/active_projects/eop/chapter1/show_proportion.py new file mode 100644 index 00000000..f891dae4 --- /dev/null +++ b/active_projects/eop/chapter1/show_proportion.py @@ -0,0 +1,145 @@ +from big_ol_pile_of_manim_imports import * + + +class ProbabilityRect(VMobject): + CONFIG = { + "unit_width" : 2, + "unit_height" : 2, + "alignment" : LEFT, + "color": YELLOW, + "opacity": 1.0, + "num_decimal_places": 2, + "use_percent" : False + } + + def __init__(self, p0, **kwargs): + + VMobject.__init__(self, **kwargs) + self.unit_rect = Rectangle( + width = self.unit_width, + height = self.unit_height, + stroke_color = self.color + ) + self.p = p0 + self.prob_rect = self.create_prob_rect(p0) + self.prob_label = self.create_prob_label(p0) + + self.add(self.unit_rect, self.prob_rect, self.prob_label) + + + def create_prob_rect(self, p): + + prob_width, prob_height = self.unit_width, self.unit_height + + if self.alignment in [LEFT, RIGHT]: + prob_width *= p + elif self.alignment in [UP, DOWN]: + prob_height *= p + else: + raise Exception("Aligment must be LEFT, RIGHT, UP or DOWN") + + prob_rect = Rectangle( + width = prob_width, + height = prob_height, + fill_color = self.color, + fill_opacity = self.opacity, + stroke_color = self.color + ) + + prob_rect.align_to(self.unit_rect, direction = self.alignment) + return prob_rect + + + def create_prob_label(self, p): + + if self.use_percent: + prob_label = DecimalNumber( + p * 100, + color = BLACK, + num_decimal_places = self.num_decimal_places, + unit = "\%" + ) + else: + prob_label = DecimalNumber( + p, + color = BLACK, + num_decimal_places = self.num_decimal_places, + ) + + prob_label.move_to(self.prob_rect) + + return prob_label + + +class ChangeProbability(Animation): + + def __init__(self, prob_mob, p1, **kwargs): + + if not isinstance(prob_mob, ProbabilityRect): + raise Exception("ChangeProportion's mobject must be a ProbabilityRect") + + self.p1 = p1 + self.p0 = prob_mob.p + Animation.__init__(self, prob_mob, **kwargs) + + + def update_mobject(self, alpha): + + p = (1 - alpha) * self.p0 + alpha * self.p1 + self.mobject.remove(self.mobject.prob_rect, self.mobject.prob_label) + self.mobject.prob_rect = self.mobject.create_prob_rect(p) + self.mobject.prob_label = self.mobject.create_prob_label(p) + self.mobject.add(self.mobject.prob_rect, self.mobject.prob_label) + + + def clean_up(self, surrounding_scene=None): + self.mobject.p = self.p1 + super(ChangeProbability, self).clean_up(surrounding_scene = surrounding_scene) + + + + + +class ShowProbAsProportion(Scene): + + def construct(self): + + p0 = 0.3 + p1 = 1 + p2 = 0.18 + p3 = 0.64 + + prob_mob = ProbabilityRect(p0, + unit_width = 4, + unit_height = 2, + use_percent = False, + num_decimal_places = 2 + ) + + self.add(prob_mob) + self.wait() + self.play( + ChangeProbability(prob_mob, p1, + run_time = 3) + ) + self.wait(0.5) + self.play( + ChangeProbability(prob_mob, p2, + run_time = 3) + ) + self.wait(0.5) + self.play( + ChangeProbability(prob_mob, p3, + run_time = 3) + ) + + + + + + + + + + + diff --git a/active_projects/eop/chapter1/stacking_coins.py b/active_projects/eop/chapter1/stacking_coins.py new file mode 100644 index 00000000..40962157 --- /dev/null +++ b/active_projects/eop/chapter1/stacking_coins.py @@ -0,0 +1,29 @@ +from big_ol_pile_of_manim_imports import * +from active_projects.eop.reusable_imports import * + + +class StackingCoins(Scene): + + def construct(self): + + h = t = 0 + heads_stack = HeadsStack(size = h) + heads_stack.next_to(0.5*LEFT + 3*DOWN, UP) + tails_stack = TailsStack(size = t) + tails_stack.next_to(0.5*RIGHT + 3*DOWN, UP) + self.add(heads_stack, tails_stack) + + for i in range(120): + flip = np.random.choice(["H", "T"]) + if flip == "H": + h += 1 + new_heads_stack = HeadsStack(size = h) + new_heads_stack.next_to(0.5*LEFT + 3*DOWN, UP) + self.play(Transform(heads_stack, new_heads_stack, + run_time = 0.2)) + elif flip == "T": + t += 1 + new_tails_stack = TailsStack(size = t) + new_tails_stack.next_to(0.5*RIGHT + 3*DOWN, UP) + self.play(Transform(tails_stack, new_tails_stack, + run_time = 0.2)) diff --git a/active_projects/eop/chapter1/think_about_coin.py b/active_projects/eop/chapter1/think_about_coin.py new file mode 100644 index 00000000..50cfd2de --- /dev/null +++ b/active_projects/eop/chapter1/think_about_coin.py @@ -0,0 +1,31 @@ + +from big_ol_pile_of_manim_imports import * +from active_projects.eop.reusable_imports import * + +class RandyThinksAboutCoin(PiCreatureScene): + + def construct(self): + + randy = self.get_primary_pi_creature() + randy.center() + self.add(randy) + self.wait() + h_or_t = BinaryOption(UprightHeads().scale(3), UprightTails().scale(3), + text_scale = 1.5) + self.think(h_or_t, direction = LEFT) + + v = 0.3 + self.play( + h_or_t[0].shift,v*UP, + h_or_t[2].shift,v*DOWN, + ) + self.play( + h_or_t[0].shift,2*v*DOWN, + h_or_t[2].shift,2*v*UP, + ) + self.play( + h_or_t[0].shift,v*UP, + h_or_t[2].shift,v*DOWN, + ) + + self.wait() diff --git a/active_projects/eop/chapter1/what_does_probability_mean.py b/active_projects/eop/chapter1/what_does_probability_mean.py new file mode 100644 index 00000000..99fc1413 --- /dev/null +++ b/active_projects/eop/chapter1/what_does_probability_mean.py @@ -0,0 +1,46 @@ + +from big_ol_pile_of_manim_imports import * + +class WhatDoesItReallyMean(TeacherStudentsScene): + + CONFIG = { + "default_pi_creature_kwargs": { + "color": MAROON_E, + "flip_at_start": True, + }, + } + + def construct(self): + + student_q = TextMobject("What does", "``probability''", "\emph{actually}", "mean?") + student_q.set_color_by_tex("probability", YELLOW) + self.student_says(student_q, target_mode = "sassy") + self.wait() + self.play( + self.students[1].change_mode, "plain" + ) + self.wait() + self.play(RemovePiCreatureBubble(self.students[1])) + + self.wait() + + self.teacher_says("Don't worry -- philosophy can come later!") + self.wait() + + + +class EmptyTSScene(TeacherStudentsScene): + CONFIG = { + "default_pi_creature_kwargs": { + "color": MAROON_E, + "flip_at_start": True, + }, + } + + def construct(self): + + self.wait() + self.play(*[ + ApplyMethod(pi.look_at,ORIGIN) for pi in self.get_pi_creatures() + ]) + self.wait(8) \ No newline at end of file diff --git a/active_projects/eop/reusables/binary_option.py b/active_projects/eop/reusables/binary_option.py index ed0c3f45..b9911c93 100644 --- a/active_projects/eop/reusables/binary_option.py +++ b/active_projects/eop/reusables/binary_option.py @@ -2,11 +2,14 @@ from mobject.types.vectorized_mobject import * from mobject.svg.tex_mobject import * class BinaryOption(VMobject): + CONFIG = { + "text_scale" : 0.5 + } def __init__(self, mob1, mob2, **kwargs): VMobject.__init__(self, **kwargs) - text = TextMobject("or").scale(0.5) + text = TextMobject("or").scale(self.text_scale) mob1.next_to(text, LEFT) mob2.next_to(text, RIGHT) self.add(mob1, text, mob2) diff --git a/active_projects/eop/reusables/brick_row.py b/active_projects/eop/reusables/brick_row.py index 92ca15f7..38bf603d 100644 --- a/active_projects/eop/reusables/brick_row.py +++ b/active_projects/eop/reusables/brick_row.py @@ -6,8 +6,8 @@ from active_projects.eop.reusables.upright_coins import * class BrickRow(VMobject): CONFIG = { - "left_color" : RED, - "right_color" : BLUE, + "left_color" : COLOR_HEADS, + "right_color" : COLOR_TAILS, "height" : 1.0, "width" : 8.0, "outcome_shrinkage_factor_x" : 0.95, @@ -104,14 +104,14 @@ class BrickRow(VMobject): outcome_width = float(self.width) / (2 ** r) outcome_height = self.height - corner_radius = min(0.1, 0.3 * min(outcome_width, outcome_height)) + corner_radius = 0.1 # max(0.1, 0.3 * min(outcome_width, outcome_height)) # this scales down the corner radius for very narrow rects rect = RoundedRectangle( width = outcome_width, height = outcome_height, corner_radius = corner_radius, - fill_color = WHITE, - fill_opacity = 0.2, + fill_color = OUTCOME_COLOR, + fill_opacity = OUTCOME_OPACITY, stroke_width = 0 ) rects = VGroup() @@ -179,11 +179,11 @@ class BrickRow(VMobject): - class SplitRectsInBrickWall(AnimationGroup): def __init__(self, mobject, **kwargs): + #print mobject.height, mobject.get_height() r = self.subdiv_level = mobject.subdiv_level + 1 subdivs = VGroup() @@ -196,6 +196,7 @@ class SplitRectsInBrickWall(AnimationGroup): subdiv = DashedLine( mobject.get_top() + x * RIGHT, mobject.get_bottom() + x * RIGHT, + dashed_segment_length = 0.05 ) subdivs.add(subdiv) anims.append(ShowCreation(subdiv)) diff --git a/active_projects/eop/reusables/eop_constants.py b/active_projects/eop/reusables/eop_constants.py index 8711a36f..5e5eb762 100644 --- a/active_projects/eop/reusables/eop_constants.py +++ b/active_projects/eop/reusables/eop_constants.py @@ -9,10 +9,16 @@ COIN_STROKE_WIDTH = 2 COIN_SEQUENCE_SPACING = 0.1 -GRADE_COLOR_1 = COLOR_HEADS = RED -GRADE_COLOR_2 = COLOR_TAILS = BLUE_E +GRADE_COLOR_1 = COLOR_HEADS = RED_E +GRADE_COLOR_2 = COLOR_TAILS = BLUE_C + +COLOR_HEADS_COIN = RED +COLOR_TAILS_COIN = BLUE_E TALLY_BACKGROUND_WIDTH = 1.0 TALLY_BACKGROUND_COLOR = BLACK -SICKLY_GREEN = "#9BBD37" \ No newline at end of file +SICKLY_GREEN = "#9BBD37" + +OUTCOME_COLOR = WHITE +OUTCOME_OPACITY = 0.5 \ No newline at end of file diff --git a/active_projects/eop/reusables/upright_coins.py b/active_projects/eop/reusables/upright_coins.py index 1f5456b7..2835455a 100644 --- a/active_projects/eop/reusables/upright_coins.py +++ b/active_projects/eop/reusables/upright_coins.py @@ -24,13 +24,13 @@ class UprightCoin(Circle): class UprightHeads(UprightCoin): CONFIG = { - "fill_color": COLOR_HEADS, + "fill_color": COLOR_HEADS_COIN, "symbol": "H", } class UprightTails(UprightCoin): CONFIG = { - "fill_color": COLOR_TAILS, + "fill_color": COLOR_TAILS_COIN, "symbol": "T", } @@ -120,13 +120,13 @@ class FlatCoin(UprightCoin): class FlatHeads(FlatCoin): CONFIG = { - "fill_color": COLOR_HEADS, + "fill_color": COLOR_HEADS_COIN, "symbol": "H", } class FlatTails(FlatCoin): CONFIG = { - "fill_color": COLOR_TAILS, + "fill_color": COLOR_TAILS_COIN, "symbol": "T", } \ No newline at end of file diff --git a/active_projects/eop/what_does_probability_mean.py b/active_projects/eop/what_does_probability_mean.py index 31247c7e..0da0ec10 100644 --- a/active_projects/eop/what_does_probability_mean.py +++ b/active_projects/eop/what_does_probability_mean.py @@ -16,6 +16,15 @@ class WhatDoesItReallyMean(TeacherStudentsScene): student_q.set_color_by_tex("probability", YELLOW) self.student_says(student_q, target_mode = "sassy") self.wait() + + question_bubble = VGroup(student_q, students[1].bubble) + scaled_qb = question_bubble.copy() + scaled_qb.scale(0.4).to_corner(UL) + self.play(Transform(question_bubble, scaled_qb)) + self.wait() + + + self.teacher_says("Don't worry -- philosophy can come later!") self.wait() diff --git a/mobject/svg/drawings.py b/mobject/svg/drawings.py index e22ec529..e2c753fb 100644 --- a/mobject/svg/drawings.py +++ b/mobject/svg/drawings.py @@ -458,9 +458,9 @@ class Bubble(SVGMobject): def pin_to(self, mobject): mob_center = mobject.get_center() - want_to_filp = np.sign(mob_center[0]) != np.sign(self.direction[0]) + want_to_flip = np.sign(mob_center[0]) != np.sign(self.direction[0]) can_flip = not self.direction_was_specified - if want_to_filp and can_flip: + if want_to_flip and can_flip: self.flip() boundary_point = mobject.get_critical_point(UP - self.direction) vector_from_center = 1.0 * (boundary_point - mob_center) diff --git a/utils/rate_functions.py b/utils/rate_functions.py index f9ebb142..fe43c48a 100644 --- a/utils/rate_functions.py +++ b/utils/rate_functions.py @@ -82,3 +82,24 @@ def squish_rate_func(func, a=0.4, b=0.6): def lingering(t): return squish_rate_func(lambda t: t, 0, 0.8)(t) + +def exponential_decay(t, half_life = 0.1): +# The half-life should be rather small to minimize the cut-off error at the end + return 1 - np.exp(-t/half_life) + + + + + + + + + + + + + + + + +