mirror of
https://github.com/3b1b/manim.git
synced 2026-04-26 03:00:23 -04:00
@@ -1,7 +1,6 @@
|
||||
from big_ol_pile_of_manim_imports import *
|
||||
from old_projects.eoc.chapter8 import *
|
||||
from active_projects.eop.histograms import *
|
||||
from svgpathtools import *
|
||||
|
||||
import scipy.special
|
||||
|
||||
@@ -75,7 +74,7 @@ class CoinFlippingPiCreature(PiCreature):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
|
||||
coin = PiCreatureCoin() # Line(ORIGIN, 0.4 * RIGHT, stroke_width = 15, color = YELLOW)
|
||||
coin = PiCreatureCoin()
|
||||
PiCreature.__init__(self,**kwargs)
|
||||
self.coin = coin
|
||||
self.add(coin)
|
||||
@@ -107,12 +106,15 @@ class FlipCoin(AnimationGroup):
|
||||
rate_func = self.rate_func,
|
||||
**kwargs
|
||||
)
|
||||
coin_motion = FlipUpAndDown(
|
||||
pi_creature.coin,
|
||||
vector = UP,
|
||||
nb_turns = 5,
|
||||
rate_func = self.rate_func,
|
||||
**kwargs
|
||||
coin_motion = Succession(
|
||||
EmptyAnimation(run_time = 1.0),
|
||||
FlipUpAndDown(
|
||||
pi_creature.coin,
|
||||
vector = UP,
|
||||
nb_turns = 5,
|
||||
rate_func = self.rate_func,
|
||||
**kwargs
|
||||
)
|
||||
)
|
||||
AnimationGroup.__init__(self,pi_creature_motion, coin_motion)
|
||||
|
||||
@@ -270,19 +272,33 @@ class TailsStack(CoinStack):
|
||||
}
|
||||
|
||||
class TallyStack(VGroup):
|
||||
CONFIG = {
|
||||
"coin_thickness": COIN_THICKNESS
|
||||
}
|
||||
|
||||
def __init__(self,h,t,**kwargs):
|
||||
def __init__(self,h,t,anchor = ORIGIN, **kwargs):
|
||||
self.nb_heads = h
|
||||
self.nb_tails = t
|
||||
self.anchor = anchor
|
||||
VGroup.__init__(self,**kwargs)
|
||||
|
||||
def generate_points(self):
|
||||
stack1 = HeadsStack(size = self.nb_heads, coin_thickness = self.coin_thickness)
|
||||
stack2 = TailsStack(size = self.nb_tails, coin_thickness = self.coin_thickness)
|
||||
stack2.next_to(stack1, RIGHT, buff = SMALL_BUFF)
|
||||
stack2.align_to(stack1, DOWN)
|
||||
stack1.next_to(self.anchor, LEFT, buff = SMALL_BUFF)
|
||||
stack2.next_to(self.anchor, RIGHT, buff = SMALL_BUFF)
|
||||
stack1.align_to(self.anchor, DOWN)
|
||||
stack2.align_to(self.anchor, DOWN)
|
||||
self.heads_stack = stack1
|
||||
self.tails_stack = stack2
|
||||
self.add(stack1, stack2)
|
||||
|
||||
def move_anchor_to(self, new_anchor):
|
||||
for submob in self.submobjects:
|
||||
submob.shift(new_anchor - self.anchor)
|
||||
self.anchor = new_anchor
|
||||
return self
|
||||
|
||||
class CoinFlipTree(VGroup):
|
||||
CONFIG = {
|
||||
"total_width": 12,
|
||||
@@ -362,36 +378,6 @@ class CoinFlipTree(VGroup):
|
||||
|
||||
|
||||
|
||||
class TestScene(Scene):
|
||||
|
||||
def construct(self):
|
||||
|
||||
#seq = CoinSequence(["H", "T", "T", "H"]).move_to(2 * LEFT)
|
||||
#self.add(seq)
|
||||
|
||||
#stack = TallyStack(4,7, coin_thickness = COIN_THICKNESS)
|
||||
#self.add(stack)
|
||||
|
||||
tree = CoinFlipTree(nb_levels = 7, sort_until_level = 0)
|
||||
tree.move_to(ORIGIN)
|
||||
self.add(tree)
|
||||
|
||||
for i in range(1, 8):
|
||||
new_tree = CoinFlipTree(nb_levels = 7, sort_until_level = i)
|
||||
new_tree.move_to(ORIGIN)
|
||||
self.play(Transform(tree, new_tree))
|
||||
self.wait()
|
||||
|
||||
self.wait()
|
||||
|
||||
|
||||
class CoinFlipBranchToAreaScene(Scene):
|
||||
|
||||
def construct(self):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class Chapter1OpeningQuote(OpeningQuote):
|
||||
CONFIG = {
|
||||
@@ -425,6 +411,7 @@ class Introduction(TeacherStudentsScene):
|
||||
|
||||
def construct(self):
|
||||
self.show_series()
|
||||
self.show_area_model1()
|
||||
|
||||
def show_series(self):
|
||||
series = VideoSeries()
|
||||
@@ -475,28 +462,28 @@ class Introduction(TeacherStudentsScene):
|
||||
Animation(self.teacher.bubble.content),
|
||||
])
|
||||
|
||||
essence_words = words.get_part_by_tex("Essence").copy()
|
||||
self.play(
|
||||
FadeOut(self.teacher.bubble),
|
||||
FadeOut(self.teacher.bubble.content),
|
||||
essence_words.next_to, series, DOWN,
|
||||
*[
|
||||
ApplyMethod(pi.change_mode, "pondering")
|
||||
for pi in self.get_pi_creatures()
|
||||
]
|
||||
)
|
||||
self.wait(3)
|
||||
self.wait()
|
||||
|
||||
self.series = series
|
||||
self.essence_words = essence_words
|
||||
|
||||
class IllustrateAreaModel1(Scene):
|
||||
|
||||
def construct(self):
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
# show examples of the area model #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
|
||||
|
||||
def show_area_model1(self):
|
||||
|
||||
# show independent events
|
||||
|
||||
sample_space_width = sample_space_height = 3.0
|
||||
sample_space_width = sample_space_height = 2.5
|
||||
p_of_A = 0.7
|
||||
p_of_not_A = 1 - p_of_A
|
||||
p_of_B = 0.8
|
||||
@@ -509,7 +496,8 @@ class IllustrateAreaModel1(Scene):
|
||||
stroke_width = 0,
|
||||
fill_color = BLUE,
|
||||
fill_opacity = 1.0
|
||||
)
|
||||
).move_to(2 * RIGHT + 1.5 * UP)
|
||||
|
||||
rect_not_A = Rectangle(
|
||||
width = p_of_not_A * sample_space_width,
|
||||
height = 1 * sample_space_height,
|
||||
@@ -523,18 +511,13 @@ class IllustrateAreaModel1(Scene):
|
||||
brace_not_A = Brace(rect_not_A, DOWN)
|
||||
label_not_A = TexMobject("P(\\text{not }A)").next_to(brace_not_A, DOWN).scale(0.7)
|
||||
|
||||
self.play(
|
||||
LaggedStart(FadeIn, VGroup(rect_A, rect_not_A), lag_factor = 0.5)
|
||||
)
|
||||
self.play(
|
||||
ShowCreation(brace_A),
|
||||
Write(label_A),
|
||||
)
|
||||
# self.play(
|
||||
# ShowCreation(brace_not_A),
|
||||
# Write(label_not_A),
|
||||
# LaggedStart(FadeIn, VGroup(rect_A, rect_not_A), lag_factor = 0.5)
|
||||
# )
|
||||
# self.play(
|
||||
# ShowCreation(brace_A),
|
||||
# Write(label_A),
|
||||
# )
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -560,16 +543,12 @@ class IllustrateAreaModel1(Scene):
|
||||
brace_not_B = Brace(rect_not_B, LEFT)
|
||||
label_not_B = TexMobject("P(\\text{not }B)").next_to(brace_not_B, LEFT).scale(0.7)
|
||||
|
||||
self.play(
|
||||
LaggedStart(FadeIn, VGroup(rect_B, rect_not_B), lag_factor = 0.5)
|
||||
)
|
||||
self.play(
|
||||
ShowCreation(brace_B),
|
||||
Write(label_B),
|
||||
)
|
||||
# self.play(
|
||||
# ShowCreation(brace_not_B),
|
||||
# Write(label_not_B),
|
||||
# LaggedStart(FadeIn, VGroup(rect_B, rect_not_B), lag_factor = 0.5)
|
||||
# )
|
||||
# self.play(
|
||||
# ShowCreation(brace_B),
|
||||
# Write(label_B),
|
||||
# )
|
||||
|
||||
rect_A_and_B = Rectangle(
|
||||
@@ -581,11 +560,9 @@ class IllustrateAreaModel1(Scene):
|
||||
label_A_and_B = TexMobject("P(A\\text{ and }B)").scale(0.7)
|
||||
label_A_and_B.move_to(rect_A_and_B)
|
||||
|
||||
self.play(
|
||||
ShowCreation(rect_A_and_B)
|
||||
)
|
||||
self.play(FadeIn(label_A_and_B))
|
||||
self.add_foreground_mobject(label_A_and_B)
|
||||
# self.play(
|
||||
# ShowCreation(rect_A_and_B)
|
||||
# )
|
||||
|
||||
indep_formula = TexMobject("P(A\\text{ and }B)", "=", "P(A)", "\cdot", "P(B)")
|
||||
indep_formula = indep_formula.scale(0.7).next_to(rect_not_B, UP, buff = MED_LARGE_BUFF)
|
||||
@@ -593,16 +570,19 @@ class IllustrateAreaModel1(Scene):
|
||||
label_A_and_B_copy = label_A_and_B.copy()
|
||||
label_A_copy = label_A.copy()
|
||||
label_B_copy = label_B.copy()
|
||||
self.add(label_A_and_B_copy, label_A_copy, label_B_copy)
|
||||
# self.add(label_A_and_B_copy, label_A_copy, label_B_copy)
|
||||
|
||||
self.play(Transform(label_A_and_B_copy, indep_formula[0]))
|
||||
self.play(FadeIn(indep_formula[1]))
|
||||
self.play(Transform(label_A_copy, indep_formula[2]))
|
||||
self.play(FadeIn(indep_formula[3]))
|
||||
self.play(Transform(label_B_copy, indep_formula[4]))
|
||||
# self.play(Transform(label_A_and_B_copy, indep_formula[0]))
|
||||
# self.play(FadeIn(indep_formula[1]))
|
||||
# self.play(Transform(label_A_copy, indep_formula[2]))
|
||||
# self.play(FadeIn(indep_formula[3]))
|
||||
# self.play(Transform(label_B_copy, indep_formula[4]))
|
||||
|
||||
self.wait()
|
||||
#self.wait()
|
||||
|
||||
label_A_and_B_copy = indep_formula[0]
|
||||
label_A_copy = indep_formula[2]
|
||||
label_B_copy = indep_formula[4]
|
||||
|
||||
# show conditional prob
|
||||
|
||||
@@ -631,11 +611,22 @@ class IllustrateAreaModel1(Scene):
|
||||
fill_opacity = 0.5
|
||||
).next_to(rect_not_A_and_B, UP, buff = 0)
|
||||
|
||||
self.remove(rect_B, rect_not_B)
|
||||
self.add(rect_A_and_not_B, rect_not_A_and_B, rect_not_A_and_not_B)
|
||||
|
||||
indep_formula.next_to(rect_not_A, LEFT, buff = 4)
|
||||
indep_formula.shift(UP)
|
||||
|
||||
self.play(Write(indep_formula))
|
||||
|
||||
self.play(
|
||||
FadeIn(VGroup(
|
||||
rect_A, rect_not_A, brace_A, label_A, brace_B, label_B,
|
||||
rect_A_and_not_B, rect_not_A_and_B, rect_not_A_and_not_B,
|
||||
rect_A_and_B,
|
||||
label_A_and_B,
|
||||
))
|
||||
)
|
||||
|
||||
self.wait()
|
||||
|
||||
|
||||
p_of_B_knowing_A = 0.6
|
||||
@@ -668,7 +659,7 @@ class IllustrateAreaModel1(Scene):
|
||||
)
|
||||
label_B_knowing_A = label_B
|
||||
|
||||
self.play(FadeOut(label_B_copy))
|
||||
#self.play(FadeOut(label_B_copy))
|
||||
self.remove(indep_formula.get_part_by_tex("P(B)"))
|
||||
label_B_knowing_A_copy = label_B_knowing_A.copy()
|
||||
self.add(label_B_knowing_A_copy)
|
||||
@@ -684,6 +675,7 @@ class IllustrateAreaModel1(Scene):
|
||||
|
||||
self.wait()
|
||||
|
||||
|
||||
self.play(
|
||||
# in some places get_part_by_tex does not find the correct part
|
||||
# so I picked out fitting indices
|
||||
@@ -691,7 +683,17 @@ class IllustrateAreaModel1(Scene):
|
||||
label_A_copy.move_to, rearranged_formula[-1][10],
|
||||
label_A_and_B_copy.move_to, rearranged_formula[-1][3],
|
||||
indep_formula.get_part_by_tex("=").move_to, rearranged_formula.get_part_by_tex("="),
|
||||
Transform(indep_formula.get_part_by_tex("\cdot"), rearranged_formula[-1][8]),
|
||||
Transform(indep_formula.get_part_by_tex("\cdot"), rearranged_formula[2][6]),
|
||||
)
|
||||
|
||||
|
||||
self.play(
|
||||
FadeOut(VGroup(
|
||||
indep_formula, rect_A, rect_B, rect_not_A, rect_not_B,
|
||||
rect_A_and_B, rect_A_and_not_B, rect_not_A_and_B, rect_not_A_and_not_B,
|
||||
brace_A, brace_B, label_A, label_B_knowing_A, label_A_and_B,
|
||||
label_B_knowing_A_copy
|
||||
))
|
||||
)
|
||||
|
||||
|
||||
@@ -776,8 +778,8 @@ class IllustrateAreaModel1(Scene):
|
||||
|
||||
class IllustrateAreaModel2(GraphScene):
|
||||
CONFIG = {
|
||||
"x_min" : -5,
|
||||
"x_max" : 5,
|
||||
"x_min" : -3.5,
|
||||
"x_max" : 3.5,
|
||||
"y_min" : -0,
|
||||
"y_max" : 0.6,
|
||||
"graph_origin": 3*DOWN,
|
||||
@@ -785,7 +787,10 @@ class IllustrateAreaModel2(GraphScene):
|
||||
"y_axis_label" : "",
|
||||
"x_axis_label" : "",
|
||||
"variable_point_label" : "x",
|
||||
"y_axis_height" : 4
|
||||
"y_axis_height" : 4,
|
||||
"graph_origin": 2.5 * DOWN + 3 * LEFT,
|
||||
"x_axis_width": 5,
|
||||
"y_axis_height": 3
|
||||
}
|
||||
|
||||
def construct(self):
|
||||
@@ -793,7 +798,7 @@ class IllustrateAreaModel2(GraphScene):
|
||||
x_max_1 = 0
|
||||
x_min_1 = -x_max_1
|
||||
|
||||
x_max_2 = 5
|
||||
x_max_2 = 3.5
|
||||
x_min_2 = -x_max_2
|
||||
|
||||
|
||||
@@ -802,10 +807,10 @@ class IllustrateAreaModel2(GraphScene):
|
||||
|
||||
self.add(graph)
|
||||
|
||||
|
||||
cdf_formula = TexMobject("P(|X-\mu| < x) = \int_{-x}^x {\exp(-{1\over 2}({t\over \sigma})^2) \over \sigma\sqrt{2\pi}} dt")
|
||||
|
||||
cdf_formula.set_color_by_tex("x", YELLOW)
|
||||
cdf_formula.next_to(graph, LEFT, buff = 1)
|
||||
cdf_formula.next_to(graph, RIGHT, buff = -1)
|
||||
self.add(cdf_formula)
|
||||
|
||||
|
||||
@@ -1121,26 +1126,140 @@ class RowOfDice(VGroup):
|
||||
|
||||
|
||||
|
||||
class ShowUncertainty(PiCreatureScene):
|
||||
class ShowUncertainty1(PiCreatureScene):
|
||||
|
||||
def throw_a_die(self):
|
||||
|
||||
eye = np.random.randint(1,7)
|
||||
face = self.row_of_dice.submobjects[eye - 1]
|
||||
self.tallies[eye - 1] += 1
|
||||
|
||||
new_hist = self.hist_from_tallies()
|
||||
|
||||
self.play(
|
||||
ApplyMethod(face.submobjects[0].set_fill, {"opacity": 1},
|
||||
rate_func = there_and_back,
|
||||
run_time = 0.3,
|
||||
),
|
||||
)
|
||||
self.play(
|
||||
Transform(self.dice_histogram, new_hist,
|
||||
run_time = 0.5)
|
||||
)
|
||||
|
||||
|
||||
|
||||
def hist_from_tallies(self):
|
||||
x_scale = self.row_of_dice.get_width() / np.size(self.tallies)
|
||||
hist = Histogram(np.ones(6), self.tallies,
|
||||
mode = "widths",
|
||||
x_labels = "none",
|
||||
y_scale = 0.5,
|
||||
x_scale = x_scale
|
||||
)
|
||||
|
||||
hist.next_to(self.row_of_dice, UP)
|
||||
return hist
|
||||
|
||||
def construct(self):
|
||||
|
||||
row_of_dice = RowOfDice().scale(0.5).move_to(ORIGIN)
|
||||
self.add(row_of_dice)
|
||||
rounded_rect = RoundedRectangle(
|
||||
width = 3,
|
||||
height = 2,
|
||||
corner_radius = 0.1
|
||||
).shift(3*LEFT)
|
||||
self.add(rounded_rect)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
self.row_of_dice = RowOfDice().scale(0.5).move_to(3 * DOWN)
|
||||
self.add(self.row_of_dice)
|
||||
|
||||
self.tallies = np.zeros(6)
|
||||
self.dice_histogram = self.hist_from_tallies()
|
||||
|
||||
self.add(self.dice_histogram)
|
||||
|
||||
for i in range(30):
|
||||
self.throw_a_die()
|
||||
self.wait()
|
||||
|
||||
|
||||
|
||||
|
||||
class ShowUncertainty2(PiCreatureScene):
|
||||
|
||||
|
||||
def throw_darts(self, n, run_time = 1):
|
||||
|
||||
points = np.random.normal(
|
||||
loc = self.dartboard.get_center(),
|
||||
scale = 0.6 * np.ones(3),
|
||||
size = (n,3)
|
||||
)
|
||||
points[:,2] = 0
|
||||
dots = VGroup()
|
||||
for point in points:
|
||||
dot = Dot(point, radius = 0.04, fill_opacity = 0.7)
|
||||
dots.add(dot)
|
||||
self.add(dot)
|
||||
|
||||
self.play(
|
||||
LaggedStart(FadeIn, dots, lag_ratio = 0.01, run_time = run_time)
|
||||
)
|
||||
|
||||
|
||||
def construct(self):
|
||||
|
||||
self.dartboard = ImageMobject("dartboard").scale(2)
|
||||
dartboard_circle = Circle(
|
||||
radius = self.dartboard.get_width() / 2,
|
||||
fill_color = BLACK,
|
||||
fill_opacity = 0.5,
|
||||
stroke_color = WHITE,
|
||||
stroke_width = 5
|
||||
)
|
||||
self.dartboard.add(dartboard_circle)
|
||||
|
||||
self.add(self.dartboard)
|
||||
|
||||
self.throw_darts(5,5)
|
||||
self.throw_darts(20,5)
|
||||
self.throw_darts(100,5)
|
||||
self.throw_darts(1000,5)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class ShowUncertainty3(Scene):
|
||||
|
||||
def construct(self):
|
||||
|
||||
randy = CoinFlippingPiCreature(color = MAROON_E)
|
||||
randy.scale(0.5).to_edge(LEFT + DOWN)
|
||||
|
||||
heads = tails = 0
|
||||
tally = TallyStack(heads, tails, anchor = ORIGIN)
|
||||
|
||||
nb_flips = 10
|
||||
|
||||
flips = np.random.randint(2, size = nb_flips)
|
||||
|
||||
for i in range(nb_flips):
|
||||
|
||||
self.play(FlipCoin(randy))
|
||||
self.wait(0.5)
|
||||
|
||||
flip = flips[i]
|
||||
if flip == 0:
|
||||
heads += 1
|
||||
elif flip == 1:
|
||||
tails += 1
|
||||
else:
|
||||
raise Exception("That side does not exist on this coin")
|
||||
|
||||
new_tally = TallyStack(heads, tails, anchor = ORIGIN)
|
||||
|
||||
if tally.nb_heads == 0 and new_tally.nb_heads == 1:
|
||||
self.play(FadeIn(new_tally.heads_stack))
|
||||
elif tally.nb_tails == 0 and new_tally.nb_tails == 1:
|
||||
self.play(FadeIn(new_tally.tails_stack))
|
||||
else:
|
||||
self.play(Transform(tally, new_tally))
|
||||
|
||||
tally = new_tally
|
||||
|
||||
|
||||
|
||||
|
||||
103
active_projects/eop/chapter2.py
Normal file
103
active_projects/eop/chapter2.py
Normal file
@@ -0,0 +1,103 @@
|
||||
from big_ol_pile_of_manim_imports import *
|
||||
|
||||
def print_permutation(index_list):
|
||||
|
||||
|
||||
n = max(max(index_list), len(index_list))
|
||||
for i in range(0,n):
|
||||
if index_list[i] > n - i:
|
||||
raise Exception("Impossible indices!")
|
||||
|
||||
#print "given index list:", index_list
|
||||
perm_list = n * ["_"]
|
||||
alphabet = ["A", "B", "C", "D", "E", "F",
|
||||
"G", "H", "I", "J", "K", "L",
|
||||
"M", "N", "O", "P", "Q", "R",
|
||||
"S", "T", "U", "V", "W", "X",
|
||||
"Y", "Z"]
|
||||
free_indices = range(n)
|
||||
free_indices_p1 = range(1,n + 1)
|
||||
#print perm_list
|
||||
for i in range(n):
|
||||
findex = index_list[i] - 1
|
||||
#print "place next letter at", findex + 1, "th free place"
|
||||
tindex = free_indices[findex]
|
||||
#print "so at position", tindex + 1
|
||||
perm_list[tindex] = alphabet[i]
|
||||
free_indices.remove(tindex)
|
||||
free_indices_p1.remove(tindex + 1)
|
||||
#print "remaining free places:", free_indices_p1
|
||||
#print perm_list
|
||||
|
||||
return "".join(perm_list)
|
||||
|
||||
|
||||
class PermutationGrid(Scene):
|
||||
|
||||
def text_box(self, str):
|
||||
box = TextMobject(str).scale(0.3)
|
||||
box.add(SurroundingRectangle(box, stroke_color = DARK_GREY))
|
||||
return box
|
||||
|
||||
|
||||
def construct(self):
|
||||
|
||||
|
||||
N = 5
|
||||
|
||||
index_list = []
|
||||
perm5_box = VGroup()
|
||||
for i in range(1, N + 1):
|
||||
index_list.append(i)
|
||||
perm4_box = VGroup()
|
||||
for j in range(1, N):
|
||||
index_list.append(j)
|
||||
perm3_box = VGroup()
|
||||
for k in range(1, N - 1):
|
||||
index_list.append(k)
|
||||
perm2_box = VGroup()
|
||||
for l in range(1, N - 2):
|
||||
index_list.append(l)
|
||||
index_list.append(1)
|
||||
perm_box = self.text_box(print_permutation(index_list))
|
||||
if l > 1:
|
||||
perm_box.next_to(perm2_box[-1], DOWN, buff = 0)
|
||||
perm2_box.add(perm_box)
|
||||
index_list.pop()
|
||||
index_list.pop()
|
||||
if k > 1:
|
||||
perm2_box.next_to(perm3_box[-1], RIGHT, buff = 0.08)
|
||||
perm3_box.add(perm2_box)
|
||||
index_list.pop()
|
||||
perm3_box.add(SurroundingRectangle(perm3_box, buff = 0.12, stroke_color = LIGHT_GRAY))
|
||||
if j > 1:
|
||||
perm3_box.next_to(perm4_box[-1], DOWN, buff = 0)
|
||||
perm4_box.add(perm3_box)
|
||||
index_list.pop()
|
||||
if i > 1:
|
||||
perm4_box.next_to(perm5_box[-1], RIGHT, buff = 0.16)
|
||||
perm5_box.add(perm4_box)
|
||||
index_list.pop()
|
||||
|
||||
perm5_box.move_to(ORIGIN)
|
||||
self.add(perm5_box)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@ class Histogram(VMobject):
|
||||
"end_color" : BLUE,
|
||||
"x_scale" : 1.0,
|
||||
"y_scale" : 1.0,
|
||||
"x_labels" : "auto",
|
||||
"x_labels" : "auto", # widths, mids, auto, none, [...]
|
||||
"y_labels" : "auto", # auto, none, [...]
|
||||
"x_min" : 0
|
||||
}
|
||||
|
||||
@@ -31,18 +32,29 @@ class Histogram(VMobject):
|
||||
elif mode == "posts" and len(x_values) != len(y_values) + 1:
|
||||
raise Exception("Array lengths do not match up!")
|
||||
|
||||
# preliminaries
|
||||
self.y_values = np.array(y_values)
|
||||
|
||||
if mode == "widths":
|
||||
self.widths = x_values
|
||||
self.y_values = y_values
|
||||
self.x_values = x_values
|
||||
self.mode = mode
|
||||
self.process_values()
|
||||
|
||||
VMobject.__init__(self, **kwargs)
|
||||
|
||||
|
||||
def process_values(self):
|
||||
|
||||
# preliminaries
|
||||
self.y_values = np.array(self.y_values)
|
||||
|
||||
if self.mode == "widths":
|
||||
self.widths = self.x_values
|
||||
self.posts = np.cumsum(self.widths)
|
||||
self.posts = np.insert(self.posts, 0, 0)
|
||||
self.posts += self.x_min
|
||||
self.x_max = self.posts[-1]
|
||||
elif mode == "posts":
|
||||
self.posts = x_values
|
||||
self.widths = x_values[1:] - x_values[:-1]
|
||||
elif self.mode == "posts":
|
||||
self.posts = self.x_values
|
||||
self.widths = self.x_values[1:] - self.x_values[:-1]
|
||||
self.x_min = self.posts[0]
|
||||
self.x_max = self.posts[-1]
|
||||
else:
|
||||
@@ -57,12 +69,14 @@ class Histogram(VMobject):
|
||||
|
||||
self.y_values_scaled = self.y_scale * self.y_values
|
||||
|
||||
VMobject.__init__(self, **kwargs)
|
||||
digest_config(self, kwargs)
|
||||
|
||||
|
||||
|
||||
def generate_points(self):
|
||||
|
||||
self.process_values()
|
||||
for submob in self.submobjects:
|
||||
self.remove(submob)
|
||||
|
||||
def empty_string_array(n):
|
||||
arr = []
|
||||
for i in range(n):
|
||||
@@ -72,21 +86,33 @@ class Histogram(VMobject):
|
||||
def num_arr_to_string_arr(arr): # converts number array to string array
|
||||
ret_arr = []
|
||||
for x in arr:
|
||||
ret_arr.append(str(x))
|
||||
if x == np.floor(x):
|
||||
new_x = int(np.floor(x))
|
||||
else:
|
||||
new_x = x
|
||||
ret_arr.append(str(new_x))
|
||||
return ret_arr
|
||||
|
||||
previous_bar = ORIGIN
|
||||
self.bars = []
|
||||
self.bars = VGroup()
|
||||
self.x_labels_group = VGroup()
|
||||
self.y_labels_group = VGroup()
|
||||
outline_points = []
|
||||
|
||||
if self.x_labels == "widths":
|
||||
self.x_labels = num_arr_to_string_arr(self.widths)
|
||||
elif self.x_labels == "mids":
|
||||
print self.x_mids
|
||||
self.x_labels = num_arr_to_string_arr(self.x_mids)
|
||||
elif self.x_labels == "none":
|
||||
self.x_labels = empty_string_array(len(self.widths))
|
||||
|
||||
print self.x_labels
|
||||
if self.y_labels == "auto":
|
||||
self.y_labels = num_arr_to_string_arr(self.y_values)
|
||||
elif self.y_labels == "none":
|
||||
self.y_labels = empty_string_array(len(self.y_values))
|
||||
|
||||
|
||||
|
||||
|
||||
for (i,x) in enumerate(self.x_mids):
|
||||
|
||||
@@ -104,12 +130,15 @@ class Histogram(VMobject):
|
||||
bar.set_stroke(width = 0)
|
||||
bar.next_to(previous_bar,RIGHT,buff = 0, aligned_edge = DOWN)
|
||||
|
||||
self.add(bar)
|
||||
self.bars.append(bar)
|
||||
self.bars.add(bar)
|
||||
|
||||
label = TextMobject(self.x_labels[i])
|
||||
label.next_to(bar,DOWN)
|
||||
self.add(label)
|
||||
x_label = TextMobject(self.x_labels[i])
|
||||
x_label.next_to(bar,DOWN)
|
||||
self.x_labels_group.add(x_label)
|
||||
|
||||
y_label = TextMobject(self.y_labels[i])
|
||||
y_label.next_to(bar, UP)
|
||||
self.y_labels_group.add(y_label)
|
||||
|
||||
if i == 0:
|
||||
# start with the lower left
|
||||
@@ -128,7 +157,9 @@ class Histogram(VMobject):
|
||||
|
||||
self.outline = Polygon(*outline_points)
|
||||
self.outline.set_stroke(color = WHITE)
|
||||
self.add(self.outline)
|
||||
self.add(self.bars, self.x_labels_group, self.y_labels_group, self.outline)
|
||||
|
||||
print self.submobjects
|
||||
|
||||
def get_lower_left_point(self):
|
||||
return self.bars[0].get_anchors()[-2]
|
||||
|
||||
Reference in New Issue
Block a user