manim 0.18.0.post0__py3-none-any.whl → 0.19.0__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.

Files changed (146) hide show
  1. manim/__init__.py +3 -6
  2. manim/__main__.py +61 -20
  3. manim/_config/__init__.py +6 -3
  4. manim/_config/cli_colors.py +16 -8
  5. manim/_config/default.cfg +1 -3
  6. manim/_config/logger_utils.py +14 -8
  7. manim/_config/utils.py +651 -472
  8. manim/animation/animation.py +152 -5
  9. manim/animation/composition.py +80 -39
  10. manim/animation/creation.py +196 -14
  11. manim/animation/fading.py +5 -9
  12. manim/animation/indication.py +103 -47
  13. manim/animation/movement.py +22 -5
  14. manim/animation/rotation.py +3 -2
  15. manim/animation/specialized.py +4 -6
  16. manim/animation/speedmodifier.py +10 -5
  17. manim/animation/transform.py +4 -5
  18. manim/animation/transform_matching_parts.py +1 -1
  19. manim/animation/updaters/mobject_update_utils.py +17 -14
  20. manim/camera/camera.py +15 -6
  21. manim/cli/__init__.py +17 -0
  22. manim/cli/cfg/group.py +70 -44
  23. manim/cli/checkhealth/checks.py +93 -75
  24. manim/cli/checkhealth/commands.py +14 -5
  25. manim/cli/default_group.py +157 -25
  26. manim/cli/init/commands.py +32 -24
  27. manim/cli/plugins/commands.py +16 -3
  28. manim/cli/render/commands.py +72 -60
  29. manim/cli/render/ease_of_access_options.py +4 -3
  30. manim/cli/render/global_options.py +51 -15
  31. manim/cli/render/output_options.py +6 -5
  32. manim/cli/render/render_options.py +97 -32
  33. manim/constants.py +65 -19
  34. manim/gui/gui.py +2 -0
  35. manim/mobject/frame.py +0 -1
  36. manim/mobject/geometry/arc.py +112 -78
  37. manim/mobject/geometry/boolean_ops.py +32 -25
  38. manim/mobject/geometry/labeled.py +300 -77
  39. manim/mobject/geometry/line.py +132 -64
  40. manim/mobject/geometry/polygram.py +126 -30
  41. manim/mobject/geometry/shape_matchers.py +35 -15
  42. manim/mobject/geometry/tips.py +38 -29
  43. manim/mobject/graph.py +414 -133
  44. manim/mobject/graphing/coordinate_systems.py +126 -64
  45. manim/mobject/graphing/functions.py +25 -15
  46. manim/mobject/graphing/number_line.py +24 -10
  47. manim/mobject/graphing/probability.py +2 -10
  48. manim/mobject/graphing/scale.py +6 -5
  49. manim/mobject/matrix.py +17 -19
  50. manim/mobject/mobject.py +314 -165
  51. manim/mobject/opengl/opengl_compatibility.py +2 -0
  52. manim/mobject/opengl/opengl_geometry.py +30 -9
  53. manim/mobject/opengl/opengl_image_mobject.py +2 -0
  54. manim/mobject/opengl/opengl_mobject.py +509 -343
  55. manim/mobject/opengl/opengl_point_cloud_mobject.py +5 -7
  56. manim/mobject/opengl/opengl_surface.py +3 -2
  57. manim/mobject/opengl/opengl_three_dimensions.py +2 -0
  58. manim/mobject/opengl/opengl_vectorized_mobject.py +46 -79
  59. manim/mobject/svg/brace.py +63 -13
  60. manim/mobject/svg/svg_mobject.py +4 -3
  61. manim/mobject/table.py +11 -13
  62. manim/mobject/text/code_mobject.py +186 -548
  63. manim/mobject/text/numbers.py +9 -7
  64. manim/mobject/text/tex_mobject.py +23 -14
  65. manim/mobject/text/text_mobject.py +70 -24
  66. manim/mobject/three_d/polyhedra.py +98 -1
  67. manim/mobject/three_d/three_d_utils.py +4 -4
  68. manim/mobject/three_d/three_dimensions.py +62 -34
  69. manim/mobject/types/image_mobject.py +42 -24
  70. manim/mobject/types/point_cloud_mobject.py +105 -67
  71. manim/mobject/types/vectorized_mobject.py +496 -228
  72. manim/mobject/value_tracker.py +5 -4
  73. manim/mobject/vector_field.py +5 -5
  74. manim/opengl/__init__.py +3 -3
  75. manim/plugins/__init__.py +14 -1
  76. manim/plugins/plugins_flags.py +14 -8
  77. manim/renderer/cairo_renderer.py +20 -10
  78. manim/renderer/opengl_renderer.py +21 -23
  79. manim/renderer/opengl_renderer_window.py +2 -0
  80. manim/renderer/shader.py +2 -3
  81. manim/renderer/shader_wrapper.py +5 -2
  82. manim/renderer/vectorized_mobject_rendering.py +5 -0
  83. manim/scene/moving_camera_scene.py +23 -0
  84. manim/scene/scene.py +90 -43
  85. manim/scene/scene_file_writer.py +316 -165
  86. manim/scene/section.py +17 -15
  87. manim/scene/three_d_scene.py +13 -21
  88. manim/scene/vector_space_scene.py +22 -9
  89. manim/typing.py +830 -70
  90. manim/utils/bezier.py +1667 -399
  91. manim/utils/caching.py +13 -5
  92. manim/utils/color/AS2700.py +2 -0
  93. manim/utils/color/BS381.py +3 -0
  94. manim/utils/color/DVIPSNAMES.py +96 -0
  95. manim/utils/color/SVGNAMES.py +179 -0
  96. manim/utils/color/X11.py +3 -0
  97. manim/utils/color/XKCD.py +3 -0
  98. manim/utils/color/__init__.py +8 -5
  99. manim/utils/color/core.py +844 -309
  100. manim/utils/color/manim_colors.py +7 -9
  101. manim/utils/commands.py +48 -20
  102. manim/utils/config_ops.py +18 -13
  103. manim/utils/debug.py +8 -7
  104. manim/utils/deprecation.py +90 -40
  105. manim/utils/docbuild/__init__.py +17 -0
  106. manim/utils/docbuild/autoaliasattr_directive.py +234 -0
  107. manim/utils/docbuild/autocolor_directive.py +21 -17
  108. manim/utils/docbuild/manim_directive.py +50 -35
  109. manim/utils/docbuild/module_parsing.py +245 -0
  110. manim/utils/exceptions.py +6 -0
  111. manim/utils/family.py +5 -3
  112. manim/utils/family_ops.py +17 -4
  113. manim/utils/file_ops.py +26 -16
  114. manim/utils/hashing.py +9 -7
  115. manim/utils/images.py +10 -4
  116. manim/utils/ipython_magic.py +14 -8
  117. manim/utils/iterables.py +161 -119
  118. manim/utils/module_ops.py +57 -19
  119. manim/utils/opengl.py +83 -24
  120. manim/utils/parameter_parsing.py +32 -0
  121. manim/utils/paths.py +21 -23
  122. manim/utils/polylabel.py +168 -0
  123. manim/utils/qhull.py +218 -0
  124. manim/utils/rate_functions.py +74 -39
  125. manim/utils/simple_functions.py +24 -15
  126. manim/utils/sounds.py +7 -1
  127. manim/utils/space_ops.py +125 -69
  128. manim/utils/testing/__init__.py +17 -0
  129. manim/utils/testing/_frames_testers.py +13 -8
  130. manim/utils/testing/_show_diff.py +5 -3
  131. manim/utils/testing/_test_class_makers.py +33 -18
  132. manim/utils/testing/frames_comparison.py +27 -19
  133. manim/utils/tex.py +127 -197
  134. manim/utils/tex_file_writing.py +47 -45
  135. manim/utils/tex_templates.py +2 -1
  136. manim/utils/unit.py +6 -5
  137. {manim-0.18.0.post0.dist-info → manim-0.19.0.dist-info}/LICENSE.community +1 -1
  138. {manim-0.18.0.post0.dist-info → manim-0.19.0.dist-info}/METADATA +40 -39
  139. manim-0.19.0.dist-info/RECORD +221 -0
  140. {manim-0.18.0.post0.dist-info → manim-0.19.0.dist-info}/WHEEL +1 -1
  141. manim/cli/new/__init__.py +0 -0
  142. manim/cli/new/group.py +0 -189
  143. manim/plugins/import_plugins.py +0 -43
  144. manim-0.18.0.post0.dist-info/RECORD +0 -217
  145. {manim-0.18.0.post0.dist-info → manim-0.19.0.dist-info}/LICENSE +0 -0
  146. {manim-0.18.0.post0.dist-info → manim-0.19.0.dist-info}/entry_points.txt +0 -0
manim/scene/section.py CHANGED
@@ -8,6 +8,8 @@ from typing import Any
8
8
 
9
9
  from manim import get_video_metadata
10
10
 
11
+ __all__ = ["Section", "DefaultSectionType"]
12
+
11
13
 
12
14
  class DefaultSectionType(str, Enum):
13
15
  """The type of a section can be used for third party applications.
@@ -32,23 +34,23 @@ class DefaultSectionType(str, Enum):
32
34
 
33
35
 
34
36
  class Section:
35
- """A :class:`.Scene` can be segmented into multiple Sections.
37
+ r"""A :class:`.Scene` can be segmented into multiple Sections.
36
38
  Refer to :doc:`the documentation</tutorials/output_and_config>` for more info.
37
39
  It consists of multiple animations.
38
40
 
39
41
  Attributes
40
42
  ----------
41
- type
42
- Can be used by a third party applications to classify different types of sections.
43
- video
44
- Path to video file with animations belonging to section relative to sections directory.
45
- If ``None``, then the section will not be saved.
46
- name
47
- Human readable, non-unique name for this section.
48
- skip_animations
49
- Skip rendering the animations in this section when ``True``.
50
- partial_movie_files
51
- Animations belonging to this section.
43
+ type\_
44
+ Can be used by a third party applications to classify different types of sections.
45
+ video
46
+ Path to video file with animations belonging to section relative to sections directory.
47
+ If ``None``, then the section will not be saved.
48
+ name
49
+ Human readable, non-unique name for this section.
50
+ skip_animations
51
+ Skip rendering the animations in this section when ``True``.
52
+ partial_movie_files
53
+ Animations belonging to this section.
52
54
 
53
55
  See Also
54
56
  --------
@@ -57,8 +59,8 @@ class Section:
57
59
  :meth:`.OpenGLRenderer.update_skipping_status`
58
60
  """
59
61
 
60
- def __init__(self, type: str, video: str | None, name: str, skip_animations: bool):
61
- self.type = type
62
+ def __init__(self, type_: str, video: str | None, name: str, skip_animations: bool):
63
+ self.type_ = type_
62
64
  # None when not to be saved -> still keeps section alive
63
65
  self.video: str | None = video
64
66
  self.name = name
@@ -92,7 +94,7 @@ class Section:
92
94
  return dict(
93
95
  {
94
96
  "name": self.name,
95
- "type": self.type,
97
+ "type": self.type_,
96
98
  "video": self.video,
97
99
  },
98
100
  **video_metadata,
@@ -6,7 +6,7 @@ __all__ = ["ThreeDScene", "SpecialThreeDScene"]
6
6
 
7
7
 
8
8
  import warnings
9
- from typing import Iterable, Sequence
9
+ from collections.abc import Iterable, Sequence
10
10
 
11
11
  import numpy as np
12
12
 
@@ -86,7 +86,6 @@ class ThreeDScene(Scene):
86
86
  The new center of the camera frame in cartesian coordinates.
87
87
 
88
88
  """
89
-
90
89
  if phi is not None:
91
90
  self.renderer.camera.set_phi(phi)
92
91
  if theta is not None:
@@ -135,13 +134,11 @@ class ThreeDScene(Scene):
135
134
  }
136
135
  cam.add_updater(lambda m, dt: methods[about](rate * dt))
137
136
  self.add(self.camera)
138
- except Exception:
139
- raise ValueError("Invalid ambient rotation angle.")
137
+ except Exception as e:
138
+ raise ValueError("Invalid ambient rotation angle.") from e
140
139
 
141
140
  def stop_ambient_camera_rotation(self, about="theta"):
142
- """
143
- This method stops all ambient camera rotation.
144
- """
141
+ """This method stops all ambient camera rotation."""
145
142
  about: str = about.lower()
146
143
  try:
147
144
  if config.renderer == RendererType.CAIRO:
@@ -155,8 +152,8 @@ class ThreeDScene(Scene):
155
152
  self.remove(x)
156
153
  elif config.renderer == RendererType.OPENGL:
157
154
  self.camera.clear_updaters()
158
- except Exception:
159
- raise ValueError("Invalid ambient rotation angle.")
155
+ except Exception as e:
156
+ raise ValueError("Invalid ambient rotation angle.") from e
160
157
 
161
158
  def begin_3dillusion_camera_rotation(
162
159
  self,
@@ -205,9 +202,7 @@ class ThreeDScene(Scene):
205
202
  self.add(self.renderer.camera.phi_tracker)
206
203
 
207
204
  def stop_3dillusion_camera_rotation(self):
208
- """
209
- This method stops all illusion camera rotations.
210
- """
205
+ """This method stops all illusion camera rotations."""
211
206
  self.renderer.camera.theta_tracker.clear_updaters()
212
207
  self.remove(self.renderer.camera.theta_tracker)
213
208
  self.renderer.camera.phi_tracker.clear_updaters()
@@ -283,16 +278,15 @@ class ThreeDScene(Scene):
283
278
  frame_center = frame_center.get_center()
284
279
  frame_center = list(frame_center)
285
280
 
281
+ zoom_value = None
282
+ if zoom is not None:
283
+ zoom_value = config.frame_height / (zoom * cam.height)
284
+
286
285
  for value, method in [
287
286
  [theta, "theta"],
288
287
  [phi, "phi"],
289
288
  [gamma, "gamma"],
290
- [
291
- config.frame_height / (zoom * cam.height)
292
- if zoom is not None
293
- else None,
294
- "zoom",
295
- ],
289
+ [zoom_value, "zoom"],
296
290
  [frame_center, "frame_center"],
297
291
  ]:
298
292
  if value is not None:
@@ -546,7 +540,5 @@ class SpecialThreeDScene(ThreeDScene):
546
540
  return self.default_angled_camera_position
547
541
 
548
542
  def set_camera_to_default_position(self):
549
- """
550
- Sets the camera to its default position.
551
- """
543
+ """Sets the camera to its default position."""
552
544
  self.set_camera_orientation(**self.default_angled_camera_position)
@@ -297,7 +297,7 @@ class VectorScene(Scene):
297
297
  """
298
298
  if not isinstance(label, MathTex):
299
299
  if len(label) == 1:
300
- label = "\\vec{\\textbf{%s}}" % label
300
+ label = "\\vec{\\textbf{%s}}" % label # noqa: UP031
301
301
  label = MathTex(label)
302
302
  if color is None:
303
303
  color = vector.get_color()
@@ -572,7 +572,7 @@ class LinearTransformationScene(VectorScene):
572
572
  self,
573
573
  show_coordinates=True,
574
574
  leave_ghost_vectors=True,
575
- *kwargs
575
+ **kwargs
576
576
  )
577
577
 
578
578
  def construct(self):
@@ -616,6 +616,8 @@ class LinearTransformationScene(VectorScene):
616
616
  },
617
617
  }
618
618
 
619
+ self.ghost_vectors = VGroup()
620
+
619
621
  self.foreground_plane_kwargs = {
620
622
  "x_range": np.array([-config["frame_width"], config["frame_width"], 1.0]),
621
623
  "y_range": np.array([-config["frame_width"], config["frame_width"], 1.0]),
@@ -741,6 +743,13 @@ class LinearTransformationScene(VectorScene):
741
743
  mobject.target = target_mobject
742
744
  self.add_special_mobjects(self.moving_mobjects, mobject)
743
745
 
746
+ def get_ghost_vectors(self) -> VGroup:
747
+ """
748
+ Returns all ghost vectors ever added to ``self``. Each element is a ``VGroup`` of
749
+ two ghost vectors.
750
+ """
751
+ return self.ghost_vectors
752
+
744
753
  def get_unit_square(
745
754
  self, color: str = YELLOW, opacity: float = 0.3, stroke_width: float = 3
746
755
  ):
@@ -895,9 +904,8 @@ class LinearTransformationScene(VectorScene):
895
904
  if new_label:
896
905
  label_mob.target_text = new_label
897
906
  else:
898
- label_mob.target_text = "{}({})".format(
899
- transformation_name,
900
- label_mob.get_tex_string(),
907
+ label_mob.target_text = (
908
+ f"{transformation_name}({label_mob.get_tex_string()})"
901
909
  )
902
910
  label_mob.vector = vector
903
911
  label_mob.kwargs = kwargs
@@ -994,10 +1002,15 @@ class LinearTransformationScene(VectorScene):
994
1002
  Animation
995
1003
  The animation of the movement.
996
1004
  """
997
- start = VGroup(*pieces)
998
- target = VGroup(*(mob.target for mob in pieces))
999
- if self.leave_ghost_vectors:
1000
- self.add(start.copy().fade(0.7))
1005
+ v_pieces = [piece for piece in pieces if isinstance(piece, VMobject)]
1006
+ start = VGroup(*v_pieces)
1007
+ target = VGroup(*(mob.target for mob in v_pieces))
1008
+
1009
+ # don't add empty VGroups
1010
+ if self.leave_ghost_vectors and start.submobjects:
1011
+ # start.copy() gives a VGroup of Vectors
1012
+ self.ghost_vectors.add(start.copy().fade(0.7))
1013
+ self.add(self.ghost_vectors[-1])
1001
1014
  return Transform(start, target, lag_ratio=0)
1002
1015
 
1003
1016
  def get_moving_mobject_movement(self, func: Callable[[np.ndarray], np.ndarray]):