Skip to content

Conversation

@arnaud-ma
Copy link
Contributor

@arnaud-ma arnaud-ma commented Jan 17, 2026

Motivation and Explanation: Why and how do your changes improve the library?

For example:

class SceneWithRandomness(Scene):
    def construct(self):
        dots = VGroup()
        for _ in range(10):
            dot = Dot(point=np.random.uniform(-3, 3, size=3))
            dots.add(dot)
        self.add(dots)
        self.wait()

class SecondSceneWithRandomness(Scene):
    def construct(self):
        dots = VGroup()
        for _ in range(15:
            dot = Dot(point=np.random.uniform(-3, 3, size=3))
            dots.add(dot)
        self.add(dots)
        self.wait()

Before this PR, the points were never in the same position at each run. A seed option is added to get exactly the same result every time, e.g. with manim -pql --seed 42 main.py *.

It also works with multiple scenes. For example here, the 5 points of the second scene will be the same as the first 5 points of the first scene.

Links to added or changed documentation pages

https://manimce--4532.org.readthedocs.build/en/4532/guides/configuration.html

Further Information and Comments

There is some drawbacks:

  • Will break if something else than random or numpy.random is used for randomness (e.g. secrets or torch.random).

  • To avoid any change for the user, it simply modifies the global random state at each scene initialization. A pseudo-code is:

    set_seed(config.seed)
    scene = Scene1()
    scene.render()
    set_seed(config.seed)
    scene2 = Scene2()
    scene2.render()

    So if scenes are created in a different order, or if anything that uses random numbers is created between the the init and the render, results will be different.

The only way for the user to avoid any drawback is to get a local random state for each scene

rng = np.random.default_rng(config.seed)
class SceneWithRandomness(Scene):
	def construct(self):
		dots = VGroup()
		for _ in range(10):
			dot = Dot(point=rng.uniform(-3, 3, size=3))
			dots.add(dot)
		self.add(dots)
		self.wait()

or same with rng = random.Random(config.seed) for the random module.

In this case, the only thing that this PR brings is the seed config option, nothing else.

Reviewer Checklist

  • The PR title is descriptive enough for the changelog, and the PR is labeled correctly
  • If applicable: newly added non-private functions and classes have a docstring including a short summary and a PARAMETERS section
  • If applicable: newly added functions and classes are tested

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant