Skip to content

"AttributeError: 'list' object has no attribute 'reshape'" when use OpenGL renderer to transform a math LaTeX formula to another  #3617

Closed
@monusw

Description

@monusw

Description of bug / unexpected behavior

My manim version is 0.18.0. I got AttributeError: 'list' object has no attribute 'reshape' when I ran the code with manim -pqm --renderer=opengl foo.py BugScene in the How to reproduce the issue section below.

I also have a solution in the Additional comments section.

Expected behavior

It should render correctly.

How to reproduce the issue

Code for reproducing the problem
class BugScene(Scene):
    def construct(self):
        sin_text = Tex(r"$y = \sin(x)$").set_color(BLUE).to_corner(UL)
        self.add(sin_text)
        sin_text_2 = Tex(r"$y = \sin(x + \frac{\pi}{3})$").set_color(BLUE).to_corner(UL)
        self.play(Transform(sin_text, sin_text_2))
        self.wait()

Additional media files

Images/GIFs

Logs

Terminal output The traceback was:
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ /Users/wu/miniconda3/lib/python3.11/site-packages/manim/cli/render/commands.py:97 in render      │
│                                                                                                  │
│    94 │   │   │   │   for SceneClass in scene_classes_from_file(file):                           │
│    95 │   │   │   │   │   with tempconfig({}):                                                   │
│    96 │   │   │   │   │   │   scene = SceneClass(renderer)                                       │
│ ❱  97 │   │   │   │   │   │   rerun = scene.render()                                             │
│    98 │   │   │   │   │   if rerun or config["write_all"]:                                       │
│    99 │   │   │   │   │   │   renderer.num_plays = 0                                             │
│   100 │   │   │   │   │   │   continue                                                           │
│                                                                                                  │
│ /Users/wu/miniconda3/lib/python3.11/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:                                                  │
│                                                                                                  │
│ /Users/wu/Documents/Code/Python/pylearn/manim_demo/sin_f.py:94 in construct                      │
│                                                                                                  │
│    91 │   │   sin_text = Tex("$y = \sin(x)$").set_color(BLUE).to_corner(UL)                      │
│    92 │   │   self.add(sin_text)                                                                 │
│    93 │   │   sin_text_2 = Tex(r"$y = \sin(x + \frac{\pi}{3})$").set_color(BLUE).to_corner(UL)   │
│ ❱  94 │   │   self.play( Transform(sin_text, sin_text_2))                                        │
│    95 │   │   self.wait()                                                                        │
│    96                                                                                            │
│    97                                                                                            │
│                                                                                                  │
│ /Users/wu/miniconda3/lib/python3.11/site-packages/manim/scene/scene.py:1080 in play              │
│                                                                                                  │
│   1077 │   │   │   return                                                                        │
│   1078 │   │                                                                                     │
│   1079 │   │   start_time = self.renderer.time                                                   │
│ ❱ 1080 │   │   self.renderer.play(self, *args, **kwargs)                                         │
│   1081 │   │   run_time = self.renderer.time - start_time                                        │
│   1082 │   │   if subcaption:                                                                    │
│   1083 │   │   │   if subcaption_duration is None:                                               │
│                                                                                                  │
│ /Users/wu/miniconda3/lib/python3.11/site-packages/manim/utils/caching.py:65 in wrapper           │
│                                                                                                  │
│   62 │   │   │   "List of the first few animation hashes of the scene: %(h)s",                   │
│   63 │   │   │   {"h": str(self.animations_hashes[:5])},                                         │
│   64 │   │   )                                                                                   │
│ ❱ 65 │   │   func(self, scene, *args, **kwargs)                                                  │
│   66 │                                                                                           │
│   67 │   return wrapper                                                                          │
│   68                                                                                             │
│                                                                                                  │
│ /Users/wu/miniconda3/lib/python3.11/site-packages/manim/renderer/opengl_renderer.py:424 in play  │
│                                                                                                  │
│   421 │   │   self.file_writer.begin_animation(not self.skip_animations)                         │
│   422 │   │                                                                                      │
│   423 │   │   scene.compile_animation_data(*args, **kwargs)                                      │
│ ❱ 424 │   │   scene.begin_animations()                                                           │
│   425 │   │   if scene.is_current_animation_frozen_frame():                                      │
│   426 │   │   │   self.update_frame(scene)                                                       │
│   427                                                                                            │
│                                                                                                  │
│ /Users/wu/miniconda3/lib/python3.11/site-packages/manim/scene/scene.py:1208 in begin_animations  │
│                                                                                                  │
│   1205 │   │   """Start the animations of the scene."""                                          │
│   1206 │   │   for animation in self.animations:                                                 │
│   1207 │   │   │   animation._setup_scene(self)                                                  │
│ ❱ 1208 │   │   │   animation.begin()                                                             │
│   1209 │   │                                                                                     │
│   1210 │   │   if config.renderer == RendererType.CAIRO:                                         │
│   1211 │   │   │   # Paint all non-moving objects onto the screen, so they don't                 │
│                                                                                                  │
│ /Users/wu/miniconda3/lib/python3.11/site-packages/manim/animation/transform.py:201 in begin      │
│                                                                                                  │
│   198 │   │   # Note, this potentially changes the structure                                     │
│   199 │   │   # of both mobject and target_mobject                                               │
│   200 │   │   if config.renderer == RendererType.OPENGL:                                         │
│ ❱ 201 │   │   │   self.mobject.align_data_and_family(self.target_copy)                           │
│   202 │   │   else:                                                                              │
│   203 │   │   │   self.mobject.align_data(self.target_copy)                                      │
│   204 │   │   super().begin()                                                                    │
│                                                                                                  │
│ /Users/wu/miniconda3/lib/python3.11/site-packages/manim/mobject/opengl/opengl_mobject.py:2312 in │
│ align_data_and_family                                                                            │
│                                                                                                  │
│   2309 │                                                                                         │
│   2310 │   def align_data_and_family(self, mobject):                                             │
│   2311 │   │   self.align_family(mobject)                                                        │
│ ❱ 2312 │   │   self.align_data(mobject)                                                          │
│   2313 │                                                                                         │
│   2314 │   def align_data(self, mobject):                                                        │
│   2315 │   │   # In case any data arrays get resized when aligned to shader data                 │
│                                                                                                  │
│ /Users/wu/miniconda3/lib/python3.11/site-packages/manim/mobject/opengl/opengl_mobject.py:2320 in │
│ align_data                                                                                       │
│                                                                                                  │
│   2317 │   │   for mob1, mob2 in zip(self.get_family(), mobject.get_family()):                   │
│   2318 │   │   │   # Separate out how points are treated so that subclasses                      │
│   2319 │   │   │   # can handle that case differently if they choose                             │
│ ❱ 2320 │   │   │   mob1.align_points(mob2)                                                       │
│   2321 │   │   │   for key in mob1.data.keys() & mob2.data.keys():                               │
│   2322 │   │   │   │   if key == "points":                                                       │
│   2323 │   │   │   │   │   continue                                                              │
│                                                                                                  │
│ /Users/wu/miniconda3/lib/python3.11/site-packages/manim/mobject/opengl/opengl_vectorized_mobject │
│ .py:1225 in align_points                                                                         │
│                                                                                                  │
│   1222 │   │   │   diff2 = max(0, (len(sp1) - len(sp2)) // nppc)                                 │
│   1223 │   │   │   if isinstance(sp1, list):                                                     │
│   1224 │   │   │   │   print('align_points sp1', type(sp1))                                      │
│ ❱ 1225 │   │   │   sp1 = self.insert_n_curves_to_point_list(diff1, sp1)                          │
│   1226 │   │   │   if isinstance(sp2, list):                                                     │
│   1227 │   │   │   │   print('align_points sp2', type(sp1))                                      │
│   1228 │   │   │   sp2 = self.insert_n_curves_to_point_list(diff2, sp2)                          │
│                                                                                                  │
│ /Users/wu/miniconda3/lib/python3.11/site-packages/manim/mobject/opengl/opengl_vectorized_mobject │
│ .py:1280 in insert_n_curves_to_point_list                                                        │
│                                                                                                  │
│   1277 │   │                                                                                     │
│   1278 │   │   if isinstance(points, list):                                                      │
│   1279 │   │   │   print('insert_n_curves_to_point_list', type(points))                          │
│ ❱ 1280 │   │   bezier_groups = self.get_bezier_tuples_from_points(points)                        │
│   1281 │   │   norms = np.array([np.linalg.norm(bg[nppc - 1] - bg[0]) for bg in bezier_groups])  │
│   1282 │   │   total_norm = sum(norms)                                                           │
│   1283 │   │   # Calculate insertions per curve (ipc)                                            │
│                                                                                                  │
│ /Users/wu/miniconda3/lib/python3.11/site-packages/manim/mobject/opengl/opengl_vectorized_mobject │
│ .py:720 in get_bezier_tuples_from_points                                                         │
│                                                                                                  │
│    717 │   │   nppc = self.n_points_per_curve                                                    │
│    718 │   │   remainder = len(points) % nppc                                                    │
│    719 │   │   points = points[: len(points) - remainder]                                        │
│ ❱  720 │   │   return points.reshape((-1, nppc, 3))                                              │
│    721 │                                                                                         │
│    722 │   def get_bezier_tuples(self):                                                          │
│    723 │   │   return self.get_bezier_tuples_from_points(self.points)                            │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
AttributeError: 'list' object has no attribute 'reshape'

System specifications

System Details
  • OS: macOS 14.3.1 (Sonoma)
  • RAM: 64GB
  • Python version: 3.11.5
  • Installed modules (provide output from pip list):
PASTE HERE
LaTeX details
  • LaTeX distribution (e.g. TeX Live 2020): TeX Live 2023
  • Installed LaTeX packages:
FFMPEG

Output of ffmpeg -version:

ffmpeg version 4.2.2 Copyright (c) 2000-2019 the FFmpeg developers
built with clang version 12.0.0
configuration: --prefix=/Users/ktietz/demo/mc3/conda-bld/ffmpeg_1628925491858/_h_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_plac --cc=arm64-apple-darwin20.0.0-clang --disable-doc --enable-avresample --enable-gmp --enable-hardcoded-tables --enable-libfreetype --enable-libvpx --enable-pthreads --enable-libopus --enable-postproc --enable-pic --enable-pthreads --enable-shared --enable-static --enable-version3 --enable-zlib --enable-libmp3lame --disable-nonfree --enable-gpl --enable-gnutls --disable-openssl --enable-libopenh264 --enable-libx264
libavutil      56. 31.100 / 56. 31.100
libavcodec     58. 54.100 / 58. 54.100
libavformat    58. 29.100 / 58. 29.100
libavdevice    58.  8.100 / 58.  8.100
libavfilter     7. 57.100 /  7. 57.100
libavresample   4.  0.  0 /  4.  0.  0
libswscale      5.  5.100 /  5.  5.100
libswresample   3.  5.100 /  3.  5.100
libpostproc    55.  5.100 / 55.  5.100

Additional comments

I think the code below causes the issue:
https://github.com/ManimCommunity/manim/blob/011c36a6343baacefc092170a664624e3c4a737c/manim/mobject/opengl/opengl_vectorized_mobject.py#L1212C1-L1215C50

Because when I change the code return [path_list[-1][-1]] * nppc to return np.array([path_list[-1][-1]] * nppc), it works correctly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    🆕 New

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions