Skip to content

get_nth_subpath throws exception #4629

@MqCreaple

Description

@MqCreaple

Description of bug / unexpected behavior

In file

def get_nth_subpath(path_list, n):
if n >= len(path_list):
# Create a null path at the very end
return [path_list[-1][-1]] * nppcc
, the function get_nth_subpath returns an array referencing path_list[-1][-1]. However, the array path_list is potentially empty, in which case the function will raise an error.

Expected behavior

get_nth_subpath should return a valid value even when path_list is empty.

How to reproduce the issue

Code for reproducing the problem
import numpy as np
from manim import *

class TestScene(Scene):
    def construct(self):
        axes = Axes(x_range=[0, 12 * np.pi, np.pi], y_range=[-1, 1, 0.5])
        curve = axes.plot(lambda x: np.sin(x), x_range=[0, 12 * np.pi])
        timer = ValueTracker(0)
        point1 = Dot(axes.coords_to_point(0, 0, 0))
        point1.add_updater(lambda mob: mob.move_to(axes.coords_to_point(timer.get_value(), np.sin(timer.get_value()), 0.0)))
        lines1 = axes.get_lines_to_point(point1.get_center())
        lines1.add_updater(lambda mob: mob.become(axes.get_lines_to_point(point1.get_center())))

        self.add(axes, curve, point1)
        self.add(lines1)
        self.play(timer.animate.set_value(12 * np.pi), run_time = 5.0)

Additional media files

Images/GIFs

A working version of the previous code should give the following animation:

Image

Logs

Terminal output
[03/07/26 15:10:57] INFO     Animation 0 : Using cached data (hash : 1584795214_3743890524_2038886506)                                                                                                 cairo_renderer.py:94
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ C:\Users\creaple\Documents\projects\manim\.venv\Lib\site-packages\manim\cli\render\commands.py:1 │
│ 25 in render                                                                                     │
│                                                                                                  │
│   122 │   │   │   try:                                                                           │
│   123 │   │   │   │   with tempconfig({}):                                                       │
│   124 │   │   │   │   │   scene = SceneClass()                                                   │
│ ❱ 125 │   │   │   │   │   scene.render()                                                         │
│   126 │   │   │   except Exception:                                                              │
│   127 │   │   │   │   error_console.print_exception()                                            │
│   128 │   │   │   │   sys.exit(1)                                                                │
│                                                                                                  │
│ C:\Users\creaple\Documents\projects\manim\.venv\Lib\site-packages\manim\scene\scene.py:259 in    │
│ render                                                                                           │
│                                                                                                  │
│    256 │   │   """                                                                               │
│    257 │   │   self.setup()                                                                      │
│    258 │   │   try:                                                                              │
│ ❱  259 │   │   │   self.construct()                                                              │
│    260 │   │   except EndSceneEarlyException:                                                    │
│    261 │   │   │   pass                                                                          │
│    262 │   │   except RerunSceneException:                                                       │
│                                                                                                  │
│ C:\Users\creaple\Documents\projects\manim\test.py:16 in construct                                │
│                                                                                                  │
│   13 │   │                                                                                       │
│   14 │   │   self.add(axes, curve, point1)                                                       │
│   15 │   │   self.add(lines1)                                                                    │
│ ❱ 16 │   │   self.play(timer.animate.set_value(12 * np.pi), run_time = 5.0)                      │
│   17                                                                                             │
│                                                                                                  │
│ C:\Users\creaple\Documents\projects\manim\.venv\Lib\site-packages\manim\scene\scene.py:1177 in   │
│ play                                                                                             │
│                                                                                                  │
│   1174 │   │   │   return                                                                        │
│   1175 │   │                                                                                     │
│   1176 │   │   start_time = self.time                                                            │
│ ❱ 1177 │   │   self.renderer.play(self, *args, **kwargs)                                         │
│   1178 │   │   run_time = self.time - start_time                                                 │
│   1179 │   │   if subcaption:                                                                    │
│   1180 │   │   │   if subcaption_duration is None:                                               │
│                                                                                                  │
│ C:\Users\creaple\Documents\projects\manim\.venv\Lib\site-packages\manim\renderer\cairo_renderer. │
│ py:120 in play                                                                                   │
│                                                                                                  │
│   117 │   │   │   # In this case, as there is only a wait, it will be the length of the wait.    │
│   118 │   │   │   self.freeze_current_frame(scene.duration)                                      │
│   119 │   │   else:                                                                              │
│ ❱ 120 │   │   │   scene.play_internal()                                                          │
│   121 │   │   self.file_writer.end_animation(not self.skip_animations)                           │
│   122 │   │                                                                                      │
│   123 │   │   self.num_plays += 1                                                                │
│                                                                                                  │
│ C:\Users\creaple\Documents\projects\manim\.venv\Lib\site-packages\manim\scene\scene.py:1352 in   │
│ play_internal                                                                                    │
│                                                                                                  │
│   1349 │   │   │   self.duration,                                                                │
│   1350 │   │   )                                                                                 │
│   1351 │   │   for t in self.time_progression:                                                   │
│ ❱ 1352 │   │   │   self.update_to_time(t)                                                        │
│   1353 │   │   │   if not skip_rendering and not self.skip_animation_preview:                    │
│   1354 │   │   │   │   self.renderer.render(self, t, self.moving_mobjects)                       │
│   1355 │   │   │   if self.stop_condition is not None and self.stop_condition():                 │
│                                                                                                  │
│ C:\Users\creaple\Documents\projects\manim\.venv\Lib\site-packages\manim\scene\scene.py:1678 in   │
│ update_to_time                                                                                   │
│                                                                                                  │
│   1675 │   │   │   animation.update_mobjects(dt)                                                 │
│   1676 │   │   │   alpha = t / animation.run_time                                                │
│   1677 │   │   │   animation.interpolate(alpha)                                                  │
│ ❱ 1678 │   │   self.update_mobjects(dt)                                                          │
│   1679 │   │   self.update_meshes(dt)                                                            │
│   1680 │   │   self.update_self(dt)                                                              │
│   1681                                                                                           │
│                                                                                                  │
│ C:\Users\creaple\Documents\projects\manim\.venv\Lib\site-packages\manim\scene\scene.py:381 in    │
│ update_mobjects                                                                                  │
│                                                                                                  │
│    378 │   │   │   Change in time between updates. Defaults (mostly) to 1/frames_per_second      │
│    379 │   │   """                                                                               │
│    380 │   │   for mobj in self.mobjects:                                                        │
│ ❱  381 │   │   │   mobj.update(dt)                                                               │
│    382 │                                                                                         │
│    383 │   def update_meshes(self, dt: float) -> None:                                           │
│    384 │   │   for obj in self.meshes:                                                           │
│                                                                                                  │
│ C:\Users\creaple\Documents\projects\manim\.venv\Lib\site-packages\manim\mobject\mobject.py:901   │
│ in update                                                                                        │
│                                                                                                  │
│    898 │   │   │   │   if "dt" in inspect.signature(updater).parameters:                         │
│    899 │   │   │   │   │   updater(self, dt)                                                     │
│    900 │   │   │   │   else:                                                                     │
│ ❱  901 │   │   │   │   │   updater(self)                                                         │
│    902 │   │   if recursive:                                                                     │
│    903 │   │   │   for submob in self.submobjects:                                               │
│    904 │   │   │   │   submob.update(dt, recursive=recursive)                                    │
│                                                                                                  │
│ C:\Users\creaple\Documents\projects\manim\test.py:12 in <lambda>                                 │
│                                                                                                  │
│    9 │   │   point1 = Dot(axes.coords_to_point(0, 0, 0))                                         │
│   10 │   │   point1.add_updater(lambda mob: mob.move_to(axes.coords_to_point(timer.get_value(    │
│   11 │   │   lines1 = axes.get_lines_to_point(point1.get_center())                               │
│ ❱ 12 │   │   lines1.add_updater(lambda mob: mob.become(axes.get_lines_to_point(point1.get_cen    │
│   13 │   │                                                                                       │
│   14 │   │   self.add(axes, curve, point1)                                                       │
│   15 │   │   self.add(lines1)                                                                    │
│                                                                                                  │
│ C:\Users\creaple\Documents\projects\manim\.venv\Lib\site-packages\manim\mobject\mobject.py:3171  │
│ in become                                                                                        │
│                                                                                                  │
│   3168 │   │   │   if match_center:                                                              │
│   3169 │   │   │   │   mobject.move_to(self.get_center())                                        │
│   3170 │   │                                                                                     │
│ ❱ 3171 │   │   self.align_data(mobject, skip_point_alignment=True)                               │
│   3172 │   │   for sm1, sm2 in zip(self.get_family(), mobject.get_family(), strict=False):       │
│   3173 │   │   │   sm1.points = np.array(sm2.points)                                             │
│   3174 │   │   │   sm1.interpolate_color(sm1, sm2, 1)                                            │
│                                                                                                  │
│ C:\Users\creaple\Documents\projects\manim\.venv\Lib\site-packages\manim\mobject\mobject.py:2891  │
│ in align_data                                                                                    │
│                                                                                                  │
│   2888 │   │   │   self.align_points(mobject)                                                    │
│   2889 │   │   # Recurse                                                                         │
│   2890 │   │   for m1, m2 in zip(self.submobjects, mobject.submobjects, strict=False):           │
│ ❱ 2891 │   │   │   m1.align_data(m2)                                                             │
│   2892 │                                                                                         │
│   2893 │   def get_point_mobject(self, center=None):                                             │
│   2894 │   │   """The simplest :class:`~.Mobject` to be transformed to or from self.             │
│                                                                                                  │
│ C:\Users\creaple\Documents\projects\manim\.venv\Lib\site-packages\manim\mobject\mobject.py:2891  │
│ in align_data                                                                                    │
│                                                                                                  │
│   2888 │   │   │   self.align_points(mobject)                                                    │
│   2889 │   │   # Recurse                                                                         │
│   2890 │   │   for m1, m2 in zip(self.submobjects, mobject.submobjects, strict=False):           │
│ ❱ 2891 │   │   │   m1.align_data(m2)                                                             │
│   2892 │                                                                                         │
│   2893 │   def get_point_mobject(self, center=None):                                             │
│   2894 │   │   """The simplest :class:`~.Mobject` to be transformed to or from self.             │
│                                                                                                  │
│ C:\Users\creaple\Documents\projects\manim\.venv\Lib\site-packages\manim\mobject\mobject.py:2888  │
│ in align_data                                                                                    │
│                                                                                                  │
│   2885 │   │   self.null_point_align(mobject)                                                    │
│   2886 │   │   self.align_submobjects(mobject)                                                   │
│   2887 │   │   if not skip_point_alignment:                                                      │
│ ❱ 2888 │   │   │   self.align_points(mobject)                                                    │
│   2889 │   │   # Recurse                                                                         │
│   2890 │   │   for m1, m2 in zip(self.submobjects, mobject.submobjects, strict=False):           │
│   2891 │   │   │   m1.align_data(m2)                                                             │
│                                                                                                  │
│ C:\Users\creaple\Documents\projects\manim\.venv\Lib\site-packages\manim\mobject\types\vectorized │
│ _mobject.py:1786 in align_points                                                                 │
│                                                                                                  │
│   1783 │   │                                                                                     │
│   1784 │   │   for n in range(n_subpaths):                                                       │
│   1785 │   │   │   # For each pair of subpaths, add points until they are the same length        │
│ ❱ 1786 │   │   │   sp1 = get_nth_subpath(subpaths1, n)                                           │
│   1787 │   │   │   sp2 = get_nth_subpath(subpaths2, n)                                           │
│   1788 │   │   │   diff1 = max(0, (len(sp2) - len(sp1)) // nppcc)                                │
│   1789 │   │   │   diff2 = max(0, (len(sp1) - len(sp2)) // nppcc)                                │
│                                                                                                  │
│ C:\Users\creaple\Documents\projects\manim\.venv\Lib\site-packages\manim\mobject\types\vectorized │
│ _mobject.py:1772 in get_nth_subpath                                                              │
│                                                                                                  │
│   1769 │   │   def get_nth_subpath(path_list, n):                                                │
│   1770 │   │   │   if n >= len(path_list):                                                       │
│   1771 │   │   │   │   # Create a null path at the very end                                      │
│ ❱ 1772 │   │   │   │   return [path_list[-1][-1]] * nppcc                                        │
│   1773 │   │   │   path = path_list[n]                                                           │
│   1774 │   │   │   # Check for useless points at the end of the path and remove them             │
│   1775 │   │   │   # https://github.com/ManimCommunity/manim/issues/1959                         │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
IndexError: list index out of range

System specifications

System Details
  • OS (with version, e.g., Windows 10 v2004 or macOS 10.15 (Catalina)):
  • RAM:
  • Python version (python/py/python3 --version):
  • Installed modules (provide output from pip list):
PASTE HERE
LaTeX details
  • LaTeX distribution (e.g. TeX Live 2020):
  • Installed LaTeX packages:

Additional comments

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions