Skip to main content

ManimPresentations

A small layer on top of manim-slides for building presentations out of reusable pieces, and for rendering any one of those pieces on its own — with the real overlay, the real slide number, in the real position it has in the deck.

Main objectives

  • a clear hierarchy: deck → chapters → slides
  • shared elements across slides (slide number, chapter progress, title, author, event, year)
  • compose decks out of chapters and slides that can be reused elsewhere
  • render and present the deck without naming its scenes
  • render any single chapter or single slide, and see exactly what the full deck will show

State of the project

This is a personal project that I started to make my life easier when creating presentations with Manim. It may be useful to others, but do not consider it a complete, elegant or polished solution. If you have suggestions, ideas or feedback, feel free to open a discussion.

Installation

pip install manim-presentations

Or, from a clone:

pip install -e .

A deck in one file

from manim import *
from manim_presentations import Deck, Chapter, SlideUnit


class Bullets(SlideUnit):
	def __init__(self, headline, *lines, notes=""):
		self.headline = headline
		self.lines = lines
		self.notes = notes

	def construct(self):
		previous = Text(self.headline, font_size=48)
		self.play(Write(previous), run_time=0.25)
		for line in self.lines:
			self.next_slide()
			following = Text(line, font_size=36).next_to(previous, DOWN, buff=0.5)
			self.play(Write(following), run_time=0.25)
			previous = following


deck = Deck(
	title="My Presentation",
	subtitle="Subtitle",
	first_author="Author",
	event="My Event",
	year="2025",
	chapters=[
		Chapter("Intro", "Chapter 1: Where it all begins", "Chapter 1", units=[
			Bullets("First slide", "It even has a second line!", notes="Say hello."),
			Bullets("Second slide"),
		]),
	],
)

deck.register(globals())
manim-presentations render deck.py -ql     # render everything
manim-presentations present deck.py        # play it

The command lives in the environment you installed into, so activate it first (source .venv/bin/activate), or use uv run manim-presentations .... If your shell still reports an unknown command right after installing, it has cached its PATH — run rehash or open a new shell. python -m manim_presentations ... works either way and takes the same arguments.

Commands

manim-presentations reads the Deck in your file and hands its scenes to manim-slides in the right order, so you never type scene names. Any option it does not recognise is forwarded to manim-slides, so -ql, --full-screen and the rest still work.

manim-presentations render deck.py -ql
manim-presentations render deck.py --only Intro -ql        # one chapter
manim-presentations render deck.py --only Intro_S2 -ql     # one slide
manim-presentations present deck.py
manim-presentations convert deck.py slides.html
manim-presentations list deck.py                           # scene names, in order

The generated scenes are ordinary Manim scenes, so the manim-slides commands work directly too:

manim-slides render deck.py Intro -ql
manim-slides present Title Intro End

Components

SlideUnit

One unit of content, and the thing the slide number counts. It is not a Scene: inside construct, self forwards to the Scene currently rendering the unit, so self.play, self.add, self.wait, self.next_slide and self.camera behave as usual.

Units are ordinary objects, so they take constructor arguments and can be reused:

Bullets("Results"), Bullets("Method", "Two steps", notes="...")
  • notes — presenter notes for this unit.
  • clears — whether the unit's mobjects are removed when it ends. Default True.

self.next_slide() inside a unit is a pause: the audience presses a key, but the slide number does not move. The number advances at unit boundaries. To split one continuous build-up across several numbers, set clears = False on the units that should hand their mobjects to the next one:

Chapter("Proof", "The proof", units=[
	Steps("Setup", clears=False),   # slide 4, mobjects stay on screen
	Steps("Conclusion"),            # slide 5, builds on them, then clears
])

Anything registered with self.add_to_canvas(...) survives regardless — that is where the overlay lives.

Chapter

An ordered group of units, rendered as one Scene.

Chapter("Method", "Chapter 2: How it works", "Method", units=[...], intro=True)
  • name — the Scene name, so it must be a valid Python identifier and unique in the deck.
  • title / short_title — long form for the chapter card, short form for the overlay. short_title defaults to title.
  • intro — whether the chapter opens on a title card. Set to False to start on the first unit.

Deck

The presentation itself: metadata plus chapters. register(globals()) turns it into scenes — one per chapter, plus Title and End, plus one preview scene per unit (Method_S3).

deck.register(globals())                    # with per-unit previews
deck.register(globals(), previews=False)    # chapters only

intro=False / outro=False on the Deck drop the Title and End scenes.

Every scene knows its own position in the deck, computed from the deck definition rather than from what has already been rendered. That is why a single chapter or a single unit renders with the slide number and progress bar it has in the full presentation. A unit preview also replays any preceding units marked clears = False, so it shows what that unit actually sits on.

Theme

Everything that is not slide content: the chapter bars, the progress bar, the chapter label, the slide number, the footer, and the three full-frame cards. Subclass it and pass an instance to Deck(theme=...) to restyle a deck without touching a single slide.

Upgrading from 0.1

0.2 replaces ModularSlide / Chapter / Presentation with SlideUnit / Chapter / Deck. The presentation is no longer one giant Scene; each chapter is its own Scene and manim-slides plays them in sequence.

0.1 0.2
class Slide1(ModularSlide) class Slide1(SlideUnit) — and instantiate it: Slide1()
self.inner_canvas.add(x) delete the line; unit mobjects are cleared automatically
self.scenes = [Slide1, Slide2] units=[Slide1(), Slide2()]
class Chapter1(Chapter) with __init__ Chapter("Chapter1", "Long title", "Short", units=[...])
class MyTalk(Presentation) with __init__ deck = Deck(...) then deck.register(globals())
next_slide(incr=True) split into two units; use clears=False to keep mobjects
manim-slides render talk.py MyTalk manim-presentations render talk.py

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

manim_presentations-0.2.0.tar.gz (14.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

manim_presentations-0.2.0-py3-none-any.whl (13.2 kB view details)

Uploaded Python 3

File details

Details for the file manim_presentations-0.2.0.tar.gz.

File metadata

  • Download URL: manim_presentations-0.2.0.tar.gz
  • Upload date:
  • Size: 14.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for manim_presentations-0.2.0.tar.gz
Algorithm Hash digest
SHA256 279369db44c8b5cf4b91a6235e1a61e676cbbdd4d9883e3f99c0e4091410feea
MD5 5314498271dd50bddc872eba12bdd5e0
BLAKE2b-256 e75e57d3aeb0f92c7ad53fc989944f200905761122198a281df7826349d92975

See more details on using hashes here.

File details

Details for the file manim_presentations-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for manim_presentations-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c6c55bb8cbbfe9f7ae7ce976ba60160067532c4f74deb6fb4cf03dc911b95663
MD5 32df28b56a7cdd008372da5b884d1a36
BLAKE2b-256 dc19e0500eb71f428fb9e4a553015460a4e3d949b94e310ca6f33b854210e7ed

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 files

0.1.71

2 files

0.1.61

2 files

0.1.8

2 files

0.1.5

2 files

0.1.3

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page