def __init__(self, *mobjects, **kwargs): start = Group(*mobjects) target = Group(*[ m1.copy().move_to(m2) for m1, m2 in adjacent_pairs(start) ]) Transform.__init__(self, start, target, **kwargs)
def apple_pile(): bottom_row = [Apple(i).rotate(random_small_angle()) for i in xrange(3)] top_row = [Apple(3).rotate(-np.pi / 20), Apple(4).rotate(np.pi / 20)] Group(*bottom_row).arrange_submobjects(buff=0.1) Group(*top_row).arrange_submobjects(buff=0.1) Group(*top_row).next_to(Group(*bottom_row), direction=UP, buff=0) return Group(*(bottom_row + top_row))
def pear_pile(): bottom_two = [Pear(i).rotate(random_small_angle()) for i in xrange(2)] Group(*bottom_two).arrange_submobjects(buff=0.1) third_on_bottom = Pear(2).next_to(Group(*bottom_two), buff=0.1) top = (Pear(3)).rotate(-np.pi / 20).next_to(Group(*bottom_two), direction=UP, buff=0) return Group(*(bottom_two + [third_on_bottom, top]))
def show_random_results(self): group = Group(*[ Group(*[ MNistMobject(a) for a in network.get_activation_of_all_layers( np.random.randn(784, 1)) ]).arrange_submobjects(RIGHT) for x in range(10) ]).arrange_submobjects(DOWN) group.scale_to_fit_height(2 * SPACE_HEIGHT - 1) self.add(group)
def get_activation_images(self, digit, network, test_data, n_examples=8): input_vectors = [data[0] for data in test_data if data[1] == digit] activation_iamges = Group(*[ Group(*[ MNistMobject(a) for a in network.get_activation_of_all_layers(vect) ]).arrange_submobjects(RIGHT) for vect in input_vectors[:n_examples] ]).arrange_submobjects(DOWN) activation_iamges.scale_to_fit_height(2 * SPACE_HEIGHT - 1) return activation_iamges
def show_maximizing_inputs(self, network): training_data, validation_data, test_data = load_data_wrapper() layer = 1 n_neurons = DEFAULT_LAYER_SIZES[layer] groups = Group() for k in range(n_neurons): out = np.zeros(n_neurons) out[k] = 1 in_vect = maximizing_input(network, layer, out) new_out = network.get_activation_of_all_layers(in_vect)[layer] group = Group(*map(MNistMobject, [in_vect, new_out])) group.arrange_submobjects(DOWN+RIGHT, SMALL_BUFF) groups.add(group) groups.arrange_submobjects_in_grid() groups.scale_to_fit_height(2*SPACE_HEIGHT - 1) self.add(groups)
def __init__(self, *args, **kwargs): """ Each arg will either be an animation, or an animation class followed by its arguments (and potentially a dict for configuraiton). For example, Succession( ShowCreation(circle), Transform, circle, square, Transform, circle, triangle, ApplyMethod, circle.shift, 2*UP, {"run_time" : 2}, ) """ animations = [] state = { "animations" : animations, "curr_class" : None, "curr_class_args" : [], "curr_class_config" : {}, } def invoke_curr_class(state): if state["curr_class"] is None: return anim = state["curr_class"]( *state["curr_class_args"], **state["curr_class_config"] ) state["animations"].append(anim) anim.update(1) state["curr_class"] = None state["curr_class_args"] = [] state["curr_class_config"] = {} for arg in args: if isinstance(arg, Animation): animations.append(arg) arg.update(1) invoke_curr_class(state) elif isinstance(arg, type) and issubclass(arg, Animation): invoke_curr_class(state) state["curr_class"] = arg elif isinstance(arg, dict): state["curr_class_config"] = arg else: state["curr_class_args"].append(arg) invoke_curr_class(state) for anim in animations: anim.update(0) self.run_times = [anim.run_time for anim in animations] if "run_time" in kwargs: run_time = kwargs.pop("run_time") else: run_time = sum(self.run_times) self.num_anims = len(animations) self.animations = animations mobject = Group(*[anim.mobject for anim in self.animations]) Animation.__init__(self, mobject, run_time = run_time, **kwargs)
def show_all_activation_images(self, network, test_data): image_samples = Group(*[ self.get_activation_images(digit, network, test_data) for digit in range(10) ]) image_samples.arrange_submobjects_in_grid(n_rows=2, buff=LARGE_BUFF) image_samples.scale_to_fit_height(2 * SPACE_HEIGHT - 1) self.add(image_samples)
def show_test_input(self, network): training_data, validation_data, test_data = load_data_wrapper() group = Group(*[ self.get_set(network, test) for test in test_data[3:20] if test[1] in [4, 9] ]) group.arrange_submobjects(DOWN, buff=MED_LARGE_BUFF) group.scale_to_fit_height(2 * SPACE_HEIGHT - 1) self.play(FadeIn(group))
def attempt(i0, i1, i2, remove=True): apple_indices = i0, i1, i2 matching = get_matching( pears, Group(*(apples.submobjects[-1 - i] for i in apple_indices))) self.play(ShowCreation(matching), submobject_mode="all_at_once") #self.dither() if remove: self.remove(matching) else: return matching
def get_examples(self): ci = self.curr_index self.curr_index += self.n_examples group = Group( *it.starmap(get_training_image_group, self.data[ci:ci + self.n_examples])) group.arrange_submobjects(DOWN) group.scale(0.5) return group
def get_training_image_group(train_in, train_out): image = MNistMobject(train_in) image.scale_to_fit_height(1) arrow = Vector(RIGHT, color=BLUE, buff=0) output = np.argmax(train_out) output_tex = TexMobject(str(output)).scale(1.5) result = Group(image, arrow, output_tex) result.arrange_submobjects(RIGHT) result.to_edge(UP) return result
def number_submobjects(mobj, direction): zero = TexMobject("0") zero.next_to(mobj.submobjects[0], direction=direction) submobjs = [zero] for i in xrange(1, len(mobj.submobjects)): submobj = TexMobject(str(i)) submobj.next_to(submobjs[-1]) submobj.shift( (mobj.submobjects[i].get_center()[0] - submobj.get_center()[0], 0, 0)) submobjs.append(submobj) return Group(*submobjs)
def construct(self): self.numbers = Group(*(self.number_tex(i) for i in xrange(15))) self.number_text = TextMobject("Natural Numbers").to_edge(UP) self.play(ShowCreation(self.numbers), Write(self.number_text)) #self.show_matching(lambda n: 2*n, "Even", gradual_creation = True) self.show_matching(lambda n: 2 * n, "Even") self.dither() self.show_matching(lambda n: n**2, "Square") self.dither() small_primes = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113 ] self.show_matching(small_primes, "Prime")
def __init__(self, *continual_animations, **kwargs): digest_config(self, kwargs, locals()) self.group = Group(*[ca.mobject for ca in continual_animations]) ContinualAnimation.__init__(self, self.group, **kwargs)
def __init__(self, *args, **kwargs): return Animation.__init__(self, Group(), *args, **kwargs)
def __init__(self, *args, **kwargs): """ Each arg will either be an animation, or an animation class followed by its arguments (and potentially a dict for configuration). For example, Succession( ShowCreation(circle), Transform, circle, square, Transform, circle, triangle, ApplyMethod, circle.shift, 2*UP, {"run_time" : 2}, ) """ animations = [] state = { "animations": animations, "curr_class": None, "curr_class_args": [], "curr_class_config": {}, } def invoke_curr_class(state): if state["curr_class"] is None: return anim = state["curr_class"](*state["curr_class_args"], **state["curr_class_config"]) state["animations"].append(anim) anim.update(1) state["curr_class"] = None state["curr_class_args"] = [] state["curr_class_config"] = {} for arg in args: if isinstance(arg, Animation): animations.append(arg) arg.update(1) invoke_curr_class(state) elif isinstance(arg, type) and issubclass(arg, Animation): invoke_curr_class(state) state["curr_class"] = arg elif isinstance(arg, dict): state["curr_class_config"] = arg else: state["curr_class_args"].append(arg) invoke_curr_class(state) for anim in animations: anim.update(0) animations = filter(lambda x: not (x.empty), animations) self.run_times = [anim.run_time for anim in animations] if "run_time" in kwargs: run_time = kwargs.pop("run_time") warnings.warn( "Succession doesn't currently support explicit run_time.") run_time = sum(self.run_times) self.num_anims = len(animations) if self.num_anims == 0: self.empty = True self.animations = animations #Have to keep track of this run_time, because Scene.play #might very well mess with it. self.original_run_time = run_time # critical_alphas[i] is the start alpha of self.animations[i] # critical_alphas[i + 1] is the end alpha of self.animations[i] critical_times = np.concatenate(([0], np.cumsum(self.run_times))) self.critical_alphas = map( lambda x: np.true_divide(x, run_time), critical_times) if self.num_anims > 0 else [0.0] # self.scene_mobjects_at_time[i] is the scene's mobjects at start of self.animations[i] # self.scene_mobjects_at_time[i + 1] is the scene mobjects at end of self.animations[i] self.scene_mobjects_at_time = [None for i in range(self.num_anims + 1)] self.scene_mobjects_at_time[0] = Group() for i in range(self.num_anims): self.scene_mobjects_at_time[ i + 1] = self.scene_mobjects_at_time[i].copy() self.animations[i].clean_up(self.scene_mobjects_at_time[i + 1]) self.current_alpha = 0 self.current_anim_index = 0 # If self.num_anims == 0, this is an invalid index, but so it goes if self.num_anims > 0: self.mobject = self.scene_mobjects_at_time[0] self.mobject.add(self.animations[0].mobject) else: self.mobject = Group() Animation.__init__(self, self.mobject, run_time=run_time, **kwargs)
def __init__(self, *args, **kwargs): """ Each arg will either be an animation, or an animation class followed by its arguments (and potentially a dict for configuration). For example, Succession( ShowCreation(circle), Transform, circle, square, Transform, circle, triangle, ApplyMethod, circle.shift, 2*UP, {"run_time" : 2}, ) """ animations = [] state = { "animations": animations, "curr_class": None, "curr_class_args": [], "curr_class_config": {}, } def invoke_curr_class(state): if state["curr_class"] is None: return anim = state["curr_class"](*state["curr_class_args"], **state["curr_class_config"]) state["animations"].append(anim) anim.update(1) state["curr_class"] = None state["curr_class_args"] = [] state["curr_class_config"] = {} for arg in args: if isinstance(arg, Animation): animations.append(arg) arg.update(1) invoke_curr_class(state) elif isinstance(arg, type) and issubclass(arg, Animation): invoke_curr_class(state) state["curr_class"] = arg elif isinstance(arg, dict): state["curr_class_config"] = arg else: state["curr_class_args"].append(arg) invoke_curr_class(state) for anim in animations: anim.update(0) self.run_times = [anim.run_time for anim in animations] if "run_time" in kwargs: run_time = kwargs.pop("run_time") else: run_time = sum(self.run_times) self.num_anims = len(animations) self.animations = animations self.last_index = 0 #Have to keep track of this run_time, because Scene.play #might very well mess with it. self.original_run_time = run_time # critical_alphas[i] is the start alpha of self.animations[i] # critical_alphas[i + 1] is the end alpha of self.animations[i] critical_times = np.concatenate(([0], np.cumsum(self.run_times))) self.critical_alphas = map(lambda x: np.true_divide(x, run_time), critical_times) mobject = Group(*[anim.mobject for anim in self.animations]) Animation.__init__(self, mobject, run_time=run_time, **kwargs)
def summarize(self): central_number = self.numbers[-1].copy() central_number.shift( Group(*self.numbers).get_center() - central_number.get_center()) return AnimationGroup(*([FadeOut(i) for i in self.numbers[:-1]] + [Transform(self.numbers[-1], central_number)]))
def get_set(self, network, test): test_in, test_out = test activations = network.get_activation_of_all_layers(test_in) group = Group(*map(MNistMobject, activations)) group.arrange_submobjects(RIGHT, buff = LARGE_BUFF) return group
def construct(self): apples = apple_pile().center() pears = pear_pile().center().next_to(apples, direction=DOWN) Group(apples, pears).center() # Display the two lines of apples and pears self.play( Succession(*map(GrowFromCenterGeneral, apples.submobjects), rate_func=None, run_time=1.5 * DEFAULT_ANIMATION_RUN_TIME)) self.play( Succession(*map(GrowFromCenterGeneral, pears.submobjects), rate_func=None, run_time=1.5 * DEFAULT_ANIMATION_RUN_TIME)) self.dither() counted_apples = [Apple(i) for i in xrange(5)] counted_pears = [Pear(i) for i in xrange(4)] counted_apple_group = Group( *counted_apples).arrange_submobjects().to_edge(UP) counted_pear_group = Group( *counted_pears).arrange_submobjects().to_edge(DOWN) apple_count = CountTransform(apples, counted_apple_group, direction=DOWN) apple_count.play(self) pear_count = CountTransform(pears, counted_pear_group, direction=UP) pear_count.play(self) self.play(apple_count.summarize(), pear_count.summarize()) inequality = TexMobject(apple_count.numbers[-1].args[0], ">", pear_count.numbers[-1].args[0]).center() self.play( Transform( apple_count.numbers[-1], inequality.get_part_by_tex(apple_count.numbers[-1].args[0])), Write(inequality.get_part_by_tex(">")), Transform( pear_count.numbers[-1], inequality.get_part_by_tex(pear_count.numbers[-1].args[0]))) self.dither() self.play(*map( FadeOut, [apple_count.numbers[-1], inequality, pear_count.numbers[-1]])) # Show a matching matching = MatchingAnimations(Group(*apples), Group(*pears)) for anims in matching.match_animations: self.play(anims) self.play(Transform(apples[-1], apples[-1].copy().center().to_edge(UP))) self.play(FocusOn2(apples[-1], highlight_color=WHITE)) buff = matching.buff matching = matching.matching for i in range(2): apples.submobjects.sort(key=lambda apple: apple.get_center()[0]) apples_target = apples.copy() apples_target.arrange_submobjects(center=False, buff=buff) apples_target.shift(LEFT * apples_target.get_center()[0]) self.play(Uncreate(matching)) self.play(Transform(apples, apples_target)) #self.dither() # Permute them apple_permutations = permute_animations(apples, move="up") pear_permutations = permute_animations(pears, move="down") self.play(*(apple_permutations + pear_permutations)) # Show a different matching permuted_apples = permute(apples) permuted_pears = permute(pears) if i == 1: permuted_apples[0], permuted_apples[-1] = permuted_apples[ -1], permuted_apples[0] matching = get_matching(Group(*permuted_pears), Group(*permuted_apples)) self.play(ShowCreation(matching)) #self.dither() self.play( Transform(permuted_apples[-1], permuted_apples[-1].copy().center().to_edge(UP))) self.play(FocusOn2(permuted_apples[-1], highlight_color=WHITE)) self.dither()
def construct(self): #self.force_skipping() self.fruit_num = 101 apples = Group(*(Apple() for _ in xrange(self.fruit_num))) apples.arrange_submobjects(buff=0.5) apples.to_edge(LEFT, buff=2.5) pears = Group(*(Pear() for _ in xrange(self.fruit_num))) for apple, pear in zip(apples, pears): pear.move_to(apple) apples.shift(1.5 * UP) pears.shift(1.5 * DOWN) apple_numbers = number_submobjects(apples, direction=UP) pear_numbers = number_submobjects(pears, direction=DOWN) self.play(ShowCreation(apples), Write(apple_numbers)) self.play(ShowCreation(pears), Write(pear_numbers)) #self.dither() apples.submobjects.reverse() pears.submobjects.reverse() apple_numbers.submobjects.reverse() pear_numbers.submobjects.reverse() apples_ori = apples.copy() pears_ori = pears.copy() apple_numbers_ori = apple_numbers.copy() pear_numbers_ori = pear_numbers.copy() apples_persp = apples.copy() pears_persp = pears.copy() apple_numbers_persp = apple_numbers.copy() pear_numbers_persp = pear_numbers.copy() self.camera_distance = 12.0 self.camera_point = apples[-1].get_center() * X_MASK vanishing_point = self.camera_point + self.camera_distance * RIGHT self.darken(apples_persp) self.darken(pears_persp) self.darken(apple_numbers_persp) self.darken(pear_numbers_persp) # perspective shift of numbers self.apply_perspective(apples_persp, objectwise=True) self.apply_perspective(pears_persp, objectwise=True) self.apply_perspective(apple_numbers_persp, objectwise=False) self.apply_perspective(pear_numbers_persp, objectwise=False) self.play( ReplacementTransform(apples, apples_persp), ReplacementTransform(pears, pears_persp), ReplacementTransform(apple_numbers, apple_numbers_persp), ReplacementTransform(pear_numbers, pear_numbers_persp), ) apples = apples_persp pears = pears_persp apple_numbers = apple_numbers_persp pear_numbers = pear_numbers_persp #self.dither() matching = make_ordinal_matching( Ordinal(*apples[1:]), Ordinal(*pears[1:]), ) self.darken(matching) self.play(ShowCreation(matching)) self.dither() matching_straight = matching.copy() # Extra apple self.show_extra_fruit(apples, apples_ori, apple_numbers, apple_numbers_ori, matching, apples[:-1], pears[1:], matching_straight) # Extra pear self.show_extra_fruit(pears, pears_ori, pear_numbers, pear_numbers_ori, matching, apples[1:], pears[:-1], matching_straight) self.dither() self.play(Transform(matching, matching_straight)) definition = TextMobject("Definition:", "$|A| = |B|$") definition.to_edge(UP) self.play(Write(definition[0])) apple_box, apple_label = self.pack_into_box(apples, apple_numbers, UP, 'A', RED, matching, apples, pears) #self.dither() pear_box, pear_label = self.pack_into_box(pears, pear_numbers, DOWN, 'B', YELLOW, matching, apples, pears) #self.dither() self.move_labels_to_definition(apple_label, pear_label, definition[1]) finite_pears = VGroup(*pears_ori[-3:]) finite_pears.move_to(pear_box) pears_dest = VGroup(*[pears[0].copy() for _ in range(len(pears) - 3)]) pears_dest.fade(0) pears_dest.add(*finite_pears.submobjects) self.play( Uncreate(matching), FadeOut(definition[1]), ) self.play(Transform(pears, pears_dest), ) self.remove(pears) self.add(finite_pears) finite_pears.submobjects.reverse() pears = finite_pears #self.dither() def attempt(i0, i1, i2, remove=True): apple_indices = i0, i1, i2 matching = get_matching( pears, Group(*(apples.submobjects[-1 - i] for i in apple_indices))) self.play(ShowCreation(matching), submobject_mode="all_at_once") #self.dither() if remove: self.remove(matching) else: return matching attempt(5, 8, 12) attempt(0, 10, 19) matching = attempt(7, 1, 0, remove=False) def2 = TextMobject(":", "$|A|>|B|$") def2.shift(definition[0][-1].get_center() - def2[0].get_center()) self.move_labels_to_definition(apple_label, pear_label, def2[1]) self.dither()