def make_axes(self, y, label): axes = Axes(x_min=0, x_max=9.5, y_min=-y, y_max=y, number_line_config={ "color": Color("black"), "include_ticks": False }) label = axes.get_y_axis_label(label_tex=label, direction=DL).set_color(Color("black")) return VGroup(axes, label)
def make_axes(self): self.axes = Axes(x_min=-self.axes_scale * FRAME_X_RADIUS, x_max=self.axes_scale * FRAME_X_RADIUS, y_min=-self.axes_scale * FRAME_Y_RADIUS, y_max=self.axes_scale * FRAME_Y_RADIUS, x_axis_config={"include_ticks": False}, y_axis_config={"include_ticks": False}, number_line_config={"color": self.axes_color}) self.axes_labels = self.axes.get_axis_labels( x_label_tex="E_x", y_label_tex="E_y").set_color(self.axes_color) self.play( AnimationGroup(GrowFromCenter(self.axes), FadeIn(self.axes_labels), lag_ratio=0.4))
def fit_to_new_axes(self, axes, is_logscaled_xaxis=False, old_axes=Axes()): # the distribution is set to the screen default xaxis # TODO: did not consider axes rotation # set the origin to the zero point on x_axis, not on y_axis new_origin = axes.x_axis.number_to_point(0) old_origin = old_axes.x_axis.number_to_point(0) new_x_unit_lenth = get_norm(new_origin - axes.x_axis.number_to_point(1)) new_y_unit_lenth = get_norm( axes.y_axis.number_to_point(0) - axes.y_axis.number_to_point(1)) old_x_unit_lenth = get_norm(old_origin - old_axes.x_axis.number_to_point(1)) old_y_unit_lenth = get_norm( old_axes.y_axis.number_to_point(0) - old_axes.y_axis.number_to_point(1)) # calculate the unit distance in new x_axis x_strech_factor = np.divide(new_x_unit_lenth, old_x_unit_lenth) # zero point of y_axis might be different from zero point in x_axis y_strech_factor = np.divide(new_y_unit_lenth, old_y_unit_lenth) #shift and stretch about the new_origin self.points[:, 0] = x_strech_factor * self.points[:, 0] self.points[:, 1] = y_strech_factor * self.points[:, 1] self.shift(new_origin - old_origin) anchors = self.get_up_curve_anchors() self.mean = self.mean * x_strech_factor x_shift = self.mean - self.get_mean_point()[0] self.x_min = anchors[0][0] + x_shift self.x_max = anchors[-1][0] + x_shift
def setup_axes(self): axes = Axes(**self.axes_config) axes.center() axes.shift(self.axes_center) axes.x_axis.set_stroke(width = 1) axes.y_axis.set_stroke(width = 0) self.add_foreground_mobjects(axes) self.axes = axes
def construct(self): axes = Axes(x_axis_config={ "include_ticks": False }, y_axis_config={ "include_ticks": False }, number_line_config={ "color": self.axes_color }).scale(0.9) self.add(axes) ellipse = Ellipse(width=self.width, height=self.height) ellipse_x_axis = DashedLine(self.width / 2 * LEFT, self.width / 2 * RIGHT, color=BLACK) ellipse_y_axis = DashedLine(self.height / 2 * UP, self.height / 2 * DOWN, color=BLACK) elipticity_line = Line(self.width / 2 * LEFT, self.height / 2 * UP, color=BLUE) elipticity_arc = Arc(0, math.atan(self.height / self.width)).shift( self.width / 2 * LEFT) ellipse_group = VGroup(ellipse, ellipse_x_axis, ellipse_y_axis, elipticity_arc, elipticity_line) ellipse_group.rotate(self.azimuth) self.add(ellipse_group) rightest = self.get_ellipse_rightest_point(self.width / 2, self.height / 2, self.azimuth) highest = self.get_ellipse_highest_point(self.width / 2, self.height / 2, self.azimuth) vertical_line = Line(rightest * RIGHT, rightest * RIGHT + highest * UP, color=GREEN) horizontal_line = Line(highest * UP, highest * UP + rightest * RIGHT, color=GREEN) self.bring_to_back(vertical_line, horizontal_line) azimuth_arc = Arc(0, self.azimuth) self.add(azimuth_arc) self.wait()
def add_axes(self, animate=False, color=WHITE, **kwargs): """ Adds a pair of Axes to the Scene. Parameters ---------- animate (bool=False) Whether or not to animate the addition of the axes through ShowCreation. color (str) The color of the axes. Defaults to WHITE. """ axes = Axes(color=color, tick_frequency=1) if animate: self.play(ShowCreation(axes)) self.add(axes) return axes
def construct(self): a = 1 c = FunctionGraph(lambda x: 2 * np.exp(-2 * (x - a * 1)**2)) axes = Axes(y_min=-3, y_max=3) def update_curve(c, dt): alpha = interpolate(1, 4, dt) c_c = FunctionGraph(lambda x: 2 * np.exp(-2 * (x - a * alpha)**2)) c.become(c_c) self.play(ShowCreation(axes), ShowCreation(c)) self.wait() self.play(UpdateFromAlphaFunc(c, update_curve), rate_func=there_and_back, run_time=4) self.wait()
def add_axes(self, animate=False, color=WHITE, **kwargs): axes = Axes(color=color, tick_frequency=1) if animate: self.play(ShowCreation(axes)) self.add(axes) return axes
def import_data_and_set_axes( #data inputs X,#the data that is projected to X axis, its shape should be (number of bubbles, number of time intervals) Y,#the data that is projected to Y axis, its shape should be (number of bubbles, number of time intervals) ): # This function is to deal with all sorts of data # that is about to be putted in the bubble charts, # The input X,Y must be np.ndarrays. #check whether the types and shapes of X,Y,R are correct assert(isinstance(X, np.ndarray) and isinstance(Y,np.ndarray)) assert(X.shape == Y.shape and len(X.shape) == 2) #digest the range, if not custom range if not CUSTOM_AXES_RANGE: xmin = np.min(X) xmax = np.max(X) ymin = np.min(Y) ymax = np.max(Y) else: xmin = XMIN xmax = XMAX ymin = YMIN ymax = YMAX if not CUSTOM_AXES_NUMBER: DISTANCE_BETWEEN_XAXIS_TICKS = np.divide(xmax - xmin,NUM_OF_X_TICKS + 1) DISTANCE_BETWEEN_YAXIS_TICKS = np.divide(ymax - ymin,NUM_OF_Y_TICKS + 1) x_axis_config = { "tick_frequency": DISTANCE_BETWEEN_XAXIS_TICKS, "leftmost_tick": xmin, "numbers_with_elongated_ticks":[ymin], "decimal_number_config": { "num_decimal_places": X_DECIMAL_PLACES, } } y_axis_config = { "label_direction": LEFT, "tick_frequency": DISTANCE_BETWEEN_YAXIS_TICKS, "leftmost_tick": ymin, "numbers_with_elongated_ticks":[ymin], "decimal_number_config": { "num_decimal_places": Y_DECIMAL_PLACES, } } else: x_axis_config = {"include_ticks":False} y_axis_config = {"include_ticks":False,"label_direction": LEFT} #add numbers and ticks manully #create the axis config: AXES_CONFIG = { #axis information "x_min": xmin, "x_max": xmax, "y_min": ymin, "y_max": ymax, # MORE axis config at mobject.number_line.py "x_axis_config":x_axis_config, "y_axis_config":y_axis_config, "number_line_config": { "color": AXIS_COLOR, "include_tip": True, "exclude_zero_from_default_numbers": True, "number_scale_val":NUMBER_SCALE_FACTOR} } #create the axes mobject axes = Axes( x_min = AXES_CONFIG["x_min"], x_max = AXES_CONFIG["x_max"], y_min = AXES_CONFIG["y_min"], y_max = AXES_CONFIG["y_max"], x_axis_config = AXES_CONFIG["x_axis_config"], y_axis_config = AXES_CONFIG["y_axis_config"], number_line_config = AXES_CONFIG["number_line_config"], ) #adjust the axes position to fit the screen: x_scale_factor = np.divide(RIGHT_MOST_X_ON_SCREEN - NEWORIGIN[0],xmax - xmin) y_scale_factor = np.divide(TOP_MOST_Y_ON_SCREEN - NEWORIGIN[1],ymax - ymin) axes.x_axis.shift(xmin*LEFT) axes.y_axis.shift(ymin*DOWN) axes.x_axis.stretch_about_point(x_scale_factor, 0, ORIGIN) axes.y_axis.stretch_about_point(y_scale_factor, 1, ORIGIN) axes.shift(NEWORIGIN) # create customized numbers and ticks to axes if CUSTOM_AXES_NUMBER: axes.x_axis.tick_marks = VGroup() axes.y_axis.tick_marks = VGroup() for number in X_NUMBERS: axes.x_axis.tick_marks.add(axes.x_axis.get_tick(number)) axes.x_axis.add_numbers(number) for number in Y_NUMBERS: axes.y_axis.tick_marks.add(axes.y_axis.get_tick(number)) axes.y_axis.add_numbers(number) axes.x_axis.add(axes.x_axis.tick_marks) axes.y_axis.add(axes.y_axis.tick_marks) else: if SHOW_X_NUMBERS: interates = np.linspace(xmin,xmax,NUM_OF_X_TICKS + 1, endpoint = False) np.delete(interates,0) for number in interates: axes.x_axis.add_numbers(number) if SHOW_Y_NUMBERS: interates = np.linspace(ymin,ymax,NUM_OF_Y_TICKS + 1, endpoint = False) np.delete(interates,0) for number in interates: axes.y_axis.add_numbers(number) return AXES_CONFIG, axes
def add_axes(self, animate=False, color=WHITE, **kwargs): axes = Axes(color=color, tick_frequency=1) if animate: self.play(ShowCreation(axes, submobject_mode="one_at_a_time")) self.add(axes) return axes
class Polarization(Scene): CONFIG = { "period": 6, "camera_config": { "background_color": Color("white") }, "axes_scale": 0.9, "vector_length": 2, "vector_args": { "max_stroke_width_to_length_ratio": 10000, "max_tip_length_to_length_ratio": 0.95, }, "xy_line_stroke_width": DEFAULT_STROKE_WIDTH / 2, "xy_line_color": Color("blue"), "path_color": Color("red"), "axes_color": BLACK, "axes_vector_color": Color("green"), "xy_vector_color": Color("blue"), } def construct(self): self.phase = 0 point_x, point_y = self.comp_point(0) self.make_axes() self.ellipse = VMobject(color=self.path_color) self.phi = TexMobject(r"\Delta \Phi = ").set_color(BLACK).shift(4 * RIGHT + 2 * UP) self.phi_0 = TexMobject("0").set_color(BLACK).next_to(self.phi, RIGHT) self.phi_pi_2 = TexMobject(r"\frac{\pi}{2}").set_color(BLACK).next_to( self.phi, RIGHT).shift(0.06 * DOWN) self.phi_3_pi_4 = TexMobject(r"\frac{3 \pi}{4}").set_color( BLACK).next_to(self.phi, RIGHT) self.x_vector = Vector(point_x * RIGHT, color=self.axes_vector_color, **self.vector_args) self.y_vector = Vector(point_y * UP, color=self.axes_vector_color, **self.vector_args) self.xy_vector = Vector(point_x * RIGHT + point_y * UP, color=self.xy_vector_color, **self.vector_args) update_group = VGroup( self.ellipse, self.xy_vector, self.x_vector, self.y_vector, ) self.wait(1.6) self.add(self.ellipse) self.play(FadeIn(self.x_vector)) # self.wait(1) self.play(FadeIn(self.y_vector)) self.wait(4) self.play(FadeIn(self.xy_vector)) self.play(UpdateFromAlphaFunc(update_group, self.do_vectors_and_ellipse_period), run_time=self.period, rate_func=linear) self.play( UpdateFromAlphaFunc(update_group, self.do_vectors_only_period, run_time=self.period, rate_func=linear)) self.play( AnimationGroup(UpdateFromAlphaFunc(update_group, self.do_vectors_only_period, run_time=self.period, rate_func=linear), AnimationGroup(FadeIn(self.phi), FadeIn(self.phi_0)), lag_ratio=0.7)) self.play( UpdateFromAlphaFunc(update_group, self.do_vectors_only_period, run_time=self.period, rate_func=linear)) self.x_vector.set_color(BLACK) self.play(UpdateFromAlphaFunc(update_group, self.do_90_phase_shift, rate_func=linear), FadeOut(self.ellipse), FadeOut(self.phi_0), FadeIn(self.phi_pi_2), run_time=self.period / 4) self.phase = np.pi / 2 self.ellipse.set_points([]) self.x_vector.set_color(self.axes_vector_color) self.play(UpdateFromAlphaFunc(update_group, self.do_vectors_and_ellipse_period), run_time=self.period, rate_func=linear) for _ in range(3): self.play(UpdateFromAlphaFunc(update_group, self.do_vectors_only_period), run_time=self.period, rate_func=linear) self.x_vector.set_color(BLACK) self.play(UpdateFromAlphaFunc(update_group, self.do_45_phase_shift, rate_func=linear), FadeOut(self.ellipse), FadeOut(self.phi_pi_2), FadeIn(self.phi_3_pi_4), run_time=self.period / 8) self.phase = 3 * np.pi / 4 self.ellipse.set_points([]) self.x_vector.set_color(self.axes_vector_color) self.play(UpdateFromAlphaFunc(update_group, self.do_vectors_and_ellipse_period), run_time=self.period, rate_func=linear) self.play( AnimationGroup(UpdateFromAlphaFunc( update_group, self.do_vectors_only_period_hide, rate_func=linear, run_time=self.period), AnimationGroup(FadeOut(self.phi_3_pi_4), FadeOut(self.phi)), lag_ratio=0.7)) self.play(FadeOut(self.axes), FadeOut(self.axes_labels)) self.wait() def make_axes(self): self.axes = Axes(x_min=-self.axes_scale * FRAME_X_RADIUS, x_max=self.axes_scale * FRAME_X_RADIUS, y_min=-self.axes_scale * FRAME_Y_RADIUS, y_max=self.axes_scale * FRAME_Y_RADIUS, x_axis_config={"include_ticks": False}, y_axis_config={"include_ticks": False}, number_line_config={"color": self.axes_color}) self.axes_labels = self.axes.get_axis_labels( x_label_tex="E_x", y_label_tex="E_y").set_color(self.axes_color) self.play( AnimationGroup(GrowFromCenter(self.axes), FadeIn(self.axes_labels), lag_ratio=0.4)) def do_vectors_and_ellipse_period(self, _, alpha): point_x, point_y = self.comp_point(alpha) self.add_point_to_ellipse(point_x, point_y) self.set_vector_positions(point_x, point_y) def do_vectors_only_period(self, _, alpha): point_x, point_y = self.comp_point(alpha) self.set_vector_positions(point_x, point_y) def do_90_phase_shift(self, _, alpha): alpha = interpolate(0, 1 / 4, alpha) x_point, y_point = self.comp_point(alpha) self.y_vector.put_start_and_end_on(ORIGIN, y_point * UP) self.xy_vector.put_start_and_end_on(ORIGIN, y_point * UP + 2 * RIGHT) def do_45_phase_shift(self, _, alpha): alpha = interpolate(0, 1 / 8, alpha) x_point, y_point = self.comp_point(alpha) self.y_vector.put_start_and_end_on(ORIGIN, y_point * UP) self.xy_vector.put_start_and_end_on(ORIGIN, y_point * UP + 2 * RIGHT) def set_vector_positions(self, x, y): self.x_vector.put_start_and_end_on(ORIGIN, x * RIGHT) self.y_vector.put_start_and_end_on(ORIGIN, y * UP) self.xy_vector.put_start_and_end_on(ORIGIN, x * RIGHT + y * UP) def add_point_to_ellipse(self, x, y): if not len(self.ellipse.get_points()): self.ellipse.set_points([UP * y + RIGHT * x]) else: self.ellipse.add_points_as_corners([UP * y + RIGHT * x]) def do_vectors_only_period_hide(self, _, alpha): fade_ratio = 3 if alpha >= (fade_ratio - 1) / fade_ratio: opacity = 1 - smooth(fade_ratio * alpha - (fade_ratio - 1)) self.x_vector.set_opacity(opacity) self.y_vector.set_opacity(opacity) self.xy_vector.set_opacity(opacity) self.ellipse.set_stroke(opacity=opacity) self.do_vectors_only_period(_, alpha) def comp_point(self, alpha): point_x = self.vector_length * np.cos( 2 * np.pi * alpha) * RIGHT + 0.01 * RIGHT point_y = self.vector_length * np.cos(2 * np.pi * alpha + self.phase) * UP + 0.01 * UP return point_x, point_y