This commit is contained in:
Henrik Skov Midtiby 2026-06-20 20:10:37 +08:00 committed by GitHub
commit c3a9ea924d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 59 additions and 38 deletions

View file

@ -66,6 +66,7 @@ __all__ = [
import itertools as it
from collections.abc import Callable, Iterable, Sequence
from typing import Any, Self
from manim.mobject.geometry.line import Line
from manim.mobject.geometry.polygram import Polygon
@ -188,9 +189,9 @@ class Table(VGroup):
def __init__(
self,
table: Iterable[Iterable[float | str | VMobject]],
row_labels: Iterable[VMobject] | None = None,
col_labels: Iterable[VMobject] | None = None,
table: Sequence[Sequence[float | str | VMobject]],
row_labels: Sequence[VMobject] | None = None,
col_labels: Sequence[VMobject] | None = None,
top_left_entry: VMobject | None = None,
v_buff: float = 0.8,
h_buff: float = 1.3,
@ -201,16 +202,25 @@ class Table(VGroup):
include_background_rectangle: bool = False,
background_rectangle_color: ParsableManimColor = BLACK,
element_to_mobject: Callable[
[float | str],
VMobject,
]
| Callable[
[VMobject],
VMobject,
]
| Callable[
[float | str | VMobject],
VMobject,
] = Paragraph,
]
| type[VMobject] = Paragraph,
element_to_mobject_config: dict = {},
arrange_in_grid_config: dict = {},
line_config: dict = {},
**kwargs,
**kwargs: Any,
):
self.row_labels = row_labels
self.col_labels = col_labels
self.row_labels = list(row_labels) if row_labels else None
self.col_labels = list(col_labels) if col_labels else None
self.top_left_entry = top_left_entry
self.row_dim = len(table)
self.col_dim = len(table[0])
@ -234,7 +244,7 @@ class Table(VGroup):
raise ValueError("Not all rows in table have the same length.")
super().__init__(**kwargs)
mob_table = self._table_to_mob_table(table)
mob_table: list[list[VMobject]] = self._table_to_mob_table(table)
self.elements_without_labels = VGroup(*it.chain(*mob_table))
mob_table = self._add_labels(mob_table)
self._organize_mob_table(mob_table)
@ -256,7 +266,7 @@ class Table(VGroup):
def _table_to_mob_table(
self,
table: Iterable[Iterable[float | str | VMobject]],
) -> list:
) -> list[list[VMobject]]:
"""Initializes the entries of ``table`` as :class:`~.VMobject`.
Parameters
@ -272,13 +282,15 @@ class Table(VGroup):
"""
return [
[
self.element_to_mobject(item, **self.element_to_mobject_config)
# error: Argument 1 has incompatible type "float | str | VMobject"; expected "float | str" [arg-type]
# error: Argument 1 has incompatible type "float | str | VMobject"; expected "VMobject" [arg-type]
self.element_to_mobject(item, **self.element_to_mobject_config) # type: ignore[arg-type]
for item in row
]
for row in table
]
def _organize_mob_table(self, table: Iterable[Iterable[VMobject]]) -> VGroup:
def _organize_mob_table(self, table: Sequence[Sequence[VMobject]]) -> VGroup:
"""Arranges the :class:`~.VMobject` of ``table`` in a grid.
Parameters
@ -304,7 +316,7 @@ class Table(VGroup):
)
return help_table
def _add_labels(self, mob_table: VGroup) -> VGroup:
def _add_labels(self, mob_table: list[list[VMobject]]) -> list[list[VMobject]]:
"""Adds labels to an in a grid arranged :class:`~.VGroup`.
Parameters
@ -323,13 +335,13 @@ class Table(VGroup):
if self.col_labels is not None:
if self.row_labels is not None:
if self.top_left_entry is not None:
col_labels = [self.top_left_entry] + self.col_labels
col_labels = [self.top_left_entry] + list(self.col_labels)
mob_table.insert(0, col_labels)
else:
# Placeholder to use arrange_in_grid if top_left_entry is not set.
# Import OpenGLVMobject to work with --renderer=opengl
dummy_mobject = get_vectorized_mobject_class()()
col_labels = [dummy_mobject] + self.col_labels
col_labels = [dummy_mobject] + list(self.col_labels)
mob_table.insert(0, col_labels)
else:
mob_table.insert(0, self.col_labels)
@ -693,7 +705,10 @@ class Table(VGroup):
item.set_color(random_bright_color())
self.add(table)
"""
return VGroup(*self.row_labels)
if self.row_labels:
return VGroup(*self.row_labels)
else:
return VGroup()
def get_col_labels(self) -> VGroup:
"""Return the column labels of the table.
@ -721,7 +736,10 @@ class Table(VGroup):
item.set_color(random_bright_color())
self.add(table)
"""
return VGroup(*self.col_labels)
if self.col_labels:
return VGroup(*self.col_labels)
else:
return VGroup()
def get_labels(self) -> VGroup:
"""Returns the labels of the table.
@ -764,7 +782,7 @@ class Table(VGroup):
mob.add_background_rectangle(color=ManimColor(color))
return self
def get_cell(self, pos: Sequence[int] = (1, 1), **kwargs) -> Polygon:
def get_cell(self, pos: Sequence[int] = (1, 1), **kwargs: Any) -> Polygon:
"""Returns one specific cell as a rectangular :class:`~.Polygon` without the entry.
Parameters
@ -825,7 +843,7 @@ class Table(VGroup):
self,
pos: Sequence[int] = (1, 1),
color: ParsableManimColor = PURE_YELLOW,
**kwargs,
**kwargs: Any,
) -> BackgroundRectangle:
"""Returns a :class:`~.BackgroundRectangle` of the cell at the given position.
@ -864,7 +882,7 @@ class Table(VGroup):
self,
pos: Sequence[int] = (1, 1),
color: ParsableManimColor = PURE_YELLOW,
**kwargs,
**kwargs: Any,
) -> Table:
"""Highlights one cell at a specific position on the table by adding a :class:`~.BackgroundRectangle`.
@ -907,7 +925,7 @@ class Table(VGroup):
label_animation: Callable[[VMobject | VGroup], Animation] = Write,
element_animation: Callable[[VMobject | VGroup], Animation] = Create,
entry_animation: Callable[[VMobject | VGroup], Animation] = FadeIn,
**kwargs,
**kwargs: Any,
) -> AnimationGroup:
"""Customized create-type function for tables.
@ -947,7 +965,7 @@ class Table(VGroup):
self.play(table.create())
self.wait()
"""
animations: Sequence[Animation] = [
animations: list[Animation] = [
line_animation(
VGroup(self.vertical_lines, self.horizontal_lines),
**kwargs,
@ -974,12 +992,14 @@ class Table(VGroup):
return AnimationGroup(*animations, lag_ratio=lag_ratio)
def scale(self, scale_factor: float, **kwargs):
def scale(
self, scale_factor: float, scale_stroke: bool = False, **kwargs: Any
) -> Self:
# h_buff and v_buff must be adjusted so that Table.get_cell
# can construct an accurate polygon for a cell.
self.h_buff *= scale_factor
self.v_buff *= scale_factor
super().scale(scale_factor, **kwargs)
super().scale(scale_factor, scale_stroke=scale_stroke, **kwargs)
return self
@ -1005,9 +1025,10 @@ class MathTable(Table):
def __init__(
self,
table: Iterable[Iterable[float | str]],
element_to_mobject: Callable[[float | str], VMobject] = MathTex,
**kwargs,
table: Sequence[Sequence[float | str]],
element_to_mobject: Callable[[float | str], VMobject]
| type[VMobject] = MathTex,
**kwargs: Any,
):
"""
Special case of :class:`~.Table` with `element_to_mobject` set to :class:`~.MathTex`.
@ -1060,9 +1081,10 @@ class MobjectTable(Table):
def __init__(
self,
table: Iterable[Iterable[VMobject]],
element_to_mobject: Callable[[VMobject], VMobject] = lambda m: m,
**kwargs,
table: Sequence[Sequence[VMobject]],
element_to_mobject: Callable[[VMobject], VMobject]
| type[VMobject] = lambda m: m,
**kwargs: Any,
):
"""
Special case of :class:`~.Table` with ``element_to_mobject`` set to an identity function.
@ -1108,9 +1130,10 @@ class IntegerTable(Table):
def __init__(
self,
table: Iterable[Iterable[float | str]],
element_to_mobject: Callable[[float | str], VMobject] = Integer,
**kwargs,
table: Sequence[Sequence[float | str]],
element_to_mobject: Callable[[float | str], VMobject]
| type[VMobject] = Integer,
**kwargs: Any,
):
"""
Special case of :class:`~.Table` with `element_to_mobject` set to :class:`~.Integer`.
@ -1152,10 +1175,11 @@ class DecimalTable(Table):
def __init__(
self,
table: Iterable[Iterable[float | str]],
element_to_mobject: Callable[[float | str], VMobject] = DecimalNumber,
table: Sequence[Sequence[float | str]],
element_to_mobject: Callable[[float | str], VMobject]
| type[VMobject] = DecimalNumber,
element_to_mobject_config: dict = {"num_decimal_places": 1},
**kwargs,
**kwargs: Any,
):
"""
Special case of :class:`~.Table` with ``element_to_mobject`` set to :class:`~.DecimalNumber`.

View file

@ -91,9 +91,6 @@ ignore_errors = True
[mypy-manim.mobject.opengl.opengl_vectorized_mobject]
ignore_errors = True
[mypy-manim.mobject.table]
ignore_errors = True
[mypy-manim.mobject.types.point_cloud_mobject]
ignore_errors = True