Manim adding simple label updaters in loop

54 Views Asked by At

I have two lists of MObjects: elements and labels. I need to add an updater for every label to stay inside corresponding element.

So this is what I do:

self.elements: list[Circle] = []
self.labels: list[Tex] = []

for i in range(5):
    angle = i * (360 / num_elements)
    point = self.circle.point_at_angle(angle*DEGREES)
            
    element = Circle(.75, WHITE, fill_opacity=1)
    element.move_to(point)
    self.elements.append(element)

    label = Tex(f'$\\mathbf{i+1}$', color=BLACK, font_size=70)
    label.move_to(point)
    label.add_updater(lambda mob: mob.move_to(element))

    self.labels.append(label)

The problem is that all labels stick to last element:

enter image description here

How do I fix this problem?

1

There are 1 best solutions below

2
ybl On BEST ANSWER

Your loop makes use of a nested lambda function which is evaluated after the loop exits and points to the same circle element, which is the last one. You should update the code using the default argument so that it points to the correct one.

label.add_updater(lambda mob, elem=element: mob.move_to(elem))  # Use default argument to capture the current value of the element

Reference: https://docs.python-guide.org/writing/gotchas/#late-binding-closures