From b41d109be9d968935374215107abae6120bbe722 Mon Sep 17 00:00:00 2001 From: "F. Muenkel" <25496279+fmuenkel@users.noreply.github.com> Date: Sat, 24 Jan 2026 18:11:43 +0100 Subject: [PATCH 1/5] Fix some graph tests --- manim/mobject/graph.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/manim/mobject/graph.py b/manim/mobject/graph.py index 8a898247d2..ff96849272 100644 --- a/manim/mobject/graph.py +++ b/manim/mobject/graph.py @@ -1565,6 +1565,9 @@ def update_edges(self, graph): def __repr__(self: Graph) -> str: return f"Undirected graph on {len(self.vertices)} vertices and {len(self.edges)} edges" + def __str__(self: Graph) -> str: + return self.__repr__() + class DiGraph(GenericGraph): """A directed graph. @@ -1782,3 +1785,6 @@ def update_edges(self, graph): def __repr__(self: DiGraph) -> str: return f"Directed graph on {len(self.vertices)} vertices and {len(self.edges)} edges" + + def __str__(self: DiGraph) -> str: + return self.__repr__() From 45e7632ddf4eea5f5f7a7677ff528467c7b1e150 Mon Sep 17 00:00:00 2001 From: "F. Muenkel" <25496279+fmuenkel@users.noreply.github.com> Date: Tue, 3 Feb 2026 21:25:16 +0100 Subject: [PATCH 2/5] Fix two more tests --- tests/module/mobject/test_graph.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/module/mobject/test_graph.py b/tests/module/mobject/test_graph.py index a345e748cf..0dfe3e7d8c 100644 --- a/tests/module/mobject/test_graph.py +++ b/tests/module/mobject/test_graph.py @@ -1,5 +1,6 @@ from __future__ import annotations +import numpy as np import pytest from manim import DiGraph, Graph, LabeledLine, Manager, Scene, Text, tempconfig @@ -134,9 +135,9 @@ def test_custom_graph_layout_dict(): [1, 2, 3], [(1, 2), (2, 3)], layout={1: [0, 0, 0], 2: [1, 1, 0], 3: [1, -1, 0]} ) assert str(G) == "Undirected graph on 3 vertices and 2 edges" - assert all(G.vertices[1].get_center() == [0, 0, 0]) - assert all(G.vertices[2].get_center() == [1, 1, 0]) - assert all(G.vertices[3].get_center() == [1, -1, 0]) + np.testing.assert_allclose(G.vertices[1].get_center(), [0, 0, 0]) + np.testing.assert_allclose(G.vertices[2].get_center(), [1, 1, 0]) + np.testing.assert_allclose(G.vertices[3].get_center(), [1, -1, 0]) def test_graph_layouts(): @@ -165,9 +166,9 @@ def layout_func(graph, scale): return {vertex: [vertex, vertex, 0] for vertex in graph} G = Graph([1, 2, 3], [(1, 2), (2, 3)], layout=layout_func) - assert all(G.vertices[1].get_center() == [1, 1, 0]) - assert all(G.vertices[2].get_center() == [2, 2, 0]) - assert all(G.vertices[3].get_center() == [3, 3, 0]) + np.testing.assert_allclose(G.vertices[1].get_center(), [1, 1, 0]) + np.testing.assert_allclose(G.vertices[2].get_center(), [2, 2, 0]) + np.testing.assert_allclose(G.vertices[3].get_center(), [3, 3, 0]) def test_custom_graph_layout_function_with_kwargs(): From 58176b2a46cc80a84ca255afcf4e68c75796b985 Mon Sep 17 00:00:00 2001 From: "F. Muenkel" <25496279+fmuenkel@users.noreply.github.com> Date: Wed, 4 Feb 2026 01:21:52 +0100 Subject: [PATCH 3/5] Ensure temporary visuals get removed from scene --- manim/mobject/graph.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/manim/mobject/graph.py b/manim/mobject/graph.py index ff96849272..7bb83acabc 100644 --- a/manim/mobject/graph.py +++ b/manim/mobject/graph.py @@ -7,6 +7,7 @@ "DiGraph", ] +import contextlib import itertools as it from collections.abc import Hashable, Iterable, Sequence from copy import copy @@ -18,7 +19,7 @@ if TYPE_CHECKING: from typing import TypeAlias - from manim.scene.scene import Scene + from manim.scene.scene import SceneBuffer from manim.typing import Point3D, Point3DLike NxGraph: TypeAlias = nx.classes.graph.Graph | nx.classes.digraph.DiGraph @@ -908,10 +909,12 @@ def _add_vertices_animation(self, *args, anim_args=None, **kwargs): vertex_mobjects = self._create_vertices(*args, **kwargs) - def on_finish(scene: Scene): + def on_finish(buf: SceneBuffer | None): for v in vertex_mobjects: - scene.remove(v[-1]) self._add_created_vertex(*v) + if buf is not None and hasattr(buf, "replace"): + with contextlib.suppress(Exception): + buf.replace(v[-1]) return AnimationGroup( *(animation(v[-1], **anim_args) for v in vertex_mobjects), From 12366bc2cd3453f0835dea71899a344dc3a658c0 Mon Sep 17 00:00:00 2001 From: "F. Muenkel" <25496279+fmuenkel@users.noreply.github.com> Date: Fri, 6 Feb 2026 23:14:40 +0100 Subject: [PATCH 4/5] Fix wrong import --- manim/mobject/graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manim/mobject/graph.py b/manim/mobject/graph.py index 7bb83acabc..94fa2976ce 100644 --- a/manim/mobject/graph.py +++ b/manim/mobject/graph.py @@ -19,7 +19,7 @@ if TYPE_CHECKING: from typing import TypeAlias - from manim.scene.scene import SceneBuffer + from manim.animation.scene_buffer import SceneBuffer from manim.typing import Point3D, Point3DLike NxGraph: TypeAlias = nx.classes.graph.Graph | nx.classes.digraph.DiGraph From 758305e3126e3b88805b7fcf9c46b4f0e22ff6fd Mon Sep 17 00:00:00 2001 From: "F. Muenkel" <25496279+fmuenkel@users.noreply.github.com> Date: Fri, 6 Feb 2026 23:15:27 +0100 Subject: [PATCH 5/5] Remove redundant hasattr --- manim/mobject/graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manim/mobject/graph.py b/manim/mobject/graph.py index 94fa2976ce..74d4becec3 100644 --- a/manim/mobject/graph.py +++ b/manim/mobject/graph.py @@ -912,7 +912,7 @@ def _add_vertices_animation(self, *args, anim_args=None, **kwargs): def on_finish(buf: SceneBuffer | None): for v in vertex_mobjects: self._add_created_vertex(*v) - if buf is not None and hasattr(buf, "replace"): + if buf is not None: with contextlib.suppress(Exception): buf.replace(v[-1])