|
I want to display MathTex in front of a 3D scene that changes significantly throughout the animation. It seems that manim can't handle it - the rendered TeX seems to fall apart. What am I missing? I am using Manim Community v0.19.2. from manim import *
import numpy as np
from scipy.linalg import fractional_matrix_power
class ReproAnimation(ThreeDScene):
def construct(self):
self.camera.background_color = WHITE
radius_range = 2
L = (
config.frame_height + 2.5
) # make all axis lengths identical (pick what you like)
axes = ThreeDAxes(
x_range=[-radius_range, radius_range, 1],
y_range=[-radius_range, radius_range, 1],
z_range=[-radius_range, radius_range, 1],
x_length=L,
y_length=L,
z_length=L,
axis_config={"include_tip": True, "stroke_color": ORANGE},
)
time_tracker = ValueTracker(0)
state_text = always_redraw(lambda: self.get_state_tex(time_tracker.get_value()))
self.set_camera_orientation(phi=75 * DEGREES, theta=-45 * DEGREES)
self.add(axes, state_text)
self.add_fixed_in_frame_mobjects(state_text)
self.add_fixed_orientation_mobjects(state_text)
total_duration = 0.5
self.play(
time_tracker.animate.set_value(total_duration),
run_time=total_duration,
rate_func=linear,
)
def format_complex_number(self, z):
im_zero = np.isclose(z.imag, 0, atol=1e-3)
imag_sign = "+" if z.imag >= 0 else "-"
re_zero = np.isclose(z.real, 0, atol=1e-3)
real_sign = "+" if z.real >= 0 else "-"
if im_zero and re_zero:
return f"0", "+"
elif im_zero:
return f"{z.real:.2f}", real_sign
elif re_zero:
return f"{z.imag:.2f}i", imag_sign
else:
return f"({z.real:.2f}{imag_sign}{abs(z.imag):.2f}i)", real_sign
def get_state_tex(self, t):
alpha, beta = self.get_qubit_state_math(t)
alpha_str, _ = self.format_complex_number(alpha)
beta_str, beta_sign = self.format_complex_number(beta)
zero_str = "" if alpha_str == "0" else rf"{alpha_str} |0\rangle"
one_str = "" if beta_str == "0" else rf"{beta_str}|1\rangle"
superposition_str = f"{zero_str} {beta_sign if one_str and zero_str else ''} {one_str}"
tex = MathTex(
rf"|\psi\rangle = {superposition_str}",
color=BLACK,
font_size=36,
).move_to(DOWN * 6)
return tex
def get_qubit_state_math(self, t):
state0 = np.array([1.0 + 0.0j, 0.0 + 0.0j]) # |0>
X = np.array([[0, 1], [1, 0]], dtype=complex)
s = np.clip(t, 0.0, 1.0)
X_frac = fractional_matrix_power(X, s)
state = X_frac @ state0
return stateReproAnimation.mp4 |
Answered by
balopat
Feb 3, 2026
Replies: 3 comments
|
Note, the same code renders nicely in a regular ReproAnimation.mp4 |
0 replies
|
If I pad the string to the same number of non-invisible characters, then it renders perfectly. ...
full_str = rf"|\psi\rangle = {superposition_str}"
padding_chars = "." * ((100 - len(full_str)) // 2)
padded_str = rf"{padding_chars}{full_str}{padding_chars}"
tex = MathTex(
padded_str,
color=BLACK,
font_size=30,
).move_to(DOWN * 6)
...ReproAnimation.mp4This starts to feel like a rendering bug in manim. |
0 replies
|
Alright, padding with white (same color as background) dots seems to work now... ReproAnimation.mp4 |
0 replies
Answer selected by
balopat
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Alright, padding with white (same color as background) dots seems to work now...
ReproAnimation.mp4