Skip to content

CurvesAsSubmobjects should keep attributes of ParametricFunction #3150

Open
@alembcke

Description

@alembcke

Description of bug / unexpected behavior

When applying CurvesAsSubmobjects to a ParametricFunction, the attributes of ParametricFunction are no longer available. This means that the new curve cannot be used with many of the methods typically used with curves, like input_to_graph_point.

Expected behavior

CurvesAsSubmobjects should preserve the attributes of ParametricFunction, such as .function and .t_range.

How to reproduce the issue

Code for reproducing the problem
from manim import *

class CurveExample(Scene):
    def construct(self):
        axes = Axes(
            x_range=[0, 6],
            y_range=[-2, 2],
            tips=False,
        )

        curve = axes.plot(
                lambda x: 2 * np.sin(x), x_range=(0.0, 6, 0.001), color=BLUE
        )

        new_curve = CurvesAsSubmobjects(curve)

        curve_dot = Dot(axes.input_to_graph_point(1, new_curve), color=ORANGE)

        self.add(axes, new_curve, curve_dot)

Logs

Terminal output
Manim Community v0.17.2

╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ /home/alexlembcke/.local/lib/python3.10/site-packages/manim/cli/render/commands.py:115 in render │
│                                                                                                  │
│   112 │   │   │   try:                                                                           │
│   113 │   │   │   │   with tempconfig({}):                                                       │
│   114 │   │   │   │   │   scene = SceneClass()                                                   │
│ ❱ 115 │   │   │   │   │   scene.render()                                                         │
│   116 │   │   │   except Exception:                                                              │
│   117 │   │   │   │   error_console.print_exception()                                            │
│   118 │   │   │   │   sys.exit(1)                                                                │
│                                                                                                  │
│ /home/alexlembcke/.local/lib/python3.10/site-packages/manim/scene/scene.py:223 in render         │
│                                                                                                  │
│    220 │   │   """                                                                               │
│    221 │   │   self.setup()                                                                      │
│    222 │   │   try:                                                                              │
│ ❱  223 │   │   │   self.construct()                                                              │
│    224 │   │   except EndSceneEarlyException:                                                    │
│    225 │   │   │   pass                                                                          │
│    226 │   │   except RerunSceneException as e:                                                  │
│                                                                                                  │
│ /home/alexlembcke/ManimDev/plot_colorscale.py:17 in construct                                    │
│                                                                                                  │
│   14 │   │                                                                                       │
│   15 │   │   new_curve = CurvesAsSubmobjects(curve)                                              │
│   16 │   │                                                                                       │
│ ❱ 17 │   │   curve_dot = Dot(axes.input_to_graph_point(1, new_curve), color=ORANGE)              │
│   18 │   │                                                                                       │
│   19 │   │   self.add(axes, new_curve, curve_dot)                                                │
│   20                                                                                             │
│                                                                                                  │
│ /home/alexlembcke/.local/lib/python3.10/site-packages/manim/mobject/graphing/coordinate_systems. │
│ py:991 in input_to_graph_point                                                                   │
│                                                                                                  │
│    988 │   │   if hasattr(graph, "underlying_function"):                                         │
│    989 │   │   │   return graph.function(x)                                                      │
│    990 │   │   else:                                                                             │
│ ❱  991 │   │   │   alpha = binary_search(                                                        │
│    992 │   │   │   │   function=lambda a: self.point_to_coords(graph.point_from_proportion(a))[  │
│    993 │   │   │   │   │   0                                                                     │
│    994 │   │   │   │   ],                                                                        │
│                                                                                                  │
│ /home/alexlembcke/.local/lib/python3.10/site-packages/manim/utils/simple_functions.py:63 in      │
│ binary_search                                                                                    │
│                                                                                                  │
│    60 │   mh = np.mean(np.array([lh, rh]))                                                       │
│    61 │   while abs(rh - lh) > tolerance:                                                        │
│    62 │   │   mh = np.mean(np.array([lh, rh]))                                                   │
│ ❱  63 │   │   lx, mx, rx = (function(h) for h in (lh, mh, rh))                                   │
│    64 │   │   if lx == target:                                                                   │
│    65 │   │   │   return lh                                                                      │
│    66 │   │   if rx == target:                                                                   │
│                                                                                                  │
│ /home/alexlembcke/.local/lib/python3.10/site-packages/manim/utils/simple_functions.py:63 in      │
│ <genexpr>                                                                                        │
│                                                                                                  │
│    60 │   mh = np.mean(np.array([lh, rh]))                                                       │
│    61 │   while abs(rh - lh) > tolerance:                                                        │
│    62 │   │   mh = np.mean(np.array([lh, rh]))                                                   │
│ ❱  63 │   │   lx, mx, rx = (function(h) for h in (lh, mh, rh))                                   │
│    64 │   │   if lx == target:                                                                   │
│    65 │   │   │   return lh                                                                      │
│    66 │   │   if rx == target:                                                                   │
│                                                                                                  │
│ /home/alexlembcke/.local/lib/python3.10/site-packages/manim/mobject/graphing/coordinate_systems. │
│ py:992 in <lambda>                                                                               │
│                                                                                                  │
│    989 │   │   │   return graph.function(x)                                                      │
│    990 │   │   else:                                                                             │
│    991 │   │   │   alpha = binary_search(                                                        │
│ ❱  992 │   │   │   │   function=lambda a: self.point_to_coords(graph.point_from_proportion(a))[  │
│    993 │   │   │   │   │   0                                                                     │
│    994 │   │   │   │   ],                                                                        │
│    995 │   │   │   │   target=x,                                                                 │
│                                                                                                  │
│ /home/alexlembcke/.local/lib/python3.10/site-packages/manim/mobject/types/vectorized_mobject.py: │
│ 1284 in point_from_proportion                                                                    │
│                                                                                                  │
│   1281 │   │   if alpha < 0 or alpha > 1:                                                        │
│   1282 │   │   │   raise ValueError(f"Alpha {alpha} not between 0 and 1.")                       │
│   1283 │   │                                                                                     │
│ ❱ 1284 │   │   self.throw_error_if_no_points()                                                   │
│   1285 │   │   if alpha == 1:                                                                    │
│   1286 │   │   │   return self.points[-1]                                                        │
│   1287                                                                                           │
│                                                                                                  │
│ /home/alexlembcke/.local/lib/python3.10/site-packages/manim/mobject/mobject.py:2731 in           │
│ throw_error_if_no_points                                                                         │
│                                                                                                  │
│   2728 │   def throw_error_if_no_points(self):                                                   │
│   2729 │   │   if self.has_no_points():                                                          │
│   2730 │   │   │   caller_name = sys._getframe(1).f_code.co_name                                 │
│ ❱ 2731 │   │   │   raise Exception(                                                              │
│   2732 │   │   │   │   f"Cannot call Mobject.{caller_name} for a Mobject with no points",        │
│   2733 │   │   │   )                                                                             │
│   2734                                                                                           │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
Exception: Cannot call Mobject.point_from_proportion for a Mobject with no points

System specifications

System Details
  • OS: Ubuntu 22.10
  • RAM: 32GB
  • Python version (python/py/python3 --version): Python 3.10.7

Metadata

Metadata

Assignees

No one assigned

    Labels

    refactorRefactor or redesign of existing code

    Type

    No type

    Projects

    Status

    🆕 New

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions