ManimCommunity / ManimCommunity/manim

alwaysRedraw() and add_fixed_in_frame_mobjects() bugs with MathTex

Open
#2,601 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

issue:bug
Dominant language
Python
Stars
40.9k
Forks
3.1k
Avg merge
3d 12h
Merged PRs (30d)
25

Description

Description of bug / unexpected behavior

With 3D plots I noticed that MathTex labels are missing characters when packaged inside alwaysRedraw() and positioned with add_fixed_in_frame_mobjects(). What's even more interesting is those missing characters flicker onto other axes rather than on the fixed frame!

Try running this gradient descent demonstration and you'll see those artifacts pop up.

Expected behavior

All mathematical latex characters should be in the fixed frame and not flickering to other axes on a 3D system.

How to reproduce the issue

Run the code below. Feel free to cut the iterations so it completes more quickly.

import numpy as np
import pandas as pd
from manim import *
from sympy import *

class ThreeDScatter(ThreeDScene):
    def construct(self):
        self.set_camera_orientation(phi=70 * DEGREES, theta=-30 * DEGREES)

        axes = ThreeDAxes(x_range=[-5,5,1],y_range=[-5,5,1],z_range=[-1,5,1])
        self.add(axes)

        data = list(pd.read_csv("https://bit.ly/3ty5BRZ").itertuples())

        a, b, c, i, n = symbols('a b c i n')
        x1, x2, y = symbols('x1 x2 y', cls=Function)
        f = Sum((y(i) - (a * x1(i) ** 2 + b * x2(i) ** 2 + c))**2, (i, 0, n)) \
            .subs(n, len(data) - 1).doit() \
            .replace(x1, lambda i: data[i].x1) \
            .replace(x2, lambda i: data[i].x2) \
            .replace(y, lambda i: data[i].y)

        d_da = lambdify([a, b, c], diff(f,a))
        d_db = lambdify([a, b, c], diff(f,b))
        d_dc = lambdify([a, b, c], diff(f,c))

        adjustments = []
        iterations = 2000
        L = .0001
        a,b,c = 5, 5, 5

        for i in range(0,iterations):
            a -= L * d_da(a, b, c)
            b -= L * d_db(a, b, c)
            c -= L * d_dc(a, b, c)

            print(a,b,c)
            if round(a, 4) == round(0.15796197645267426,4) and \
                round(b,4) == round(0.2540842631984235, 4) and \
                round(c,4) == round(-0.17889460357692097, 4):
                    print(i)
                    break

            adjustments.append((a,b,c))

        # graphical visualization
        for i in range(0, len(data)):
            self.add(Sphere(center=(data[i].x1, data[i].x2, data[i].y), radius=.05))

        a = ValueTracker(adjustments[0][0])
        b = ValueTracker(adjustments[0][1])
        c = ValueTracker(adjustments[0][2])

        def param_f(u, v):
            x1 = u
            x2 = v

            y = a.get_value() * x1**2 + b.get_value() * x2**2
            return np.array([x1, x2, y])

        def draw_plot():
            s = Surface(
                param_f,
                resolution=(42, 42),
                v_range=[-5, +5],
                u_range=[-5, +5]
            )
            s.set_style(fill_opacity=.5, stroke_color=BLUE)
            s.set_fill(BLUE, opacity=0.2)
            return s

        surface_plot = always_redraw(draw_plot)

        self.add(surface_plot)

        coeff_label = always_redraw(lambda: MathTex("a &= ", round(a.get_value(), 4),
                                                  "\\\\b &= ", round(b.get_value(), 4),
                                                    "\\\\c &=  ", round(c.get_value(), 4),
                                                  font_size=35).to_edge(DL))

        self.add_fixed_in_frame_mobjects(coeff_label)


        for i in range(0,len(adjustments)):
            self.play(
                a.animate.set_value(adjustments[i][0]),
                b.animate.set_value(adjustments[i][1]),
                c.animate.set_value(adjustments[i][2]),
                run_time=max(.1, 1.0 - (i * .01)),
                rate_func = linear
            )

You can also see this behavior on another example I uploaded a video for here. Look in the first 10 seconds and notice how some of the digits teleport behind the line graph.

https://www.youtube.com/watch?v=t2ocp134aHg

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Run the provided ThreeDScene reproduction, focusing on the interaction between always_redraw, MathTex, and add_fixed_in_frame_mobjects. Trace those entry points through the rendering behavior and verify the fix by confirming that every label character stays in the fixed frame without flickering onto other axes.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
computer-graphics
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.