# How to Animate Numerical Values Using the ValueTracker in Manim

> Animate numerical values in Manim with ValueTracker. Learn to track and display changing numbers smoothly, enhancing your educational math animations.

- Repository: [Grant Sanderson/manim](https://github.com/3b1b/manim)
- Tags: how-to-guide
- Published: 2026-02-28

---

**To animate numerical values in Manim, instantiate a `ValueTracker` to store a hidden numeric state, connect it to a visual element via an updater function, and call `self.play(tracker.animate.set_value(target))` to interpolate the value over time.**

The `ValueTracker` class in the 3b1b/manim library provides a lightweight mechanism for driving animations with numerical data. Because it inherits from `Mobject`, it integrates seamlessly with Manim’s animation system while remaining invisible on screen, making it ideal for controlling positions, colors, or displayed numbers without managing complex keyframe logic manually.

## What Is the ValueTracker?

`ValueTracker` is a specialized `Mobject` defined in [`manimlib/mobject/value_tracker.py`](https://github.com/3b1b/manim/blob/main/manimlib/mobject/value_tracker.py) that stores a numeric value inside its *uniforms* dictionary rather than rendering any geometry. This design allows the object to participate in the animation graph while acting purely as a data source.

The core implementation reveals how the value is stored and accessed:

```python
class ValueTracker(Mobject):
    def init_uniforms(self):
        self.uniforms["value"] = np.array(listify(self.value), dtype=self.value_type)
    
    def get_value(self):
        result = self.uniforms["value"]
        return result[0] if len(result) == 1 else result
    
    def set_value(self, value):
        self.uniforms["value"][:] = value
        return self

```

Because `set_value()` returns `self`, you can chain it with `.animate` to create smooth interpolations. The stored value can be a scalar, a complex number, or a NumPy array, providing flexibility for multi-dimensional tracking.

## Connecting ValueTracker to Visual Elements with Updaters

To make the tracked value visible, you attach an **updater** to a rendered mobject. Updaters are functions called every frame that read the current tracker value and update the visual element accordingly.

A typical pattern for moving an object based on a changing number looks like this:

```python
tracker = ValueTracker(0)  # Start at position 0

dot = Dot()
dot.add_updater(lambda m: m.move_to(tracker.get_value() * RIGHT))
self.add(dot)

# Animate the tracker to move the dot

self.play(tracker.animate.set_value(3), run_time=2)

```

In this example, the dot remains stationary until `self.play` interpolates the tracker’s internal value from `0` to `3`. Because the updater runs continuously, the dot slides smoothly along the x-axis without requiring explicit coordinate keyframes.

## Displaying and Animating Numbers On Screen

While `ValueTracker` handles the hidden state, Manim provides `DecimalNumber` (defined in [`manimlib/mobject/numbers.py`](https://github.com/3b1b/manim/blob/main/manimlib/mobject/numbers.py)) to render typeset numbers that update in real time.

### Rendering Numbers with DecimalNumber

`DecimalNumber` is a `VMobject` that displays a floating-point value. When combined with a `ValueTracker` updater, it creates a live counter:

```python
tracker = ValueTracker(0)
number = DecimalNumber(0, num_decimal_places=1).to_edge(UP)
number.add_updater(lambda m: m.set_value(tracker.get_value()))
self.add(number)

self.play(tracker.animate.set_value(100), run_time=3)

```

### Using ChangeDecimalToValue for Direct Animation

For cases where you want to animate a number without manually managing a `ValueTracker`, Manim offers the `ChangingDecimal` animation class and its subclasses in [`manimlib/animation/numbers.py`](https://github.com/3b1b/manim/blob/main/manimlib/animation/numbers.py). These animations interpolate a `DecimalNumber` directly by repeatedly calling a *number_update_func*.

The base `ChangingDecimal` class works as follows:

```python
class ChangingDecimal(Animation):
    def __init__(self, decimal_mob, number_update_func, ...):
        self.number_update_func = number_update_func
        super().__init__(decimal_mob, ...)
    
    def interpolate_mobject(self, alpha):
        new_value = self.number_update_func(self.time_spanned_alpha(alpha))
        self.mobject.set_value(new_value)

```

Convenient subclasses include:

- **ChangeDecimalToValue**: Linearly interpolates from the current number to a specified target value.
- **CountInFrom**: Counts in from a starting value to the current number, useful for intro animations.

Example usage:

```python
number = DecimalNumber(0).to_edge(UP)
self.add(number)

# Animate the number from its current value (0) to 5 over 3 seconds

self.play(ChangeDecimalToValue(number, target_number=5, run_time=3))

```

## Advanced ValueTracker Variants

Manim provides specialized trackers for specific interpolation behaviors, all inheriting from the base `ValueTracker` class.

### ExponentialValueTracker

`ExponentialValueTracker` stores the **logarithm** of the desired value rather than the value itself. When animated, this produces exponential growth or decay instead of linear interpolation. This is useful for zooming effects or scaling animations where perceptual speed should increase with size.

```python
exp_tracker = ExponentialValueTracker(1)  # Stores log(1) = 0

dot = Dot().add_updater(lambda m: m.move_to(exp_tracker.get_value() * RIGHT))
self.add(dot)

# Animates from 1 to 4 exponentially

self.play(exp_tracker.animate.set_value(4), run_time=2)

```

### ComplexValueTracker

`ComplexValueTracker` changes the underlying `value_type` to `np.complex128`, allowing you to track complex numbers. This is particularly useful for animating rotations in the complex plane or phasor diagrams where the real and imaginary components must evolve simultaneously.

All variants share the same uniform-based storage mechanism, ensuring they work interchangeably with standard updaters and animations.

## Summary

- **`ValueTracker`** is an invisible `Mobject` that stores numeric state in its `uniforms` dictionary, enabling it to work with Manim’s animation system.
- Access the current value with **`get_value()`** and update it (for animation) with **`set_value()`**, which supports method chaining with `.animate`.
- Connect trackers to visual elements using **updaters**—functions that read the tracker each frame and update geometry, positions, or colors.
- Display numbers on screen with **`DecimalNumber`**, and animate them directly using **`ChangeDecimalToValue`** or **`CountInFrom`** from [`manimlib/animation/numbers.py`](https://github.com/3b1b/manim/blob/main/manimlib/animation/numbers.py).
- Use **`ExponentialValueTracker`** for exponential interpolation and **`ComplexValueTracker`** for complex-valued animations.

## Frequently Asked Questions

### What is the difference between ValueTracker and DecimalNumber?

**`ValueTracker`** is an invisible data container that holds a number but renders nothing on screen, while **`DecimalNumber`** is a visual `VMobject` that displays a number as text. Typically, you use a `ValueTracker` to store the state and a `DecimalNumber` with an updater to display it, or you animate the `DecimalNumber` directly using `ChangeDecimalToValue`.

### Can I animate multiple values simultaneously with ValueTracker?

Yes. Since `ValueTracker` can store a **NumPy array** instead of a scalar, you can track multiple dimensions at once. Alternatively, you can create multiple `ValueTracker` instances and reference them in a single updater function that combines their values to update a visual element’s position, color, or other attributes.

### How do I access the current value during an animation?

Call **`tracker.get_value()`** inside an updater function or during scene construction. The method retrieves the value from the internal `uniforms` dictionary. If you need the value to drive another animation or logic, query it within the `interpolate` method of a custom animation or inside a `there_and_back` style animation loop.

### When should I use ExponentialValueTracker instead of ValueTracker?

Use **`ExponentialValueTracker`** when you want the animation to speed up or slow down exponentially rather than linearly. Because it stores the logarithm of the value, interpolating from 1 to 4 takes the same time as from 4 to 16, making it ideal for zooming camera animations, scaling objects where perceptual size matters, or decay effects like radioactive half-life visualizations.