{"record":{"id":"3b0c7754fda6e39c","repo":"3b1b/manim","slug":"matrix-has-bad-dimensions","errorCode":null,"errorMessage":"Matrix has bad dimensions","messagePattern":"Matrix has bad dimensions","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"manimlib/animation/transform.py","lineNumber":288,"sourceCode":"        matrix: npt.ArrayLike,\n        mobject: Mobject,\n        **kwargs\n    ):\n        matrix = self.initialize_matrix(matrix)\n\n        def func(p):\n            return np.dot(p, matrix.T)\n\n        super().__init__(func, mobject, **kwargs)\n\n    def initialize_matrix(self, matrix: npt.ArrayLike) -> np.ndarray:\n        matrix = np.array(matrix)\n        if matrix.shape == (2, 2):\n            new_matrix = np.identity(3)\n            new_matrix[:2, :2] = matrix\n            matrix = new_matrix\n        elif matrix.shape != (3, 3):\n            raise Exception(\"Matrix has bad dimensions\")\n        return matrix\n\n\nclass ApplyComplexFunction(ApplyMethod):\n    def __init__(\n        self,\n        function: Callable[[complex], complex],\n        mobject: Mobject,\n        **kwargs\n    ):\n        self.function = function\n        method = mobject.apply_complex_function\n        super().__init__(method, function, **kwargs)\n\n    def init_path_func(self) -> None:\n        func1 = self.function(complex(1))\n        self.path_arc = np.log(func1).imag\n        super().init_path_func()","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/3b1b/manim/blob/dee01804d47b9f94402d71472674710dcac125b8/manimlib/animation/transform.py#L270-L306","documentation":"ApplyMatrix animates a linear transformation of a mobject's points. initialize_matrix accepts exactly a (2,2) matrix (promoted to 3x3 in the xy-plane) or a (3,3) matrix; anything else — 1x3, 4x4, non-square, wrong dtype shape — raises 'Matrix has bad dimensions'.","triggerScenarios":"ApplyMatrix([[1, 0, 0], [0, 1, 0]], mob) (2x3); passing a rotation_about_z(...) result plus an extra row; passing a 4x4 homogeneous matrix from graphics code; passing a flat list of 9 numbers without reshaping.","commonSituations":"Mixing up homogeneous 4x4 matrices from other graphics libraries; building matrices by hand and getting row counts wrong; intending ApplyPointwiseFunction or apply_matrix on the mobject instead.","solutions":["Reshape to exactly 2x2 or 3x3: np.array(mat).reshape(3, 3)","For homogeneous transforms, drop the last row and column before passing","For pure rotations, prefer ApplyMethod(mob.rotate, angle, axis=Z) or Rotation(angle) which handle the matrix for you"],"exampleFix":"# before\nself.play(ApplyMatrix(rotation_matrix_4x4, mob))\n# after\nself.play(ApplyMatrix(rotation_matrix_4x4[:3, :3], mob))","handlingStrategy":"validation","validationCode":"import numpy as np\nmat = np.asarray(mat)\nassert mat.shape in ((2, 2), (3, 3)), f\"matrix must be 2x2 or 3x3, got {mat.shape}\"","typeGuard":"import numpy as np\ndef is_valid_transform_matrix(mat) -> bool:\n    return np.asarray(mat).shape in ((2, 2), (3, 3))","tryCatchPattern":null,"preventionTips":["Build matrices with manim's rotation_matrix(...) helpers, which return 3x3","Strip the homogeneous row/column when copying 4x4 matrices from other graphics code"],"tags":["animation","transform","matrix","validation"],"backgroundTag":null,"analyzedSha":"dee01804d47b9f94402d71472674710dcac125b8","analyzedAt":"2026-08-14T19:53:44.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}