manim 0.17.3__py3-none-any.whl → 0.18.0.post0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of manim might be problematic. Click here for more details.
- manim/__init__.py +1 -0
- manim/__main__.py +2 -0
- manim/_config/__init__.py +0 -1
- manim/_config/logger_utils.py +1 -0
- manim/_config/utils.py +14 -5
- manim/animation/changing.py +9 -5
- manim/animation/creation.py +8 -3
- manim/animation/indication.py +4 -4
- manim/animation/speedmodifier.py +2 -4
- manim/animation/updaters/mobject_update_utils.py +134 -16
- manim/camera/camera.py +31 -17
- manim/cli/checkhealth/__init__.py +0 -0
- manim/cli/checkhealth/checks.py +173 -0
- manim/cli/checkhealth/commands.py +81 -0
- manim/cli/render/global_options.py +6 -0
- manim/constants.py +58 -54
- manim/mobject/geometry/__init__.py +1 -0
- manim/mobject/geometry/arc.py +126 -91
- manim/mobject/geometry/boolean_ops.py +6 -10
- manim/mobject/geometry/labeled.py +155 -0
- manim/mobject/geometry/line.py +66 -50
- manim/mobject/geometry/polygram.py +23 -15
- manim/mobject/geometry/shape_matchers.py +24 -15
- manim/mobject/geometry/tips.py +62 -40
- manim/mobject/graph.py +3 -4
- manim/mobject/graphing/coordinate_systems.py +190 -139
- manim/mobject/graphing/number_line.py +5 -2
- manim/mobject/graphing/probability.py +4 -3
- manim/mobject/graphing/scale.py +7 -7
- manim/mobject/logo.py +108 -22
- manim/mobject/matrix.py +33 -37
- manim/mobject/mobject.py +327 -260
- manim/mobject/opengl/opengl_image_mobject.py +1 -1
- manim/mobject/opengl/opengl_mobject.py +18 -12
- manim/mobject/opengl/opengl_point_cloud_mobject.py +1 -1
- manim/mobject/opengl/opengl_surface.py +1 -1
- manim/mobject/opengl/opengl_vectorized_mobject.py +21 -17
- manim/mobject/svg/brace.py +3 -1
- manim/mobject/svg/svg_mobject.py +9 -11
- manim/mobject/table.py +50 -54
- manim/mobject/text/numbers.py +48 -6
- manim/mobject/text/tex_mobject.py +8 -12
- manim/mobject/text/text_mobject.py +32 -24
- manim/mobject/three_d/three_d_utils.py +13 -8
- manim/mobject/three_d/three_dimensions.py +61 -43
- manim/mobject/types/image_mobject.py +5 -4
- manim/mobject/types/point_cloud_mobject.py +8 -6
- manim/mobject/types/vectorized_mobject.py +385 -258
- manim/mobject/vector_field.py +19 -11
- manim/plugins/import_plugins.py +1 -1
- manim/plugins/plugins_flags.py +1 -6
- manim/renderer/shader.py +2 -2
- manim/scene/scene.py +15 -7
- manim/scene/scene_file_writer.py +1 -2
- manim/scene/three_d_scene.py +1 -1
- manim/scene/vector_space_scene.py +17 -7
- manim/typing.py +133 -0
- manim/utils/bezier.py +267 -83
- manim/utils/color/AS2700.py +234 -0
- manim/utils/color/BS381.py +315 -0
- manim/utils/color/X11.py +530 -0
- manim/utils/color/XKCD.py +949 -0
- manim/utils/color/__init__.py +58 -0
- manim/utils/color/core.py +1036 -0
- manim/utils/color/manim_colors.py +220 -0
- manim/utils/docbuild/autocolor_directive.py +92 -0
- manim/utils/docbuild/manim_directive.py +40 -6
- manim/utils/file_ops.py +1 -1
- manim/utils/hashing.py +1 -1
- manim/utils/iterables.py +1 -1
- manim/utils/rate_functions.py +33 -0
- manim/utils/simple_functions.py +0 -18
- manim/utils/space_ops.py +55 -42
- manim/utils/testing/frames_comparison.py +9 -0
- manim/utils/tex.py +2 -0
- manim/utils/tex_file_writing.py +29 -2
- {manim-0.17.3.dist-info → manim-0.18.0.post0.dist-info}/METADATA +14 -14
- {manim-0.17.3.dist-info → manim-0.18.0.post0.dist-info}/RECORD +82 -71
- {manim-0.17.3.dist-info → manim-0.18.0.post0.dist-info}/WHEEL +1 -1
- manim/communitycolors.py +0 -9
- manim/utils/color.py +0 -552
- {manim-0.17.3.dist-info → manim-0.18.0.post0.dist-info}/LICENSE +0 -0
- {manim-0.17.3.dist-info → manim-0.18.0.post0.dist-info}/LICENSE.community +0 -0
- {manim-0.17.3.dist-info → manim-0.18.0.post0.dist-info}/entry_points.txt +0 -0
|
@@ -29,7 +29,7 @@ class OpenGLImageMobject(OpenGLTexturedSurface):
|
|
|
29
29
|
):
|
|
30
30
|
self.image = filename_or_array
|
|
31
31
|
self.resampling_algorithm = resampling_algorithm
|
|
32
|
-
if
|
|
32
|
+
if isinstance(filename_or_array, np.ndarray):
|
|
33
33
|
self.size = self.image.shape[1::-1]
|
|
34
34
|
elif isinstance(filename_or_array, (str, Path)):
|
|
35
35
|
path = get_full_raster_image_path(filename_or_array)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import copy
|
|
4
|
+
import inspect
|
|
4
5
|
import itertools as it
|
|
5
6
|
import random
|
|
6
7
|
import sys
|
|
@@ -10,13 +11,19 @@ from typing import Iterable, Sequence
|
|
|
10
11
|
|
|
11
12
|
import moderngl
|
|
12
13
|
import numpy as np
|
|
13
|
-
from colour import Color
|
|
14
14
|
|
|
15
15
|
from manim import config, logger
|
|
16
16
|
from manim.constants import *
|
|
17
|
+
from manim.renderer.shader_wrapper import get_colormap_code
|
|
17
18
|
from manim.utils.bezier import integer_interpolate, interpolate
|
|
18
|
-
from manim.utils.color import
|
|
19
|
-
|
|
19
|
+
from manim.utils.color import (
|
|
20
|
+
WHITE,
|
|
21
|
+
ManimColor,
|
|
22
|
+
ParsableManimColor,
|
|
23
|
+
color_gradient,
|
|
24
|
+
color_to_rgb,
|
|
25
|
+
rgb_to_hex,
|
|
26
|
+
)
|
|
20
27
|
from manim.utils.config_ops import _Data, _Uniforms
|
|
21
28
|
|
|
22
29
|
# from ..utils.iterables import batch_by_property
|
|
@@ -31,7 +38,6 @@ from manim.utils.iterables import (
|
|
|
31
38
|
uniq_chain,
|
|
32
39
|
)
|
|
33
40
|
from manim.utils.paths import straight_path
|
|
34
|
-
from manim.utils.simple_functions import get_parameters
|
|
35
41
|
from manim.utils.space_ops import (
|
|
36
42
|
angle_between_vectors,
|
|
37
43
|
normalize,
|
|
@@ -146,7 +152,7 @@ class OpenGLMobject:
|
|
|
146
152
|
self.init_updaters()
|
|
147
153
|
# self.init_event_listners()
|
|
148
154
|
self.init_points()
|
|
149
|
-
self.color =
|
|
155
|
+
self.color = ManimColor.parse(color)
|
|
150
156
|
self.init_colors()
|
|
151
157
|
|
|
152
158
|
self.shader_indices = None
|
|
@@ -203,10 +209,10 @@ class OpenGLMobject:
|
|
|
203
209
|
>>> from manim import Square, GREEN
|
|
204
210
|
>>> Square.set_default(color=GREEN, fill_opacity=0.25)
|
|
205
211
|
>>> s = Square(); s.color, s.fill_opacity
|
|
206
|
-
(
|
|
212
|
+
(ManimColor('#83C167'), 0.25)
|
|
207
213
|
>>> Square.set_default()
|
|
208
214
|
>>> s = Square(); s.color, s.fill_opacity
|
|
209
|
-
(
|
|
215
|
+
(ManimColor('#FFFFFF'), 0.0)
|
|
210
216
|
|
|
211
217
|
.. manim:: ChangedDefaultTextcolor
|
|
212
218
|
:save_last_frame:
|
|
@@ -1377,7 +1383,7 @@ class OpenGLMobject:
|
|
|
1377
1383
|
return list(it.chain(*(sm.get_updaters() for sm in self.get_family())))
|
|
1378
1384
|
|
|
1379
1385
|
def add_updater(self, update_function, index=None, call_updater=False):
|
|
1380
|
-
if "dt" in
|
|
1386
|
+
if "dt" in inspect.signature(update_function).parameters:
|
|
1381
1387
|
updater_list = self.time_based_updaters
|
|
1382
1388
|
else:
|
|
1383
1389
|
updater_list = self.non_time_updaters
|
|
@@ -1971,12 +1977,12 @@ class OpenGLMobject:
|
|
|
1971
1977
|
for mob in self.get_family(recurse):
|
|
1972
1978
|
mob.data[name] = rgbas.copy()
|
|
1973
1979
|
|
|
1974
|
-
def set_color(self, color, opacity=None, recurse=True):
|
|
1980
|
+
def set_color(self, color: ParsableManimColor | None, opacity=None, recurse=True):
|
|
1975
1981
|
self.set_rgba_array(color, opacity, recurse=False)
|
|
1976
1982
|
# Recurse to submobjects differently from how set_rgba_array
|
|
1977
1983
|
# in case they implement set_color differently
|
|
1978
1984
|
if color is not None:
|
|
1979
|
-
self.color =
|
|
1985
|
+
self.color: ManimColor = ManimColor.parse(color)
|
|
1980
1986
|
if opacity is not None:
|
|
1981
1987
|
self.opacity = opacity
|
|
1982
1988
|
if recurse:
|
|
@@ -2037,7 +2043,7 @@ class OpenGLMobject:
|
|
|
2037
2043
|
# Background rectangle
|
|
2038
2044
|
|
|
2039
2045
|
def add_background_rectangle(
|
|
2040
|
-
self, color:
|
|
2046
|
+
self, color: ParsableManimColor | None = None, opacity: float = 0.75, **kwargs
|
|
2041
2047
|
):
|
|
2042
2048
|
# TODO, this does not behave well when the mobject has points,
|
|
2043
2049
|
# since it gets displayed on top
|
|
@@ -2725,7 +2731,7 @@ class OpenGLMobject:
|
|
|
2725
2731
|
|
|
2726
2732
|
class OpenGLGroup(OpenGLMobject):
|
|
2727
2733
|
def __init__(self, *mobjects, **kwargs):
|
|
2728
|
-
if not all(
|
|
2734
|
+
if not all(isinstance(m, OpenGLMobject) for m in mobjects):
|
|
2729
2735
|
raise Exception("All submobjects must be of type OpenGLMobject")
|
|
2730
2736
|
super().__init__(**kwargs)
|
|
2731
2737
|
self.add(*mobjects)
|
|
@@ -162,7 +162,7 @@ class OpenGLPMobject(OpenGLMobject):
|
|
|
162
162
|
|
|
163
163
|
class OpenGLPGroup(OpenGLPMobject):
|
|
164
164
|
def __init__(self, *pmobs, **kwargs):
|
|
165
|
-
if not all(
|
|
165
|
+
if not all(isinstance(m, OpenGLPMobject) for m in pmobs):
|
|
166
166
|
raise Exception("All submobjects must be of type OpenglPMObject")
|
|
167
167
|
super().__init__(**kwargs)
|
|
168
168
|
self.add(*pmobs)
|
|
@@ -380,7 +380,7 @@ class OpenGLTexturedSurface(OpenGLSurface):
|
|
|
380
380
|
|
|
381
381
|
if not isinstance(uv_surface, OpenGLSurface):
|
|
382
382
|
raise Exception("uv_surface must be of type OpenGLSurface")
|
|
383
|
-
if
|
|
383
|
+
if isinstance(image_file, np.ndarray):
|
|
384
384
|
image_file = change_to_rgba_array(image_file)
|
|
385
385
|
|
|
386
386
|
# Set texture information
|
|
@@ -3,11 +3,10 @@ from __future__ import annotations
|
|
|
3
3
|
import itertools as it
|
|
4
4
|
import operator as op
|
|
5
5
|
from functools import reduce, wraps
|
|
6
|
-
from typing import Callable, Iterable,
|
|
6
|
+
from typing import Callable, Iterable, Sequence
|
|
7
7
|
|
|
8
8
|
import moderngl
|
|
9
9
|
import numpy as np
|
|
10
|
-
from colour import Color
|
|
11
10
|
|
|
12
11
|
from manim import config
|
|
13
12
|
from manim.constants import *
|
|
@@ -23,7 +22,7 @@ from manim.utils.bezier import (
|
|
|
23
22
|
proportions_along_bezier_curve_for_point,
|
|
24
23
|
quadratic_bezier_remap,
|
|
25
24
|
)
|
|
26
|
-
from manim.utils.color import
|
|
25
|
+
from manim.utils.color import BLACK, WHITE, ManimColor, ParsableManimColor
|
|
27
26
|
from manim.utils.config_ops import _Data
|
|
28
27
|
from manim.utils.iterables import listify, make_even, resize_with_interpolation
|
|
29
28
|
from manim.utils.space_ops import (
|
|
@@ -81,9 +80,9 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
81
80
|
|
|
82
81
|
def __init__(
|
|
83
82
|
self,
|
|
84
|
-
fill_color:
|
|
83
|
+
fill_color: ParsableManimColor | None = None,
|
|
85
84
|
fill_opacity: float = 0.0,
|
|
86
|
-
stroke_color:
|
|
85
|
+
stroke_color: ParsableManimColor | None = None,
|
|
87
86
|
stroke_opacity: float = 1.0,
|
|
88
87
|
stroke_width: float = DEFAULT_STROKE_WIDTH,
|
|
89
88
|
draw_stroke_behind_fill: bool = False,
|
|
@@ -137,6 +136,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
137
136
|
self.needs_new_triangulation = True
|
|
138
137
|
self.triangulation = np.zeros(0, dtype="i4")
|
|
139
138
|
self.orientation = 1
|
|
139
|
+
|
|
140
140
|
self.fill_data = None
|
|
141
141
|
self.stroke_data = None
|
|
142
142
|
self.fill_shader_wrapper = None
|
|
@@ -146,10 +146,10 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
146
146
|
super().__init__(**kwargs)
|
|
147
147
|
self.refresh_unit_normal()
|
|
148
148
|
|
|
149
|
-
if fill_color:
|
|
150
|
-
self.fill_color =
|
|
151
|
-
if stroke_color:
|
|
152
|
-
self.stroke_color =
|
|
149
|
+
if fill_color is not None:
|
|
150
|
+
self.fill_color = ManimColor.parse(fill_color)
|
|
151
|
+
if stroke_color is not None:
|
|
152
|
+
self.stroke_color = ManimColor.parse(stroke_color)
|
|
153
153
|
|
|
154
154
|
def get_group_class(self):
|
|
155
155
|
return OpenGLVGroup
|
|
@@ -184,7 +184,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
184
184
|
|
|
185
185
|
def set_fill(
|
|
186
186
|
self,
|
|
187
|
-
color:
|
|
187
|
+
color: ParsableManimColor | None = None,
|
|
188
188
|
opacity: float | None = None,
|
|
189
189
|
recurse: bool = True,
|
|
190
190
|
) -> OpenGLVMobject:
|
|
@@ -350,14 +350,15 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
350
350
|
super().fade(darkness, recurse)
|
|
351
351
|
return self
|
|
352
352
|
|
|
353
|
+
# Todo im not quite sure why we are doing this
|
|
353
354
|
def get_fill_colors(self):
|
|
354
|
-
return [
|
|
355
|
+
return [ManimColor.from_rgb(rgba[:3]) for rgba in self.fill_rgba]
|
|
355
356
|
|
|
356
357
|
def get_fill_opacities(self):
|
|
357
358
|
return self.fill_rgba[:, 3]
|
|
358
359
|
|
|
359
360
|
def get_stroke_colors(self):
|
|
360
|
-
return [
|
|
361
|
+
return [ManimColor.from_rgb(rgba[:3]) for rgba in self.stroke_rgba]
|
|
361
362
|
|
|
362
363
|
def get_stroke_opacities(self):
|
|
363
364
|
return self.stroke_rgba[:, 3]
|
|
@@ -1283,14 +1284,17 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1283
1284
|
for _ in range(-diff):
|
|
1284
1285
|
ipc[np.argmax(ipc)] -= 1
|
|
1285
1286
|
|
|
1286
|
-
|
|
1287
|
+
new_length = sum(x + 1 for x in ipc)
|
|
1288
|
+
new_points = np.empty((new_length, nppc, 3))
|
|
1289
|
+
i = 0
|
|
1287
1290
|
for group, n_inserts in zip(bezier_groups, ipc):
|
|
1288
1291
|
# What was once a single quadratic curve defined
|
|
1289
1292
|
# by "group" will now be broken into n_inserts + 1
|
|
1290
1293
|
# smaller quadratic curves
|
|
1291
1294
|
alphas = np.linspace(0, 1, n_inserts + 2)
|
|
1292
1295
|
for a1, a2 in zip(alphas, alphas[1:]):
|
|
1293
|
-
new_points
|
|
1296
|
+
new_points[i] = partial_quadratic_bezier_points(group, a1, a2)
|
|
1297
|
+
i = i + 1
|
|
1294
1298
|
return np.vstack(new_points)
|
|
1295
1299
|
|
|
1296
1300
|
def interpolate(self, mobject1, mobject2, alpha, *args, **kwargs):
|
|
@@ -1301,7 +1305,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1301
1305
|
if self.has_fill():
|
|
1302
1306
|
tri1 = mobject1.get_triangulation()
|
|
1303
1307
|
tri2 = mobject2.get_triangulation()
|
|
1304
|
-
if len(tri1) != len(
|
|
1308
|
+
if len(tri1) != len(tri2) or not np.all(tri1 == tri2):
|
|
1305
1309
|
self.refresh_triangulation()
|
|
1306
1310
|
return self
|
|
1307
1311
|
|
|
@@ -1676,7 +1680,7 @@ class OpenGLVGroup(OpenGLVMobject):
|
|
|
1676
1680
|
"""
|
|
1677
1681
|
|
|
1678
1682
|
def __init__(self, *vmobjects, **kwargs):
|
|
1679
|
-
if not all(
|
|
1683
|
+
if not all(isinstance(m, OpenGLVMobject) for m in vmobjects):
|
|
1680
1684
|
raise Exception("All submobjects must be of type OpenGLVMobject")
|
|
1681
1685
|
super().__init__(**kwargs)
|
|
1682
1686
|
self.add(*vmobjects)
|
|
@@ -1881,7 +1885,7 @@ class OpenGLDashedVMobject(OpenGLVMobject):
|
|
|
1881
1885
|
vmobject: OpenGLVMobject,
|
|
1882
1886
|
num_dashes: int = 15,
|
|
1883
1887
|
dashed_ratio: float = 0.5,
|
|
1884
|
-
color:
|
|
1888
|
+
color: ParsableManimColor = WHITE,
|
|
1885
1889
|
**kwargs,
|
|
1886
1890
|
):
|
|
1887
1891
|
self.dashed_ratio = dashed_ratio
|
manim/mobject/svg/brace.py
CHANGED
|
@@ -335,10 +335,12 @@ class ArcBrace(Brace):
|
|
|
335
335
|
|
|
336
336
|
def __init__(
|
|
337
337
|
self,
|
|
338
|
-
arc: Arc
|
|
338
|
+
arc: Arc | None = None,
|
|
339
339
|
direction: Sequence[float] = RIGHT,
|
|
340
340
|
**kwargs,
|
|
341
341
|
):
|
|
342
|
+
if arc is None:
|
|
343
|
+
arc = Arc(start_angle=-1, angle=2, radius=1)
|
|
342
344
|
arc_end_angle = arc.start_angle + arc.angle
|
|
343
345
|
line = Line(UP * arc.start_angle, UP * arc_end_angle)
|
|
344
346
|
scale_shift = RIGHT * np.log(arc.radius)
|
manim/mobject/svg/svg_mobject.py
CHANGED
|
@@ -280,7 +280,7 @@ class SVGMobject(VMobject, metaclass=ConvertToOpenGL):
|
|
|
280
280
|
mob = self.polyline_to_mobject(shape)
|
|
281
281
|
elif isinstance(shape, se.Text):
|
|
282
282
|
mob = self.text_to_mobject(shape)
|
|
283
|
-
elif isinstance(shape, se.Use) or type(shape)
|
|
283
|
+
elif isinstance(shape, se.Use) or type(shape) is se.SVGElement:
|
|
284
284
|
continue
|
|
285
285
|
else:
|
|
286
286
|
logger.warning(f"Unsupported element type: {type(shape)}")
|
|
@@ -510,17 +510,15 @@ class VMobjectFromSVGPath(VMobject, metaclass=ConvertToOpenGL):
|
|
|
510
510
|
all_points: list[np.ndarray] = []
|
|
511
511
|
last_move = None
|
|
512
512
|
curve_start = None
|
|
513
|
+
last_true_move = None
|
|
513
514
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
# of updating this Mobject's numpy array of points. This way,
|
|
517
|
-
# we don't observe O(n^2) behavior for complex paths due to
|
|
518
|
-
# numpy's need to re-allocate memory on every append.
|
|
519
|
-
def move_pen(pt):
|
|
520
|
-
nonlocal last_move, curve_start
|
|
515
|
+
def move_pen(pt, *, true_move: bool = False):
|
|
516
|
+
nonlocal last_move, curve_start, last_true_move
|
|
521
517
|
last_move = pt
|
|
522
518
|
if curve_start is None:
|
|
523
519
|
curve_start = last_move
|
|
520
|
+
if true_move:
|
|
521
|
+
last_true_move = last_move
|
|
524
522
|
|
|
525
523
|
if self.n_points_per_curve == 4:
|
|
526
524
|
|
|
@@ -568,7 +566,7 @@ class VMobjectFromSVGPath(VMobject, metaclass=ConvertToOpenGL):
|
|
|
568
566
|
for segment in self.path_obj:
|
|
569
567
|
segment_class = segment.__class__
|
|
570
568
|
if segment_class == se.Move:
|
|
571
|
-
move_pen(_convert_point_to_3d(*segment.end))
|
|
569
|
+
move_pen(_convert_point_to_3d(*segment.end), true_move=True)
|
|
572
570
|
elif segment_class == se.Line:
|
|
573
571
|
add_line(last_move, _convert_point_to_3d(*segment.end))
|
|
574
572
|
elif segment_class == se.QuadraticBezier:
|
|
@@ -588,8 +586,8 @@ class VMobjectFromSVGPath(VMobject, metaclass=ConvertToOpenGL):
|
|
|
588
586
|
# If the SVG path naturally ends at the beginning of the curve,
|
|
589
587
|
# we do *not* need to draw a closing line. To account for floating
|
|
590
588
|
# point precision, we use a small value to compare the two points.
|
|
591
|
-
if abs(np.linalg.norm(last_move -
|
|
592
|
-
add_line(last_move,
|
|
589
|
+
if abs(np.linalg.norm(last_move - last_true_move)) > 0.0001:
|
|
590
|
+
add_line(last_move, last_true_move)
|
|
593
591
|
curve_start = None
|
|
594
592
|
else:
|
|
595
593
|
raise AssertionError(f"Not implemented: {segment_class}")
|
manim/mobject/table.py
CHANGED
|
@@ -67,8 +67,6 @@ __all__ = [
|
|
|
67
67
|
import itertools as it
|
|
68
68
|
from typing import Callable, Iterable, Sequence
|
|
69
69
|
|
|
70
|
-
from colour import Color
|
|
71
|
-
|
|
72
70
|
from manim.mobject.geometry.line import Line
|
|
73
71
|
from manim.mobject.geometry.polygram import Polygon
|
|
74
72
|
from manim.mobject.geometry.shape_matchers import BackgroundRectangle
|
|
@@ -82,13 +80,50 @@ from ..animation.composition import AnimationGroup
|
|
|
82
80
|
from ..animation.creation import Create, Write
|
|
83
81
|
from ..animation.fading import FadeIn
|
|
84
82
|
from ..mobject.types.vectorized_mobject import VGroup, VMobject
|
|
85
|
-
from ..utils.color import BLACK, YELLOW
|
|
83
|
+
from ..utils.color import BLACK, YELLOW, ManimColor, ParsableManimColor
|
|
86
84
|
from .utils import get_vectorized_mobject_class
|
|
87
85
|
|
|
88
86
|
|
|
89
87
|
class Table(VGroup):
|
|
90
88
|
"""A mobject that displays a table on the screen.
|
|
91
89
|
|
|
90
|
+
Parameters
|
|
91
|
+
----------
|
|
92
|
+
table
|
|
93
|
+
A 2D array or list of lists. Content of the table has to be a valid input
|
|
94
|
+
for the callable set in ``element_to_mobject``.
|
|
95
|
+
row_labels
|
|
96
|
+
List of :class:`~.VMobject` representing the labels of each row.
|
|
97
|
+
col_labels
|
|
98
|
+
List of :class:`~.VMobject` representing the labels of each column.
|
|
99
|
+
top_left_entry
|
|
100
|
+
The top-left entry of the table, can only be specified if row and
|
|
101
|
+
column labels are given.
|
|
102
|
+
v_buff
|
|
103
|
+
Vertical buffer passed to :meth:`~.Mobject.arrange_in_grid`, by default 0.8.
|
|
104
|
+
h_buff
|
|
105
|
+
Horizontal buffer passed to :meth:`~.Mobject.arrange_in_grid`, by default 1.3.
|
|
106
|
+
include_outer_lines
|
|
107
|
+
``True`` if the table should include outer lines, by default False.
|
|
108
|
+
add_background_rectangles_to_entries
|
|
109
|
+
``True`` if background rectangles should be added to entries, by default ``False``.
|
|
110
|
+
entries_background_color
|
|
111
|
+
Background color of entries if ``add_background_rectangles_to_entries`` is ``True``.
|
|
112
|
+
include_background_rectangle
|
|
113
|
+
``True`` if the table should have a background rectangle, by default ``False``.
|
|
114
|
+
background_rectangle_color
|
|
115
|
+
Background color of table if ``include_background_rectangle`` is ``True``.
|
|
116
|
+
element_to_mobject
|
|
117
|
+
The :class:`~.Mobject` class applied to the table entries. by default :class:`~.Paragraph`. For common choices, see :mod:`~.text_mobject`/:mod:`~.tex_mobject`.
|
|
118
|
+
element_to_mobject_config
|
|
119
|
+
Custom configuration passed to :attr:`element_to_mobject`, by default {}.
|
|
120
|
+
arrange_in_grid_config
|
|
121
|
+
Dict passed to :meth:`~.Mobject.arrange_in_grid`, customizes the arrangement of the table.
|
|
122
|
+
line_config
|
|
123
|
+
Dict passed to :class:`~.Line`, customizes the lines of the table.
|
|
124
|
+
kwargs
|
|
125
|
+
Additional arguments to be passed to :class:`~.VGroup`.
|
|
126
|
+
|
|
92
127
|
Examples
|
|
93
128
|
--------
|
|
94
129
|
|
|
@@ -160,9 +195,9 @@ class Table(VGroup):
|
|
|
160
195
|
h_buff: float = 1.3,
|
|
161
196
|
include_outer_lines: bool = False,
|
|
162
197
|
add_background_rectangles_to_entries: bool = False,
|
|
163
|
-
entries_background_color:
|
|
198
|
+
entries_background_color: ParsableManimColor = BLACK,
|
|
164
199
|
include_background_rectangle: bool = False,
|
|
165
|
-
background_rectangle_color:
|
|
200
|
+
background_rectangle_color: ParsableManimColor = BLACK,
|
|
166
201
|
element_to_mobject: Callable[
|
|
167
202
|
[float | str | VMobject],
|
|
168
203
|
VMobject,
|
|
@@ -172,45 +207,6 @@ class Table(VGroup):
|
|
|
172
207
|
line_config: dict = {},
|
|
173
208
|
**kwargs,
|
|
174
209
|
):
|
|
175
|
-
"""
|
|
176
|
-
Parameters
|
|
177
|
-
----------
|
|
178
|
-
table
|
|
179
|
-
A 2D array or list of lists. Content of the table has to be a valid input
|
|
180
|
-
for the callable set in ``element_to_mobject``.
|
|
181
|
-
row_labels
|
|
182
|
-
List of :class:`~.VMobject` representing the labels of each row.
|
|
183
|
-
col_labels
|
|
184
|
-
List of :class:`~.VMobject` representing the labels of each column.
|
|
185
|
-
top_left_entry
|
|
186
|
-
The top-left entry of the table, can only be specified if row and
|
|
187
|
-
column labels are given.
|
|
188
|
-
v_buff
|
|
189
|
-
Vertical buffer passed to :meth:`~.Mobject.arrange_in_grid`, by default 0.8.
|
|
190
|
-
h_buff
|
|
191
|
-
Horizontal buffer passed to :meth:`~.Mobject.arrange_in_grid`, by default 1.3.
|
|
192
|
-
include_outer_lines
|
|
193
|
-
``True`` if the table should include outer lines, by default False.
|
|
194
|
-
add_background_rectangles_to_entries
|
|
195
|
-
``True`` if background rectangles should be added to entries, by default ``False``.
|
|
196
|
-
entries_background_color
|
|
197
|
-
Background color of entries if ``add_background_rectangles_to_entries`` is ``True``.
|
|
198
|
-
include_background_rectangle
|
|
199
|
-
``True`` if the table should have a background rectangle, by default ``False``.
|
|
200
|
-
background_rectangle_color
|
|
201
|
-
Background color of table if ``include_background_rectangle`` is ``True``.
|
|
202
|
-
element_to_mobject
|
|
203
|
-
The :class:`~.Mobject` class applied to the table entries. by default :class:`~.Paragraph`. For common choices, see :mod:`~.text_mobject`/:mod:`~.tex_mobject`.
|
|
204
|
-
element_to_mobject_config
|
|
205
|
-
Custom configuration passed to :attr:`element_to_mobject`, by default {}.
|
|
206
|
-
arrange_in_grid_config
|
|
207
|
-
Dict passed to :meth:`~.Mobject.arrange_in_grid`, customizes the arrangement of the table.
|
|
208
|
-
line_config
|
|
209
|
-
Dict passed to :class:`~.Line`, customizes the lines of the table.
|
|
210
|
-
kwargs
|
|
211
|
-
Additional arguments to be passed to :class:`~.VGroup`.
|
|
212
|
-
"""
|
|
213
|
-
|
|
214
210
|
self.row_labels = row_labels
|
|
215
211
|
self.col_labels = col_labels
|
|
216
212
|
self.top_left_entry = top_left_entry
|
|
@@ -220,9 +216,9 @@ class Table(VGroup):
|
|
|
220
216
|
self.h_buff = h_buff
|
|
221
217
|
self.include_outer_lines = include_outer_lines
|
|
222
218
|
self.add_background_rectangles_to_entries = add_background_rectangles_to_entries
|
|
223
|
-
self.entries_background_color = entries_background_color
|
|
219
|
+
self.entries_background_color = ManimColor(entries_background_color)
|
|
224
220
|
self.include_background_rectangle = include_background_rectangle
|
|
225
|
-
self.background_rectangle_color = background_rectangle_color
|
|
221
|
+
self.background_rectangle_color = ManimColor(background_rectangle_color)
|
|
226
222
|
self.element_to_mobject = element_to_mobject
|
|
227
223
|
self.element_to_mobject_config = element_to_mobject_config
|
|
228
224
|
self.arrange_in_grid_config = arrange_in_grid_config
|
|
@@ -506,7 +502,7 @@ class Table(VGroup):
|
|
|
506
502
|
"""
|
|
507
503
|
return VGroup(*(VGroup(*row) for row in self.mob_table))
|
|
508
504
|
|
|
509
|
-
def set_column_colors(self, *colors: Iterable[
|
|
505
|
+
def set_column_colors(self, *colors: Iterable[ParsableManimColor]) -> Table:
|
|
510
506
|
"""Set individual colors for each column of the table.
|
|
511
507
|
|
|
512
508
|
Parameters
|
|
@@ -535,7 +531,7 @@ class Table(VGroup):
|
|
|
535
531
|
column.set_color(color)
|
|
536
532
|
return self
|
|
537
533
|
|
|
538
|
-
def set_row_colors(self, *colors: Iterable[
|
|
534
|
+
def set_row_colors(self, *colors: Iterable[ParsableManimColor]) -> Table:
|
|
539
535
|
"""Set individual colors for each row of the table.
|
|
540
536
|
|
|
541
537
|
Parameters
|
|
@@ -754,10 +750,10 @@ class Table(VGroup):
|
|
|
754
750
|
label_group.add(*label)
|
|
755
751
|
return label_group
|
|
756
752
|
|
|
757
|
-
def add_background_to_entries(self, color:
|
|
753
|
+
def add_background_to_entries(self, color: ParsableManimColor = BLACK) -> Table:
|
|
758
754
|
"""Adds a black :class:`~.BackgroundRectangle` to each entry of the table."""
|
|
759
755
|
for mob in self.get_entries():
|
|
760
|
-
mob.add_background_rectangle(color=color)
|
|
756
|
+
mob.add_background_rectangle(color=ManimColor(color))
|
|
761
757
|
return self
|
|
762
758
|
|
|
763
759
|
def get_cell(self, pos: Sequence[int] = (1, 1), **kwargs) -> Polygon:
|
|
@@ -818,7 +814,7 @@ class Table(VGroup):
|
|
|
818
814
|
return rec
|
|
819
815
|
|
|
820
816
|
def get_highlighted_cell(
|
|
821
|
-
self, pos: Sequence[int] = (1, 1), color:
|
|
817
|
+
self, pos: Sequence[int] = (1, 1), color: ParsableManimColor = YELLOW, **kwargs
|
|
822
818
|
) -> BackgroundRectangle:
|
|
823
819
|
"""Returns a :class:`~.BackgroundRectangle` of the cell at the given position.
|
|
824
820
|
|
|
@@ -850,11 +846,11 @@ class Table(VGroup):
|
|
|
850
846
|
self.add(table)
|
|
851
847
|
"""
|
|
852
848
|
cell = self.get_cell(pos)
|
|
853
|
-
bg_cell = BackgroundRectangle(cell, color=color, **kwargs)
|
|
849
|
+
bg_cell = BackgroundRectangle(cell, color=ManimColor(color), **kwargs)
|
|
854
850
|
return bg_cell
|
|
855
851
|
|
|
856
852
|
def add_highlighted_cell(
|
|
857
|
-
self, pos: Sequence[int] = (1, 1), color:
|
|
853
|
+
self, pos: Sequence[int] = (1, 1), color: ParsableManimColor = YELLOW, **kwargs
|
|
858
854
|
) -> Table:
|
|
859
855
|
"""Highlights one cell at a specific position on the table by adding a :class:`~.BackgroundRectangle`.
|
|
860
856
|
|
|
@@ -884,7 +880,7 @@ class Table(VGroup):
|
|
|
884
880
|
table.add_highlighted_cell((2,2), color=GREEN)
|
|
885
881
|
self.add(table)
|
|
886
882
|
"""
|
|
887
|
-
bg_cell = self.get_highlighted_cell(pos, color=color, **kwargs)
|
|
883
|
+
bg_cell = self.get_highlighted_cell(pos, color=ManimColor(color), **kwargs)
|
|
888
884
|
self.add_to_back(bg_cell)
|
|
889
885
|
entry = self.get_entries(pos)
|
|
890
886
|
entry.background_rectangle = bg_cell
|
manim/mobject/text/numbers.py
CHANGED
|
@@ -22,6 +22,34 @@ string_to_mob_map = {}
|
|
|
22
22
|
class DecimalNumber(VMobject, metaclass=ConvertToOpenGL):
|
|
23
23
|
"""An mobject representing a decimal number.
|
|
24
24
|
|
|
25
|
+
Parameters
|
|
26
|
+
----------
|
|
27
|
+
number
|
|
28
|
+
The numeric value to be displayed. It can later be modified using :meth:`.set_value`.
|
|
29
|
+
num_decimal_places
|
|
30
|
+
The number of decimal places after the decimal separator. Values are automatically rounded.
|
|
31
|
+
mob_class
|
|
32
|
+
The class for rendering digits and units, by default :class:`.MathTex`.
|
|
33
|
+
include_sign
|
|
34
|
+
Set to ``True`` to include a sign for positive numbers and zero.
|
|
35
|
+
group_with_commas
|
|
36
|
+
When ``True`` thousands groups are separated by commas for readability.
|
|
37
|
+
digit_buff_per_font_unit
|
|
38
|
+
Additional spacing between digits. Scales with font size.
|
|
39
|
+
show_ellipsis
|
|
40
|
+
When a number has been truncated by rounding, indicate with an ellipsis (``...``).
|
|
41
|
+
unit
|
|
42
|
+
A unit string which can be placed to the right of the numerical values.
|
|
43
|
+
unit_buff_per_font_unit
|
|
44
|
+
An additional spacing between the numerical values and the unit. A value
|
|
45
|
+
of ``unit_buff_per_font_unit=0.003`` gives a decent spacing. Scales with font size.
|
|
46
|
+
include_background_rectangle
|
|
47
|
+
Adds a background rectangle to increase contrast on busy scenes.
|
|
48
|
+
edge_to_fix
|
|
49
|
+
Assuring right- or left-alignment of the full object.
|
|
50
|
+
font_size
|
|
51
|
+
Size of the font.
|
|
52
|
+
|
|
25
53
|
Examples
|
|
26
54
|
--------
|
|
27
55
|
|
|
@@ -34,6 +62,8 @@ class DecimalNumber(VMobject, metaclass=ConvertToOpenGL):
|
|
|
34
62
|
show_ellipsis=True,
|
|
35
63
|
num_decimal_places=3,
|
|
36
64
|
include_sign=True,
|
|
65
|
+
unit=r"\text{M-Units}",
|
|
66
|
+
unit_buff_per_font_unit=0.003
|
|
37
67
|
)
|
|
38
68
|
square = Square().to_edge(UP)
|
|
39
69
|
|
|
@@ -59,6 +89,7 @@ class DecimalNumber(VMobject, metaclass=ConvertToOpenGL):
|
|
|
59
89
|
digit_buff_per_font_unit: float = 0.001,
|
|
60
90
|
show_ellipsis: bool = False,
|
|
61
91
|
unit: str | None = None, # Aligned to bottom unless it starts with "^"
|
|
92
|
+
unit_buff_per_font_unit: float = 0,
|
|
62
93
|
include_background_rectangle: bool = False,
|
|
63
94
|
edge_to_fix: Sequence[float] = LEFT,
|
|
64
95
|
font_size: float = DEFAULT_FONT_SIZE,
|
|
@@ -66,7 +97,7 @@ class DecimalNumber(VMobject, metaclass=ConvertToOpenGL):
|
|
|
66
97
|
fill_opacity: float = 1.0,
|
|
67
98
|
**kwargs,
|
|
68
99
|
):
|
|
69
|
-
super().__init__(**kwargs)
|
|
100
|
+
super().__init__(**kwargs, stroke_width=stroke_width)
|
|
70
101
|
self.number = number
|
|
71
102
|
self.num_decimal_places = num_decimal_places
|
|
72
103
|
self.include_sign = include_sign
|
|
@@ -75,10 +106,10 @@ class DecimalNumber(VMobject, metaclass=ConvertToOpenGL):
|
|
|
75
106
|
self.digit_buff_per_font_unit = digit_buff_per_font_unit
|
|
76
107
|
self.show_ellipsis = show_ellipsis
|
|
77
108
|
self.unit = unit
|
|
109
|
+
self.unit_buff_per_font_unit = unit_buff_per_font_unit
|
|
78
110
|
self.include_background_rectangle = include_background_rectangle
|
|
79
111
|
self.edge_to_fix = edge_to_fix
|
|
80
112
|
self._font_size = font_size
|
|
81
|
-
self.stroke_width = stroke_width
|
|
82
113
|
self.fill_opacity = fill_opacity
|
|
83
114
|
|
|
84
115
|
self.initial_config = kwargs.copy()
|
|
@@ -90,6 +121,7 @@ class DecimalNumber(VMobject, metaclass=ConvertToOpenGL):
|
|
|
90
121
|
"digit_buff_per_font_unit": digit_buff_per_font_unit,
|
|
91
122
|
"show_ellipsis": show_ellipsis,
|
|
92
123
|
"unit": unit,
|
|
124
|
+
"unit_buff_per_font_unit": unit_buff_per_font_unit,
|
|
93
125
|
"include_background_rectangle": include_background_rectangle,
|
|
94
126
|
"edge_to_fix": edge_to_fix,
|
|
95
127
|
"font_size": font_size,
|
|
@@ -131,15 +163,25 @@ class DecimalNumber(VMobject, metaclass=ConvertToOpenGL):
|
|
|
131
163
|
self._string_to_mob("\\dots", SingleStringMathTex, color=self.color),
|
|
132
164
|
)
|
|
133
165
|
|
|
134
|
-
if self.unit is not None:
|
|
135
|
-
self.unit_sign = self._string_to_mob(self.unit, SingleStringMathTex)
|
|
136
|
-
self.add(self.unit_sign)
|
|
137
|
-
|
|
138
166
|
self.arrange(
|
|
139
167
|
buff=self.digit_buff_per_font_unit * self._font_size,
|
|
140
168
|
aligned_edge=DOWN,
|
|
141
169
|
)
|
|
142
170
|
|
|
171
|
+
if self.unit is not None:
|
|
172
|
+
self.unit_sign = self._string_to_mob(self.unit, SingleStringMathTex)
|
|
173
|
+
self.add(
|
|
174
|
+
self.unit_sign.next_to(
|
|
175
|
+
self,
|
|
176
|
+
direction=RIGHT,
|
|
177
|
+
buff=(self.unit_buff_per_font_unit + self.digit_buff_per_font_unit)
|
|
178
|
+
* self._font_size,
|
|
179
|
+
aligned_edge=DOWN,
|
|
180
|
+
)
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
self.move_to(ORIGIN)
|
|
184
|
+
|
|
143
185
|
# Handle alignment of parts that should be aligned
|
|
144
186
|
# to the bottom
|
|
145
187
|
for i, c in enumerate(num_string):
|