def get_subdivision_braces_and_labels( self, parts, labels, direction, buff=SMALL_BUFF, min_num_quads=1 ): label_mobs = VGroup() braces = VGroup() for label, part in zip(labels, parts): brace = Brace( part, direction, min_num_quads=min_num_quads, buff=buff ) if isinstance(label, Mobject): label_mob = label else: label_mob = Tex(label) label_mob.scale(self.default_label_scale_val) label_mob.next_to(brace, direction, buff) braces.add(brace) label_mobs.add(label_mob) parts.braces = braces parts.labels = label_mobs parts.label_kwargs = { "labels": label_mobs.copy(), "direction": direction, "buff": buff, } return VGroup(parts.braces, parts.labels)
def get_graph_label(self, graph, label="f(x)", x=None, direction=RIGHT, buff=MED_SMALL_BUFF, color=None): if isinstance(label, str): label = Tex(label) if color is None: label.match_color(graph) if x is None: # Searching from the right, find a point # whose y value is in bounds max_y = FRAME_Y_RADIUS - label.get_height() max_x = FRAME_X_RADIUS - label.get_width() for x0 in np.arange(*self.x_range)[::-1]: pt = self.i2gp(x0, graph) if abs(pt[0]) < max_x and abs(pt[1]) < max_y: x = x0 break if x is None: x = self.x_range[1] point = self.input_to_graph_point(x, graph) angle = self.angle_of_tangent(x, graph) normal = rotate_vector(RIGHT, angle + 90 * DEGREES) if normal[1] < 0: normal *= -1 label.next_to(point, normal, buff=buff) label.shift_onto_screen() return label
def add_axes(self): x_axis = Line(self.tick_width * LEFT / 2, self.width * RIGHT) y_axis = Line(MED_LARGE_BUFF * DOWN, self.height * UP) ticks = VGroup() heights = np.linspace(0, self.height, self.n_ticks + 1) values = np.linspace(0, self.max_value, self.n_ticks + 1) for y, value in zip(heights, values): tick = Line(LEFT, RIGHT) tick.set_width(self.tick_width) tick.move_to(y * UP) ticks.add(tick) y_axis.add(ticks) self.add(x_axis, y_axis) self.x_axis, self.y_axis = x_axis, y_axis if self.label_y_axis: labels = VGroup() for tick, value in zip(ticks, values): label = Tex(str(np.round(value, 2))) label.set_height(self.y_axis_label_height) label.next_to(tick, LEFT, SMALL_BUFF) labels.add(label) self.y_axis_labels = labels self.add(labels)
def add_T_label(self, x_val, side=RIGHT, label=None, color=WHITE, animated=False, **kwargs): triangle = RegularPolygon(n=3, start_angle=np.pi / 2) triangle.set_height(MED_SMALL_BUFF) triangle.move_to(self.coords_to_point(x_val, 0), UP) triangle.set_fill(color, 1) triangle.set_stroke(width=0) if label is None: T_label = Tex(self.variable_point_label, fill_color=color) else: T_label = Tex(label, fill_color=color) T_label.next_to(triangle, DOWN) v_line = self.get_vertical_line_to_graph(x_val, self.v_graph, color=YELLOW) if animated: self.play(DrawBorderThenFill(triangle), ShowCreation(v_line), Write(T_label, run_time=1), **kwargs) if np.all(side == LEFT): self.left_T_label_group = VGroup(T_label, triangle) self.left_v_line = v_line self.add(self.left_T_label_group, self.left_v_line) elif np.all(side == RIGHT): self.right_T_label_group = VGroup(T_label, triangle) self.right_v_line = v_line self.add(self.right_T_label_group, self.right_v_line)
def get_vector_label(self, vector, label, at_tip=False, direction="left", rotate=False, color=None, label_scale_factor=VECTOR_LABEL_SCALE_FACTOR): if not isinstance(label, Tex): if len(label) == 1: label = "\\vec{\\textbf{%s}}" % label label = Tex(label) if color is None: color = vector.get_color() label.set_color(color) label.scale(label_scale_factor) label.add_background_rectangle() if at_tip: vect = vector.get_vector() vect /= get_norm(vect) label.next_to(vector.get_end(), vect, buff=SMALL_BUFF) else: angle = vector.get_angle() if not rotate: label.rotate(-angle, about_point=ORIGIN) if direction == "left": label.shift(-label.get_bottom() + 0.1 * UP) else: label.shift(-label.get_top() + 0.1 * DOWN) label.rotate(angle, about_point=ORIGIN) label.shift((vector.get_end() - vector.get_start()) / 2) return label
def get_det_text( matrix: Matrix, determinant: int | str | None = None, background_rect: bool = False, initial_scale_factor: int = 2 ) -> VGroup: parens = Tex("(", ")") parens.scale(initial_scale_factor) parens.stretch_to_fit_height(matrix.get_height()) l_paren, r_paren = parens.split() l_paren.next_to(matrix, LEFT, buff=0.1) r_paren.next_to(matrix, RIGHT, buff=0.1) det = TexText("det") det.scale(initial_scale_factor) det.next_to(l_paren, LEFT, buff=0.1) if background_rect: det.add_background_rectangle() det_text = VGroup(det, l_paren, r_paren) if determinant is not None: eq = Tex("=") eq.next_to(r_paren, RIGHT, buff=0.1) result = Tex(str(determinant)) result.next_to(eq, RIGHT, buff=0.2) det_text.add(eq, result) return det_text
def get_axis_label(self, label_tex, axis, edge, direction, buff=MED_SMALL_BUFF): label = Tex(label_tex) label.next_to( axis.get_edge_center(edge), direction, buff=buff ) label.shift_onto_screen(buff=MED_SMALL_BUFF) return label
def get_axis_label(self, label_tex: str, axis: np.ndarray, edge: np.ndarray, direction: np.ndarray, buff: float = MED_SMALL_BUFF) -> Tex: label = Tex(label_tex) label.next_to(axis.get_edge_center(edge), direction, buff=buff) label.shift_onto_screen(buff=MED_SMALL_BUFF) return label
def get_number_mob(self, num): result = VGroup() place = 0 max_place = self.max_place while place < max_place: digit = Tex(str(self.get_place_num(num, place))) if place >= len(self.digit_place_colors): self.digit_place_colors += self.digit_place_colors digit.set_color(self.digit_place_colors[place]) digit.scale(self.num_scale_factor) digit.next_to(result, LEFT, buff=SMALL_BUFF, aligned_edge=DOWN) result.add(digit) place += 1 return result
def add_axes(self) -> None: x_axis = Line(self.tick_width * LEFT / 2, self.width * RIGHT) y_axis = Line(MED_LARGE_BUFF * DOWN, self.height * UP) y_ticks = VGroup() heights = np.linspace(0, self.height, self.n_ticks + 1) values = np.linspace(0, self.max_value, self.n_ticks + 1) for y, value in zip(heights, values): y_tick = Line(LEFT, RIGHT) y_tick.set_width(self.tick_width) y_tick.move_to(y * UP) y_ticks.add(y_tick) y_axis.add(y_ticks) if self.include_x_ticks == True: x_ticks = VGroup() widths = np.linspace(0, self.width, self.n_ticks_x + 1) label_values = np.linspace(0, len(self.bar_names), self.n_ticks_x + 1) for x, value in zip(widths, label_values): x_tick = Line(UP, DOWN) x_tick.set_height(self.tick_height) x_tick.move_to(x * RIGHT) x_ticks.add(x_tick) x_axis.add(x_ticks) self.add(x_axis, y_axis) self.x_axis, self.y_axis = x_axis, y_axis if self.label_y_axis: labels = VGroup() for y_tick, value in zip(y_ticks, values): label = Tex(str(np.round(value, 2))) label.set_height(self.y_axis_label_height) label.next_to(y_tick, LEFT, SMALL_BUFF) labels.add(label) self.y_axis_labels = labels self.add(labels)
def add_bars(self, values): buff = float(self.width) / (2 * len(values) + 1) bars = VGroup() for i, value in enumerate(values): bar = Rectangle( height=(value / self.max_value) * self.height, width=buff, stroke_width=self.bar_stroke_width, fill_opacity=self.bar_fill_opacity, ) bar.move_to((2 * i + 1) * buff * RIGHT, DOWN + LEFT) bars.add(bar) bars.set_color_by_gradient(*self.bar_colors) bar_labels = VGroup() for bar, name in zip(bars, self.bar_names): label = Tex(str(name)) label.scale(self.bar_label_scale_val) label.next_to(bar, DOWN, SMALL_BUFF) bar_labels.add(label) self.add(bars, bar_labels) self.bars = bars self.bar_labels = bar_labels
def get_graph_label( self, graph, label="f(x)", x_val=None, direction=RIGHT, buff=MED_SMALL_BUFF, color=None, ): label = Tex(label) color = color or graph.get_color() label.set_color(color) if x_val is None: # Search from right to left for x in np.linspace(self.x_max, self.x_min, 100): point = self.input_to_graph_point(x, graph) if point[1] < FRAME_Y_RADIUS: break x_val = x label.next_to(self.input_to_graph_point(x_val, graph), direction, buff=buff) label.shift_onto_screen() return label
def construct(self): r=0.3 fc = ORANGE oc = RED bd = RED_C wc = BLUE yc = RED_D offset = np.array([-4,-1,0]) h1 = Circle(fill_color=fc, fill_opacity=2, arc_center=offset+np.array([0,3,0]), radius=r) h2 = Circle(fill_color=fc, fill_opacity=2, arc_center=offset+np.array([0,1,0]), radius=r) h3 = Circle(fill_color=fc, fill_opacity=2, arc_center=offset+np.array([0,-1,0]), radius=r) o1 = Circle(fill_color=oc, color=bd, fill_opacity=2, arc_center=offset+np.array([5,1,0]), radius=r) arrow1 = Arrow(LEFT, RIGHT) arrow2 = Arrow(LEFT, RIGHT) arrow3 = Arrow(LEFT, RIGHT) arrow1.next_to(h1, LEFT) arrow2.next_to(h2, LEFT) arrow3.next_to(h3, LEFT) t1 = Tex("x_1") t1.next_to(arrow1, UP) t2 = Tex("x_2") t2.next_to(arrow2, UP) t3 = Tex("x_3") t3.next_to(arrow3, UP) arrow4 = Arrow(h1, o1) arrow5 = Arrow(h2, o1) arrow6 = Arrow(h3, o1) arrow7 = Arrow(LEFT, RIGHT,color=MAROON_C).next_to(o1, RIGHT) script = ' \hat y = x1*w1 + x2*w2 + x3*w3' t7 = VGroup(Tex("\hat y = x_1\cdot w_1",color=MAROON_C), Tex("+x_2\cdot w_2",color=MAROON_C), Tex("+x_3\cdot w_3",color=MAROON_C) ).arrange(DOWN,aligned_edge=RIGHT).next_to(arrow7,UP) error = Tex('E = ').next_to(arrow7, RIGHT) erreq = Tex('\\frac{1}{2}(\hat y-y)^2').next_to(error, RIGHT).scale(0.8) derr = Tex('\\frac{\delta E}{\delta \hat y} = (\hat y - y)').next_to(error, DOWN).scale(0.8).shift(RIGHT) dyw = Tex('\\frac{\delta \hat y}{\delta w_i} = x_i').next_to(derr, DOWN).scale(0.8) dEw = Tex('\\frac{\delta E}{\delta w_i} = (\hat y - y) \cdot x_i') dEw.bg = SurroundingRectangle(dEw, color=YELLOW, fill_color=RED, fill_opacity=.22) dEw_group = VGroup(dEw, dEw.bg).to_corner(DOWN*0.3+RIGHT/8).scale(0.8) barrows = [ Arrow(o1,h1).shift(UP*0.25).set_color(YELLOW_C), Arrow(o1,h2).shift(UP*0.25).set_color(YELLOW_C), Arrow(o1,h3).shift(DOWN*0.25).set_color(YELLOW_C), ] barrow_labels = [Tex("\delta w_%d"%(i+1),color=YELLOW_C).next_to(barrows[i],UP).shift(DOWN*0.25) for i in range(len(barrows)-1)] barrow_labels.append(Tex("\delta w_%d"%(len(barrows)),color=YELLOW_C).next_to(barrows[len(barrows)-1],DOWN).shift(UP*0.25)) barrow_updates = [Tex("w_%d-\eta \cdot \\frac{\delta E}{\delta w_%d}"%(i+1,i+1),color=YELLOW_C).next_to(barrows[i],UP).shift(DOWN*0.25).scale(0.8) for i in range(len(barrows)-1)] barrow_updates.append(Tex("w_%d-\eta \cdot \\frac{\delta E}{\delta w_%d}"%(len(barrows),len(barrows)),color=YELLOW_C).next_to(barrows[len(barrows)-1],DOWN).shift(UP*0.9).scale(0.8)) barrow_updates[1].shift(LEFT*1.3) #for k in COLOR_MAP: # print(k) # s=Square(color=globals()[k],stroke_width=23) # s.set_fill(globals()[k]) # self.play(FadeIn(s)) self.add(h1,h2,h3) self.add(arrow1,t1) self.add(arrow2,t2) self.add(arrow3,t3) self.add(o1) self.add(arrow4, arrow5, arrow6) self.add(arrow7, t7) self.play(Write(error), Write(erreq)) self.play(Write(derr)) self.play(Write(dyw)) self.play(Write(dEw_group)) for b,bl in zip(barrows,barrow_labels): self.play(GrowArrow(b)) self.play(Write(bl)) for bl, bl2 in zip(barrow_labels, barrow_updates): self.play(Transform(bl,bl2)) self.wait(1)