def __init__(self, eq1, eq2, regex, regex2=None, map_list=None, align_char=None): # align equations if align_char: difference_vec = \ self.mob_from_char(eq1, eq1.tex_string, align_char).get_center() - \ self.mob_from_char(eq2, eq2.tex_string, align_char).get_center() else: difference_vec = eq1.get_center() - eq2.get_center() eq2.shift(difference_vec) if regex2 is None: g1 = self.split_by_regex(eq1, regex) g2 = self.split_by_regex(eq2, regex) assert (len(g1.submobjects) == len(g2.submobjects)) trans = ReplacementTransform(g1, g2) AnimationGroup.__init__(self, trans) else: assert (map_list) g1 = self.split_by_regex(eq1, regex) g2 = self.split_by_regex(eq2, regex2) self.g1 = g1 self.g2 = g2 G1 = VGroup() G2 = VGroup() F1 = Group() F2 = Group() g1_nodes = set(pair[0] for pair in map_list) g2_nodes = set(pair[1] for pair in map_list) while map_list: l1 = [g1.submobjects[map_list[0][0]]] l2 = [g2.submobjects[map_list[0][1]]] new_list = [] for i in range(1, len(map_list)): if map_list[i][0] == map_list[0][0]: l2.append(g2.submobjects[map_list[i][1]]) elif map_list[i][1] == map_list[0][1]: l1.append(g1.submobjects[map_list[i][0]]) else: new_list.append(map_list[i]) map_list = new_list G1.submobjects.append(VGroup(*l1)) G2.submobjects.append(VGroup(*l2)) for i in range(len(g1.submobjects)): if i not in g1_nodes: F1.submobjects.append(g1.submobjects[i]) for i in range(len(g2.submobjects)): if i not in g2_nodes: F2.submobjects.append(g2.submobjects[i]) self.g1 = g1 self.g2 = g2 trans = ReplacementTransform(G1, G2) fadeout = FadeOut(F1) fadein = FadeIn(F2) AnimationGroup.__init__(self, trans, fadeout, fadein)
def __init__(self, nodes, edges, attrs=None, **kwargs): # typechecking for node in nodes: Node.assert_primitive(node) for edge in edges: Edge.assert_primitive(edge) if attrs is None: attrs = OrderedDict() # mobject init update_without_overwrite(kwargs, self.CONFIG) Group.__init__(self, **kwargs) # create submobjects self.nodes = {} self.edges = {} # create nodes for point in nodes: node_attrs = attrs.get(point, OrderedDict()) node = Node(point, **update_without_overwrite(node_attrs, kwargs)) self.nodes[node.key] = node self.add(node) # create edges for pair in edges: edge_attrs = attrs.get(pair, OrderedDict()) u, v = pair[0], pair[1] edge_attrs["curved"] = (v, u) in edges u = self.nodes[u] v = self.nodes[v] edge = Edge(u, v, **update_without_overwrite(edge_attrs, kwargs)) self.edges[edge.key] = edge self.add(edge)
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 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(FRAME_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(FRAME_HEIGHT - 1) return activation_iamges
def repeat_cursor_1(self, target_depth=-1): cursor = self.cursors[target_depth] anims = [ApplyMethod(cursor.shift, self.repeat_cursor_dist * LEFT)] # remove child cursors anims.append(Uncreate(Group(*self.cursors[target_depth + 1:]))) self.cursors = self.cursors[:target_depth + 1] self.cursor_indices = self.cursor_indices[:target_depth + 1] return anims
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(FRAME_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(FRAME_HEIGHT - 1) self.play(FadeIn(group))
def __init__(self, pi_creature, *content, **kwargs): digest_config(self, kwargs) bubble = pi_creature.get_bubble(*content, bubble_class=self.bubble_class, **self.bubble_kwargs) Group(bubble, bubble.content).shift_onto_screen() pi_creature.generate_target() pi_creature.target.change_mode(self.target_mode) if self.look_at_arg is not None: pi_creature.target.look_at(self.look_at_arg) change_mode = MoveToTarget(pi_creature, **self.change_mode_kwargs) bubble_creation = self.bubble_creation_class( bubble, **self.bubble_creation_kwargs) content_introduction = self.content_introduction_class( bubble.content, **self.content_introduction_kwargs) AnimationGroup.__init__(self, change_mode, bubble_creation, content_introduction, **kwargs)
def place_cursors(self, indices=None, block=None): """ place cursors on the blocks denoted by indices if it was passed, otherwise the blocks denoted by self.cursor_indices """ if indices is None and len(self.cursor_indices) == 0: raise Exception("no indices to use") elif indices is None: indices = self.cursor_indices if block is None: cur_block = self else: cur_block = block cursors = [] for block_idx in indices: cur_block = cur_block.submobjects[block_idx] cursor = TexMobject("\\blacktriangleright") cursor.next_to(cur_block[0], LEFT) cursors.append(cursor) self.cursors.extend(cursors) return [ShowCreation(Group(*cursors))]
class Succession(Animation): CONFIG = { "rate_func": None, } 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 = [x for x in animations if not (x.empty)] 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 = [ np.true_divide(x, run_time) for x in 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 # If self.num_anims == 0, this is an invalid index, but so it goes self.current_anim_index = 0 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) # Beware: This does NOT take care of calling update(0) on the subanimation. # This was important to avoid a pernicious possibility in which subanimations were called # with update twice, which could in turn call a sub-Succession with update four times, # continuing exponentially. def jump_to_start_of_anim(self, index): if index != self.current_anim_index: # Should probably have a cleaner "remove_all" method... self.mobject.remove(*self.mobject.submobjects) self.mobject.add(*self.scene_mobjects_at_time[index].submobjects) self.mobject.add(self.animations[index].mobject) for i in range(index): self.animations[i].update(1) self.current_anim_index = index self.current_alpha = self.critical_alphas[index] def update_mobject(self, alpha): if self.num_anims == 0: # This probably doesn't matter for anything, but just in case, # we want it in the future, we set current_alpha even in this case self.current_alpha = alpha return gt_alpha_iter = iter( filter(lambda i: self.critical_alphas[i + 1] >= alpha, range(self.num_anims))) i = next(gt_alpha_iter, None) if i is None: # In this case, we assume what is happening is that alpha is 1.0, # but that rounding error is causing us to overshoot the end of # self.critical_alphas (which is also 1.0) if not abs(alpha - 1) < 0.001: warnings.warn( "Rounding error not near alpha=1 in Succession.update_mobject," + "instead alpha = %f" % alpha) print(self.critical_alphas, alpha) i = self.num_anims - 1 # At this point, we should have self.critical_alphas[i] <= alpha <= self.critical_alphas[i +1] self.jump_to_start_of_anim(i) sub_alpha = inverse_interpolate(self.critical_alphas[i], self.critical_alphas[i + 1], alpha) self.animations[i].update(sub_alpha) self.current_alpha = alpha def clean_up(self, *args, **kwargs): # We clean up as though we've played ALL animations, even if # clean_up is called in middle of things for anim in self.animations: anim.clean_up(*args, **kwargs)
class Succession(Animation): CONFIG = { "rate_func": None, } 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 # If self.num_anims == 0, this is an invalid index, but so it goes self.current_anim_index = 0 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) # Beware: This does NOT take care of calling update(0) on the subanimation. # This was important to avoid a pernicious possibility in which subanimations were called # with update twice, which could in turn call a sub-Succession with update four times, # continuing exponentially. def jump_to_start_of_anim(self, index): if index != self.current_anim_index: # Should probably have a cleaner "remove_all" method... self.mobject.remove(*self.mobject.submobjects) self.mobject.add(*self.scene_mobjects_at_time[index].submobjects) self.mobject.add(self.animations[index].mobject) for i in range(index): self.animations[i].update(1) self.current_anim_index = index self.current_alpha = self.critical_alphas[index] def update_mobject(self, alpha): if self.num_anims == 0: # This probably doesn't matter for anything, but just in case, # we want it in the future, we set current_alpha even in this case self.current_alpha = alpha return gt_alpha_iter = it.ifilter( lambda i: self.critical_alphas[i + 1] >= alpha, range(self.num_anims) ) i = next(gt_alpha_iter, None) if i is None: # In this case, we assume what is happening is that alpha is 1.0, # but that rounding error is causing us to overshoot the end of # self.critical_alphas (which is also 1.0) if not abs(alpha - 1) < 0.001: warnings.warn( "Rounding error not near alpha=1 in Succession.update_mobject," + "instead alpha = %f" % alpha ) print self.critical_alphas, alpha i = self.num_anims - 1 # At this point, we should have self.critical_alphas[i] <= alpha <= self.critical_alphas[i +1] self.jump_to_start_of_anim(i) sub_alpha = inverse_interpolate( self.critical_alphas[i], self.critical_alphas[i + 1], alpha ) self.animations[i].update(sub_alpha) self.current_alpha = alpha def clean_up(self, *args, **kwargs): # We clean up as though we've played ALL animations, even if # clean_up is called in middle of things for anim in self.animations: anim.clean_up(*args, **kwargs)
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): """ 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 # If self.num_anims == 0, this is an invalid index, but so it goes self.current_anim_index = 0 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 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 __init__(self, *args, **kwargs): return Animation.__init__(self, Group(), *args, **kwargs)
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(FRAME_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 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 = [x for x in animations if not (x.empty)] 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 = [ np.true_divide(x, run_time) for x in 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 # If self.num_anims == 0, this is an invalid index, but so it goes self.current_anim_index = 0 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)