manim 0.17.0__py3-none-any.whl → 0.19.1__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.
- manim/__init__.py +11 -6
- manim/__main__.py +62 -19
- manim/_config/__init__.py +10 -9
- manim/_config/cli_colors.py +26 -9
- manim/_config/default.cfg +1 -3
- manim/_config/logger_utils.py +23 -13
- manim/_config/utils.py +662 -468
- manim/animation/animation.py +164 -18
- manim/animation/changing.py +34 -23
- manim/animation/composition.py +265 -67
- manim/animation/creation.py +208 -26
- manim/animation/fading.py +16 -18
- manim/animation/growing.py +35 -15
- manim/animation/indication.py +150 -76
- manim/animation/movement.py +56 -22
- manim/animation/numbers.py +64 -6
- manim/animation/rotation.py +78 -7
- manim/animation/specialized.py +6 -7
- manim/animation/speedmodifier.py +13 -10
- manim/animation/transform.py +14 -11
- manim/animation/transform_matching_parts.py +3 -4
- manim/animation/updaters/mobject_update_utils.py +152 -30
- manim/animation/updaters/update.py +10 -7
- manim/camera/camera.py +182 -118
- manim/camera/mapping_camera.py +34 -3
- manim/camera/moving_camera.py +95 -74
- manim/camera/multi_camera.py +23 -15
- manim/camera/three_d_camera.py +70 -52
- manim/cli/__init__.py +17 -0
- manim/cli/cfg/group.py +76 -44
- manim/cli/checkhealth/checks.py +192 -0
- manim/cli/checkhealth/commands.py +90 -0
- manim/cli/default_group.py +158 -25
- manim/cli/init/commands.py +33 -25
- manim/cli/plugins/commands.py +16 -3
- manim/cli/render/commands.py +72 -60
- manim/cli/render/ease_of_access_options.py +4 -3
- manim/cli/render/global_options.py +59 -17
- manim/cli/render/output_options.py +6 -5
- manim/cli/render/render_options.py +98 -33
- manim/constants.py +109 -59
- manim/data_structures.py +31 -0
- manim/mobject/frame.py +8 -5
- manim/mobject/geometry/__init__.py +1 -0
- manim/mobject/geometry/arc.py +277 -135
- manim/mobject/geometry/boolean_ops.py +32 -31
- manim/mobject/geometry/labeled.py +376 -0
- manim/mobject/geometry/line.py +192 -87
- manim/mobject/geometry/polygram.py +224 -58
- manim/mobject/geometry/shape_matchers.py +61 -25
- manim/mobject/geometry/tips.py +122 -48
- manim/mobject/graph.py +1027 -419
- manim/mobject/graphing/coordinate_systems.py +533 -278
- manim/mobject/graphing/functions.py +53 -32
- manim/mobject/graphing/number_line.py +123 -65
- manim/mobject/graphing/probability.py +88 -62
- manim/mobject/graphing/scale.py +33 -19
- manim/mobject/logo.py +118 -28
- manim/mobject/matrix.py +87 -83
- manim/mobject/mobject.py +912 -442
- manim/mobject/opengl/dot_cloud.py +16 -5
- manim/mobject/opengl/opengl_compatibility.py +4 -2
- manim/mobject/opengl/opengl_geometry.py +254 -153
- manim/mobject/opengl/opengl_image_mobject.py +3 -1
- manim/mobject/opengl/opengl_mobject.py +779 -482
- manim/mobject/opengl/opengl_point_cloud_mobject.py +41 -14
- manim/mobject/opengl/opengl_surface.py +14 -92
- manim/mobject/opengl/opengl_three_dimensions.py +12 -8
- manim/mobject/opengl/opengl_vectorized_mobject.py +98 -100
- manim/mobject/svg/brace.py +173 -41
- manim/mobject/svg/svg_mobject.py +139 -53
- manim/mobject/table.py +61 -68
- manim/mobject/text/code_mobject.py +193 -539
- manim/mobject/text/numbers.py +81 -34
- manim/mobject/text/tex_mobject.py +130 -78
- manim/mobject/text/text_mobject.py +288 -164
- manim/mobject/three_d/polyhedra.py +111 -13
- manim/mobject/three_d/three_d_utils.py +17 -8
- manim/mobject/three_d/three_dimensions.py +239 -106
- manim/mobject/types/image_mobject.py +50 -30
- manim/mobject/types/point_cloud_mobject.py +120 -75
- manim/mobject/types/vectorized_mobject.py +841 -408
- manim/mobject/value_tracker.py +105 -38
- manim/mobject/vector_field.py +50 -31
- manim/opengl/__init__.py +3 -3
- manim/plugins/__init__.py +14 -1
- manim/plugins/plugins_flags.py +10 -14
- manim/renderer/cairo_renderer.py +65 -50
- manim/renderer/opengl_renderer.py +89 -69
- manim/renderer/opengl_renderer_window.py +39 -18
- manim/renderer/shader.py +123 -87
- manim/renderer/shader_wrapper.py +44 -28
- manim/renderer/vectorized_mobject_rendering.py +38 -10
- manim/scene/moving_camera_scene.py +32 -3
- manim/scene/scene.py +507 -242
- manim/scene/scene_file_writer.py +371 -220
- manim/scene/section.py +20 -16
- manim/scene/three_d_scene.py +14 -22
- manim/scene/vector_space_scene.py +223 -129
- manim/scene/zoomed_scene.py +46 -41
- manim/typing.py +990 -0
- manim/utils/bezier.py +1823 -371
- manim/utils/caching.py +12 -5
- manim/utils/color/AS2700.py +236 -0
- manim/utils/color/BS381.py +318 -0
- manim/utils/color/DVIPSNAMES.py +96 -0
- manim/utils/color/SVGNAMES.py +179 -0
- manim/utils/color/X11.py +533 -0
- manim/utils/color/XKCD.py +952 -0
- manim/utils/color/__init__.py +61 -0
- manim/utils/color/core.py +1667 -0
- manim/utils/color/manim_colors.py +218 -0
- manim/utils/commands.py +48 -20
- manim/utils/config_ops.py +39 -19
- manim/utils/debug.py +8 -7
- manim/utils/deprecation.py +86 -39
- manim/utils/docbuild/__init__.py +17 -0
- manim/utils/docbuild/autoaliasattr_directive.py +236 -0
- manim/utils/docbuild/autocolor_directive.py +99 -0
- manim/utils/docbuild/manim_directive.py +94 -41
- manim/utils/docbuild/module_parsing.py +245 -0
- manim/utils/exceptions.py +6 -0
- manim/utils/family.py +5 -3
- manim/utils/family_ops.py +17 -4
- manim/utils/file_ops.py +27 -17
- manim/utils/hashing.py +55 -45
- manim/utils/images.py +13 -7
- manim/utils/ipython_magic.py +13 -7
- manim/utils/iterables.py +163 -120
- manim/utils/module_ops.py +66 -24
- manim/utils/opengl.py +77 -24
- manim/utils/parameter_parsing.py +32 -0
- manim/utils/paths.py +30 -33
- manim/utils/polylabel.py +235 -0
- manim/utils/qhull.py +218 -0
- manim/utils/rate_functions.py +98 -32
- manim/utils/simple_functions.py +25 -33
- manim/utils/sounds.py +7 -1
- manim/utils/space_ops.py +188 -115
- manim/utils/testing/__init__.py +17 -0
- manim/utils/testing/_frames_testers.py +13 -8
- manim/utils/testing/_show_diff.py +5 -3
- manim/utils/testing/_test_class_makers.py +34 -18
- manim/utils/testing/frames_comparison.py +37 -19
- manim/utils/tex.py +130 -198
- manim/utils/tex_file_writing.py +77 -47
- manim/utils/tex_templates.py +2 -1
- manim/utils/unit.py +6 -5
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info}/METADATA +64 -65
- manim-0.19.1.dist-info/RECORD +220 -0
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info}/WHEEL +1 -1
- manim-0.19.1.dist-info/entry_points.txt +3 -0
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info/licenses}/LICENSE.community +1 -1
- manim/cli/new/group.py +0 -189
- manim/communitycolors.py +0 -9
- manim/gui/__init__.py +0 -0
- manim/gui/gui.py +0 -82
- manim/plugins/import_plugins.py +0 -43
- manim/utils/color.py +0 -552
- manim-0.17.0.dist-info/RECORD +0 -206
- manim-0.17.0.dist-info/entry_points.txt +0 -4
- /manim/cli/{new → checkhealth}/__init__.py +0 -0
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info/licenses}/LICENSE +0 -0
|
@@ -5,20 +5,20 @@ from __future__ import annotations
|
|
|
5
5
|
__all__ = ["SampleSpace", "BarChart"]
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
from
|
|
8
|
+
from collections.abc import Iterable, MutableSequence, Sequence
|
|
9
|
+
from typing import Any
|
|
9
10
|
|
|
10
11
|
import numpy as np
|
|
11
|
-
from colour import Color
|
|
12
12
|
|
|
13
13
|
from manim import config, logger
|
|
14
14
|
from manim.constants import *
|
|
15
15
|
from manim.mobject.geometry.polygram import Rectangle
|
|
16
16
|
from manim.mobject.graphing.coordinate_systems import Axes
|
|
17
|
-
from manim.mobject.
|
|
18
|
-
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
|
|
17
|
+
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject
|
|
19
18
|
from manim.mobject.svg.brace import Brace
|
|
20
19
|
from manim.mobject.text.tex_mobject import MathTex, Tex
|
|
21
20
|
from manim.mobject.types.vectorized_mobject import VGroup, VMobject
|
|
21
|
+
from manim.typing import Vector3D
|
|
22
22
|
from manim.utils.color import (
|
|
23
23
|
BLUE_E,
|
|
24
24
|
DARK_GREY,
|
|
@@ -26,6 +26,7 @@ from manim.utils.color import (
|
|
|
26
26
|
LIGHT_GREY,
|
|
27
27
|
MAROON_B,
|
|
28
28
|
YELLOW,
|
|
29
|
+
ParsableManimColor,
|
|
29
30
|
color_gradient,
|
|
30
31
|
)
|
|
31
32
|
from manim.utils.iterables import tuplify
|
|
@@ -34,7 +35,8 @@ EPSILON = 0.0001
|
|
|
34
35
|
|
|
35
36
|
|
|
36
37
|
class SampleSpace(Rectangle):
|
|
37
|
-
"""
|
|
38
|
+
"""A mobject representing a twodimensional rectangular
|
|
39
|
+
sampling space.
|
|
38
40
|
|
|
39
41
|
Examples
|
|
40
42
|
--------
|
|
@@ -53,13 +55,13 @@ class SampleSpace(Rectangle):
|
|
|
53
55
|
|
|
54
56
|
def __init__(
|
|
55
57
|
self,
|
|
56
|
-
height=3,
|
|
57
|
-
width=3,
|
|
58
|
-
fill_color=DARK_GREY,
|
|
59
|
-
fill_opacity=1,
|
|
60
|
-
stroke_width=0.5,
|
|
61
|
-
stroke_color=LIGHT_GREY,
|
|
62
|
-
default_label_scale_val=1,
|
|
58
|
+
height: float = 3,
|
|
59
|
+
width: float = 3,
|
|
60
|
+
fill_color: ParsableManimColor = DARK_GREY,
|
|
61
|
+
fill_opacity: float = 1,
|
|
62
|
+
stroke_width: float = 0.5,
|
|
63
|
+
stroke_color: ParsableManimColor = LIGHT_GREY,
|
|
64
|
+
default_label_scale_val: float = 1,
|
|
63
65
|
):
|
|
64
66
|
super().__init__(
|
|
65
67
|
height=height,
|
|
@@ -71,7 +73,9 @@ class SampleSpace(Rectangle):
|
|
|
71
73
|
)
|
|
72
74
|
self.default_label_scale_val = default_label_scale_val
|
|
73
75
|
|
|
74
|
-
def add_title(
|
|
76
|
+
def add_title(
|
|
77
|
+
self, title: str = "Sample space", buff: float = MED_SMALL_BUFF
|
|
78
|
+
) -> None:
|
|
75
79
|
# TODO, should this really exist in SampleSpaceScene
|
|
76
80
|
title_mob = Tex(title)
|
|
77
81
|
if title_mob.width > self.width:
|
|
@@ -80,23 +84,30 @@ class SampleSpace(Rectangle):
|
|
|
80
84
|
self.title = title_mob
|
|
81
85
|
self.add(title_mob)
|
|
82
86
|
|
|
83
|
-
def add_label(self, label):
|
|
87
|
+
def add_label(self, label: str) -> None:
|
|
84
88
|
self.label = label
|
|
85
89
|
|
|
86
|
-
def complete_p_list(self, p_list):
|
|
87
|
-
|
|
90
|
+
def complete_p_list(self, p_list: float | Iterable[float]) -> list[float]:
|
|
91
|
+
p_list_tuplified: tuple[float] = tuplify(p_list)
|
|
92
|
+
new_p_list = list(p_list_tuplified)
|
|
88
93
|
remainder = 1.0 - sum(new_p_list)
|
|
89
94
|
if abs(remainder) > EPSILON:
|
|
90
95
|
new_p_list.append(remainder)
|
|
91
96
|
return new_p_list
|
|
92
97
|
|
|
93
|
-
def get_division_along_dimension(
|
|
94
|
-
|
|
95
|
-
|
|
98
|
+
def get_division_along_dimension(
|
|
99
|
+
self,
|
|
100
|
+
p_list: float | Iterable[float],
|
|
101
|
+
dim: int,
|
|
102
|
+
colors: Sequence[ParsableManimColor],
|
|
103
|
+
vect: Vector3D,
|
|
104
|
+
) -> VGroup:
|
|
105
|
+
p_list_complete = self.complete_p_list(p_list)
|
|
106
|
+
colors_in_gradient = color_gradient(colors, len(p_list_complete))
|
|
96
107
|
|
|
97
108
|
last_point = self.get_edge_center(-vect)
|
|
98
109
|
parts = VGroup()
|
|
99
|
-
for factor, color in zip(
|
|
110
|
+
for factor, color in zip(p_list_complete, colors_in_gradient):
|
|
100
111
|
part = SampleSpace()
|
|
101
112
|
part.set_fill(color, 1)
|
|
102
113
|
part.replace(self, stretch=True)
|
|
@@ -106,33 +117,43 @@ class SampleSpace(Rectangle):
|
|
|
106
117
|
parts.add(part)
|
|
107
118
|
return parts
|
|
108
119
|
|
|
109
|
-
def get_horizontal_division(
|
|
120
|
+
def get_horizontal_division(
|
|
121
|
+
self,
|
|
122
|
+
p_list: float | Iterable[float],
|
|
123
|
+
colors: Sequence[ParsableManimColor] = [GREEN_E, BLUE_E],
|
|
124
|
+
vect: Vector3D = DOWN,
|
|
125
|
+
) -> VGroup:
|
|
110
126
|
return self.get_division_along_dimension(p_list, 1, colors, vect)
|
|
111
127
|
|
|
112
|
-
def get_vertical_division(
|
|
128
|
+
def get_vertical_division(
|
|
129
|
+
self,
|
|
130
|
+
p_list: float | Iterable[float],
|
|
131
|
+
colors: Sequence[ParsableManimColor] = [MAROON_B, YELLOW],
|
|
132
|
+
vect: Vector3D = RIGHT,
|
|
133
|
+
) -> VGroup:
|
|
113
134
|
return self.get_division_along_dimension(p_list, 0, colors, vect)
|
|
114
135
|
|
|
115
|
-
def divide_horizontally(self, *args, **kwargs):
|
|
136
|
+
def divide_horizontally(self, *args: Any, **kwargs: Any) -> None:
|
|
116
137
|
self.horizontal_parts = self.get_horizontal_division(*args, **kwargs)
|
|
117
138
|
self.add(self.horizontal_parts)
|
|
118
139
|
|
|
119
|
-
def divide_vertically(self, *args, **kwargs):
|
|
140
|
+
def divide_vertically(self, *args: Any, **kwargs: Any) -> None:
|
|
120
141
|
self.vertical_parts = self.get_vertical_division(*args, **kwargs)
|
|
121
142
|
self.add(self.vertical_parts)
|
|
122
143
|
|
|
123
144
|
def get_subdivision_braces_and_labels(
|
|
124
145
|
self,
|
|
125
|
-
parts,
|
|
126
|
-
labels,
|
|
127
|
-
direction,
|
|
128
|
-
buff=SMALL_BUFF,
|
|
129
|
-
min_num_quads=1,
|
|
130
|
-
):
|
|
146
|
+
parts: VGroup,
|
|
147
|
+
labels: list[str | VMobject | OpenGLVMobject],
|
|
148
|
+
direction: Vector3D,
|
|
149
|
+
buff: float = SMALL_BUFF,
|
|
150
|
+
min_num_quads: int = 1,
|
|
151
|
+
) -> VGroup:
|
|
131
152
|
label_mobs = VGroup()
|
|
132
153
|
braces = VGroup()
|
|
133
154
|
for label, part in zip(labels, parts):
|
|
134
155
|
brace = Brace(part, direction, min_num_quads=min_num_quads, buff=buff)
|
|
135
|
-
if isinstance(label, (
|
|
156
|
+
if isinstance(label, (VMobject, OpenGLVMobject)):
|
|
136
157
|
label_mob = label
|
|
137
158
|
else:
|
|
138
159
|
label_mob = MathTex(label)
|
|
@@ -140,34 +161,44 @@ class SampleSpace(Rectangle):
|
|
|
140
161
|
label_mob.next_to(brace, direction, buff)
|
|
141
162
|
|
|
142
163
|
braces.add(brace)
|
|
164
|
+
assert isinstance(label_mob, VMobject)
|
|
143
165
|
label_mobs.add(label_mob)
|
|
144
|
-
parts.braces = braces
|
|
145
|
-
parts.labels = label_mobs
|
|
146
|
-
parts.label_kwargs = {
|
|
166
|
+
parts.braces = braces # type: ignore[attr-defined]
|
|
167
|
+
parts.labels = label_mobs # type: ignore[attr-defined]
|
|
168
|
+
parts.label_kwargs = { # type: ignore[attr-defined]
|
|
147
169
|
"labels": label_mobs.copy(),
|
|
148
170
|
"direction": direction,
|
|
149
171
|
"buff": buff,
|
|
150
172
|
}
|
|
151
173
|
return VGroup(parts.braces, parts.labels)
|
|
152
174
|
|
|
153
|
-
def get_side_braces_and_labels(
|
|
175
|
+
def get_side_braces_and_labels(
|
|
176
|
+
self,
|
|
177
|
+
labels: list[str | VMobject | OpenGLVMobject],
|
|
178
|
+
direction: Vector3D = LEFT,
|
|
179
|
+
**kwargs: Any,
|
|
180
|
+
) -> VGroup:
|
|
154
181
|
assert hasattr(self, "horizontal_parts")
|
|
155
182
|
parts = self.horizontal_parts
|
|
156
183
|
return self.get_subdivision_braces_and_labels(
|
|
157
184
|
parts, labels, direction, **kwargs
|
|
158
185
|
)
|
|
159
186
|
|
|
160
|
-
def get_top_braces_and_labels(
|
|
187
|
+
def get_top_braces_and_labels(
|
|
188
|
+
self, labels: list[str | VMobject | OpenGLVMobject], **kwargs: Any
|
|
189
|
+
) -> VGroup:
|
|
161
190
|
assert hasattr(self, "vertical_parts")
|
|
162
191
|
parts = self.vertical_parts
|
|
163
192
|
return self.get_subdivision_braces_and_labels(parts, labels, UP, **kwargs)
|
|
164
193
|
|
|
165
|
-
def get_bottom_braces_and_labels(
|
|
194
|
+
def get_bottom_braces_and_labels(
|
|
195
|
+
self, labels: list[str | VMobject | OpenGLVMobject], **kwargs: Any
|
|
196
|
+
) -> VGroup:
|
|
166
197
|
assert hasattr(self, "vertical_parts")
|
|
167
198
|
parts = self.vertical_parts
|
|
168
199
|
return self.get_subdivision_braces_and_labels(parts, labels, DOWN, **kwargs)
|
|
169
200
|
|
|
170
|
-
def add_braces_and_labels(self):
|
|
201
|
+
def add_braces_and_labels(self) -> None:
|
|
171
202
|
for attr in "horizontal_parts", "vertical_parts":
|
|
172
203
|
if not hasattr(self, attr):
|
|
173
204
|
continue
|
|
@@ -176,11 +207,13 @@ class SampleSpace(Rectangle):
|
|
|
176
207
|
if hasattr(parts, subattr):
|
|
177
208
|
self.add(getattr(parts, subattr))
|
|
178
209
|
|
|
179
|
-
def __getitem__(self, index):
|
|
210
|
+
def __getitem__(self, index: int) -> SampleSpace:
|
|
180
211
|
if hasattr(self, "horizontal_parts"):
|
|
181
|
-
|
|
212
|
+
val: SampleSpace = self.horizontal_parts[index]
|
|
213
|
+
return val
|
|
182
214
|
elif hasattr(self, "vertical_parts"):
|
|
183
|
-
|
|
215
|
+
val = self.vertical_parts[index]
|
|
216
|
+
return val
|
|
184
217
|
return self.split()[index]
|
|
185
218
|
|
|
186
219
|
|
|
@@ -252,9 +285,8 @@ class BarChart(Axes):
|
|
|
252
285
|
bar_width: float = 0.6,
|
|
253
286
|
bar_fill_opacity: float = 0.7,
|
|
254
287
|
bar_stroke_width: float = 3,
|
|
255
|
-
**kwargs,
|
|
288
|
+
**kwargs: Any,
|
|
256
289
|
):
|
|
257
|
-
|
|
258
290
|
if isinstance(bar_colors, str):
|
|
259
291
|
logger.warning(
|
|
260
292
|
"Passing a string to `bar_colors` has been deprecated since v0.15.2 and will be removed after v0.17.0, the parameter must be a list. "
|
|
@@ -311,7 +343,7 @@ class BarChart(Axes):
|
|
|
311
343
|
|
|
312
344
|
self.y_axis.add_numbers()
|
|
313
345
|
|
|
314
|
-
def _update_colors(self):
|
|
346
|
+
def _update_colors(self) -> None:
|
|
315
347
|
"""Initialize the colors of the bars of the chart.
|
|
316
348
|
|
|
317
349
|
Sets the color of ``self.bars`` via ``self.bar_colors``.
|
|
@@ -319,17 +351,16 @@ class BarChart(Axes):
|
|
|
319
351
|
Primarily used when the bars are initialized with ``self._add_bars``
|
|
320
352
|
or updated via ``self.change_bar_values``.
|
|
321
353
|
"""
|
|
322
|
-
|
|
323
354
|
self.bars.set_color_by_gradient(*self.bar_colors)
|
|
324
355
|
|
|
325
|
-
def _add_x_axis_labels(self):
|
|
356
|
+
def _add_x_axis_labels(self) -> None:
|
|
326
357
|
"""Essentially :meth`:~.NumberLine.add_labels`, but differs in that
|
|
327
358
|
the direction of the label with respect to the x_axis changes to UP or DOWN
|
|
328
359
|
depending on the value.
|
|
329
360
|
|
|
330
361
|
UP for negative values and DOWN for positive values.
|
|
331
362
|
"""
|
|
332
|
-
|
|
363
|
+
assert isinstance(self.bar_names, list)
|
|
333
364
|
val_range = np.arange(
|
|
334
365
|
0.5, len(self.bar_names), 1
|
|
335
366
|
) # 0.5 shifted so that labels are centered, not on ticks
|
|
@@ -339,11 +370,8 @@ class BarChart(Axes):
|
|
|
339
370
|
for i, (value, bar_name) in enumerate(zip(val_range, self.bar_names)):
|
|
340
371
|
# to accommodate negative bars, the label may need to be
|
|
341
372
|
# below or above the x_axis depending on the value of the bar
|
|
342
|
-
if self.values[i] < 0
|
|
343
|
-
|
|
344
|
-
else:
|
|
345
|
-
direction = DOWN
|
|
346
|
-
bar_name_label = self.x_axis.label_constructor(bar_name)
|
|
373
|
+
direction = UP if self.values[i] < 0 else DOWN
|
|
374
|
+
bar_name_label: MathTex = self.x_axis.label_constructor(bar_name)
|
|
347
375
|
|
|
348
376
|
bar_name_label.font_size = self.x_axis.font_size
|
|
349
377
|
bar_name_label.next_to(
|
|
@@ -372,7 +400,6 @@ class BarChart(Axes):
|
|
|
372
400
|
Rectangle
|
|
373
401
|
A positioned rectangle representing a bar on the chart.
|
|
374
402
|
"""
|
|
375
|
-
|
|
376
403
|
# bar measurements relative to the axis
|
|
377
404
|
|
|
378
405
|
# distance from between the y-axis and the top of the bar
|
|
@@ -401,11 +428,11 @@ class BarChart(Axes):
|
|
|
401
428
|
|
|
402
429
|
def get_bar_labels(
|
|
403
430
|
self,
|
|
404
|
-
color:
|
|
431
|
+
color: ParsableManimColor | None = None,
|
|
405
432
|
font_size: float = 24,
|
|
406
433
|
buff: float = MED_SMALL_BUFF,
|
|
407
|
-
label_constructor: type[
|
|
408
|
-
):
|
|
434
|
+
label_constructor: type[MathTex] = Tex,
|
|
435
|
+
) -> VGroup:
|
|
409
436
|
"""Annotates each bar with its corresponding value. Use ``self.bar_labels`` to access the
|
|
410
437
|
labels after creation.
|
|
411
438
|
|
|
@@ -435,10 +462,9 @@ class BarChart(Axes):
|
|
|
435
462
|
|
|
436
463
|
self.add(chart, c_bar_lbls)
|
|
437
464
|
"""
|
|
438
|
-
|
|
439
465
|
bar_labels = VGroup()
|
|
440
466
|
for bar, value in zip(self.bars, self.values):
|
|
441
|
-
bar_lbl = label_constructor(str(value))
|
|
467
|
+
bar_lbl: MathTex = label_constructor(str(value))
|
|
442
468
|
|
|
443
469
|
if color is None:
|
|
444
470
|
bar_lbl.set_color(bar.get_fill_color())
|
|
@@ -453,7 +479,9 @@ class BarChart(Axes):
|
|
|
453
479
|
|
|
454
480
|
return bar_labels
|
|
455
481
|
|
|
456
|
-
def change_bar_values(
|
|
482
|
+
def change_bar_values(
|
|
483
|
+
self, values: Iterable[float], update_colors: bool = True
|
|
484
|
+
) -> None:
|
|
457
485
|
"""Updates the height of the bars of the chart.
|
|
458
486
|
|
|
459
487
|
Parameters
|
|
@@ -483,7 +511,6 @@ class BarChart(Axes):
|
|
|
483
511
|
chart.change_bar_values(list(reversed(values)))
|
|
484
512
|
self.add(chart.get_bar_labels(font_size=24))
|
|
485
513
|
"""
|
|
486
|
-
|
|
487
514
|
for i, (bar, value) in enumerate(zip(self.bars, values)):
|
|
488
515
|
chart_val = self.values[i]
|
|
489
516
|
|
|
@@ -498,7 +525,6 @@ class BarChart(Axes):
|
|
|
498
525
|
if chart_val != 0:
|
|
499
526
|
quotient = value / chart_val
|
|
500
527
|
if quotient < 0:
|
|
501
|
-
|
|
502
528
|
aligned_edge = UP if chart_val > 0 else DOWN
|
|
503
529
|
|
|
504
530
|
# if the bar is already positive, then we now want to move it
|
|
@@ -521,4 +547,4 @@ class BarChart(Axes):
|
|
|
521
547
|
if update_colors:
|
|
522
548
|
self._update_colors()
|
|
523
549
|
|
|
524
|
-
self.values[: len(values)] = values
|
|
550
|
+
self.values[: len(list(values))] = values
|
manim/mobject/graphing/scale.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import math
|
|
4
|
-
from
|
|
4
|
+
from collections.abc import Iterable
|
|
5
|
+
from typing import TYPE_CHECKING, Any, overload
|
|
5
6
|
|
|
6
7
|
import numpy as np
|
|
7
8
|
|
|
@@ -10,21 +11,29 @@ __all__ = ["LogBase", "LinearBase"]
|
|
|
10
11
|
from manim.mobject.text.numbers import Integer
|
|
11
12
|
|
|
12
13
|
if TYPE_CHECKING:
|
|
13
|
-
from
|
|
14
|
+
from typing import Callable
|
|
15
|
+
|
|
16
|
+
from manim.mobject.types.vectorized_mobject import VMobject
|
|
14
17
|
|
|
15
18
|
|
|
16
19
|
class _ScaleBase:
|
|
17
|
-
"""Scale baseclass for graphing/functions.
|
|
20
|
+
"""Scale baseclass for graphing/functions.
|
|
21
|
+
|
|
22
|
+
Parameters
|
|
23
|
+
----------
|
|
24
|
+
custom_labels
|
|
25
|
+
Whether to create custom labels when plotted on a :class:`~.NumberLine`.
|
|
26
|
+
"""
|
|
18
27
|
|
|
19
28
|
def __init__(self, custom_labels: bool = False):
|
|
20
|
-
"""
|
|
21
|
-
Parameters
|
|
22
|
-
----------
|
|
23
|
-
custom_labels
|
|
24
|
-
Whether to create custom labels when plotted on a :class:`~.NumberLine`.
|
|
25
|
-
"""
|
|
26
29
|
self.custom_labels = custom_labels
|
|
27
30
|
|
|
31
|
+
@overload
|
|
32
|
+
def function(self, value: float) -> float: ...
|
|
33
|
+
|
|
34
|
+
@overload
|
|
35
|
+
def function(self, value: np.ndarray) -> np.ndarray: ...
|
|
36
|
+
|
|
28
37
|
def function(self, value: float) -> float:
|
|
29
38
|
"""The function that will be used to scale the values.
|
|
30
39
|
|
|
@@ -58,7 +67,8 @@ class _ScaleBase:
|
|
|
58
67
|
def get_custom_labels(
|
|
59
68
|
self,
|
|
60
69
|
val_range: Iterable[float],
|
|
61
|
-
|
|
70
|
+
**kw_args: Any,
|
|
71
|
+
) -> Iterable[VMobject]:
|
|
62
72
|
"""Custom instructions for generating labels along an axis.
|
|
63
73
|
|
|
64
74
|
Parameters
|
|
@@ -89,7 +99,6 @@ class LinearBase(_ScaleBase):
|
|
|
89
99
|
scale_factor
|
|
90
100
|
The slope of the linear function, by default 1.0
|
|
91
101
|
"""
|
|
92
|
-
|
|
93
102
|
super().__init__()
|
|
94
103
|
self.scale_factor = scale_factor
|
|
95
104
|
|
|
@@ -124,7 +133,7 @@ class LogBase(_ScaleBase):
|
|
|
124
133
|
The base of the log, by default 10.
|
|
125
134
|
custom_labels
|
|
126
135
|
For use with :class:`~.Axes`:
|
|
127
|
-
|
|
136
|
+
Whether or not to include ``LaTeX`` axis labels, by default True.
|
|
128
137
|
|
|
129
138
|
Examples
|
|
130
139
|
--------
|
|
@@ -139,13 +148,19 @@ class LogBase(_ScaleBase):
|
|
|
139
148
|
|
|
140
149
|
def function(self, value: float) -> float:
|
|
141
150
|
"""Scales the value to fit it to a logarithmic scale.``self.function(5)==10**5``"""
|
|
142
|
-
|
|
151
|
+
return_value: float = self.base**value
|
|
152
|
+
return return_value
|
|
143
153
|
|
|
144
154
|
def inverse_function(self, value: float) -> float:
|
|
145
155
|
"""Inverse of ``function``. The value must be greater than 0"""
|
|
146
156
|
if isinstance(value, np.ndarray):
|
|
147
157
|
condition = value.any() <= 0
|
|
148
|
-
|
|
158
|
+
|
|
159
|
+
func: Callable[[float, float], float]
|
|
160
|
+
|
|
161
|
+
def func(value: float, base: float) -> float:
|
|
162
|
+
return_value: float = np.log(value) / np.log(base)
|
|
163
|
+
return return_value
|
|
149
164
|
else:
|
|
150
165
|
condition = value <= 0
|
|
151
166
|
func = math.log
|
|
@@ -161,8 +176,8 @@ class LogBase(_ScaleBase):
|
|
|
161
176
|
self,
|
|
162
177
|
val_range: Iterable[float],
|
|
163
178
|
unit_decimal_places: int = 0,
|
|
164
|
-
**base_config:
|
|
165
|
-
) -> list[
|
|
179
|
+
**base_config: Any,
|
|
180
|
+
) -> list[Integer]:
|
|
166
181
|
"""Produces custom :class:`~.Integer` labels in the form of ``10^2``.
|
|
167
182
|
|
|
168
183
|
Parameters
|
|
@@ -174,12 +189,11 @@ class LogBase(_ScaleBase):
|
|
|
174
189
|
base_config
|
|
175
190
|
Additional arguments to be passed to :class:`~.Integer`.
|
|
176
191
|
"""
|
|
177
|
-
|
|
178
192
|
# uses `format` syntax to control the number of decimal places.
|
|
179
|
-
tex_labels = [
|
|
193
|
+
tex_labels: list[Integer] = [
|
|
180
194
|
Integer(
|
|
181
195
|
self.base,
|
|
182
|
-
unit="^{%s}" % (f"{self.inverse_function(i):.{unit_decimal_places}f}"),
|
|
196
|
+
unit="^{%s}" % (f"{self.inverse_function(i):.{unit_decimal_places}f}"), # noqa: UP031
|
|
183
197
|
**base_config,
|
|
184
198
|
)
|
|
185
199
|
for i in val_range
|