diff --git a/manim/scene/vector_space_scene.py b/manim/scene/vector_space_scene.py index d39ce32895..0fd995c981 100644 --- a/manim/scene/vector_space_scene.py +++ b/manim/scene/vector_space_scene.py @@ -4,7 +4,7 @@ __all__ = ["VectorScene", "LinearTransformationScene"] -from typing import Callable +from typing import Any, Callable import numpy as np @@ -14,7 +14,7 @@ from manim.mobject.graphing.coordinate_systems import Axes, NumberPlane from manim.mobject.opengl.opengl_mobject import OpenGLMobject from manim.mobject.text.tex_mobject import MathTex, Tex -from manim.utils.config_ops import update_dict_recursively +from manim.utils.config_ops import merge_dicts_recursively from .. import config from ..animation.animation import Animation @@ -79,7 +79,15 @@ def add_plane(self, animate: bool = False, **kwargs): self.add(plane) return plane - def add_axes(self, animate: bool = False, color: bool = WHITE, **kwargs): + def add_axes( + self, + animate: bool = False, + animation: Animation = Create, + animation_kwargs: dict[str, Any] | None = {}, + play_kwargs: dict[str, Any] | None = {}, + axis_config: dict[str, Any] | None = {}, + **axis_kwargs: dict[str, Any] | None, + ): """ Adds a pair of Axes to the Scene. @@ -87,12 +95,74 @@ def add_axes(self, animate: bool = False, color: bool = WHITE, **kwargs): ---------- animate Whether or not to animate the addition of the axes through Create. - color - The color of the axes. Defaults to WHITE. - """ - axes = Axes(color=color, axis_config={"unit_size": 1}) + + animation + The animation used to add the axes. + + animation_kwargs + Any valid keyword arguments of animation. + + play_kwargs + Any valid keyword arguments of play. + + axis_config + Any valid keyword arguments of Axes. + + axis_kwargs + Any valid keyword arguments of Axes. + + Returns + ------- + Axes + The Axes object. + + Examples + -------- + .. manim:: AddingAxes + class AddingAxes(VectorScene): + def construct(self): + axis_config = {"include_tip": True, "unit_size": 2, "include_numbers": True} + animation = FadeIn + animation_kwargs = {"shift": LEFT} + play_kwargs = {"run_time": 1, "rate_func": linear} + + axes = self.add_axes( + animate=True, + animation=animation, + animation_kwargs=animation_kwargs, + play_kwargs=play_kwargs, + axis_config=axis_config, + x_range=[0, 10, 1], + y_range=[-2, 6, 1], + x_length=5, + y_length=5, + ) + self.play(axes.animate.shift(LEFT)) + self.wait() + + .. manim:: AddingAxes2 + class AddingAxes2(VectorScene): + def construct(self): + axis_config = {"include_tip": True, "unit_size": 2, "include_numbers": True} + axes = self.add_axes(animate=True, axis_config=axis_config) + self.play(axes.animate.shift(LEFT)) + self.wait() + + """ + axis_kwargs = merge_dicts_recursively( + { + "x_range": [-5, 5, 1], + "y_range": [-5, 5, 1], + "x_length": 5, + "y_length": 5, + }, + axis_kwargs, + ) + axis_config = merge_dicts_recursively({"unit_size": 1}, axis_config) + + axes = Axes(**axis_kwargs, axis_config=axis_config) if animate: - self.play(Create(axes)) + self.play(animation(axes, **animation_kwargs), **play_kwargs) self.add(axes) return axes @@ -1003,8 +1073,10 @@ def get_piece_movement(self, pieces: list | tuple | np.ndarray): Animation The animation of the movement. """ - start = VGroup(*pieces) + + start = VGroup(pieces) target = VGroup(*(mob.target for mob in pieces)) + # don't add empty VGroups if self.leave_ghost_vectors and start.submobjects: # start.copy() gives a VGroup of Vectors @@ -1091,6 +1163,7 @@ def apply_matrix(self, matrix: np.ndarray | list | tuple, **kwargs): **kwargs Any valid keyword argument of self.apply_transposed_matrix() """ + self.apply_transposed_matrix(np.array(matrix).T, **kwargs) def apply_inverse(self, matrix: np.ndarray | list | tuple, **kwargs):