Add a reproducible toolkit for the Preceptor Table → DGM → graph animation - #36
Open
sophiezla wants to merge 1 commit into
Open
Add a reproducible toolkit for the Preceptor Table → DGM → graph animation#36sophiezla wants to merge 1 commit into
sophiezla wants to merge 1 commit into
Conversation
…imation
Adds animations/, a self-contained folder that teaches an AI agent how to
build the narrated animation connecting a Preceptor Table, the DGM formula,
and the final answer. Nothing under book/ changes.
The animation is one continuous narrated video, not two clips: the table
fills row by row, the filled values fly down and become a graph, and the
table stays faintly visible under the finished histogram. That persistence
is the argument -- the graph did not replace the table, it is what the table
becomes when you run it enough times.
Two videos per chapter, not one. Every example chapter carries a primary
question and its paired opposite framing, so one script builds both from a
`framing` argument: the predictive cut fills a single Outcome column and
graphs the outcome; the causal cut fills two potential-outcome columns,
greys the one that can never be observed, and graphs their difference
against a zero line. The quantity being graphed funnels through a single
`value` column so no layer below the table knows which framing it is
drawing -- forking the script would guarantee the pair drifts apart.
Narration drives the edit. Each beat is held for exactly as long as its
sentence takes to say, measured from synthesised audio at build time, so
there is no beat-length constant to tune; to change the pace, change the
words. The spoken line and the on-screen caption are the same sentence, so
a muted viewer loses nothing.
Contents (~50 KB of text, no binaries):
animations.md design contract, requirements, and the
build gotchas worth not rediscovering
preceptor_to_graph_video.R one script, four renders
example-embed.qmd worked example of the finished embed
.gitignore excludes the ~4 MB of rendered video and
the ~25 MB narration cache, both of which
are reproducible output
Build with:
BUILD_ANIMATIONS=true Rscript animations/preceptor_to_graph_video.R
Requires gganimate, av, ggtext and tuneR, plus edge-tts for narration; no
external ffmpeg. check_deps() fails early naming exactly what is missing,
and narrate = FALSE builds silent videos when edge-tts is unavailable.
The worked example is the Senators net-worth question from guide/tables.md
10.3, chosen as the simplest table in the guide. It is a demonstration, not
any chapter's material; adopting it means editing the two CONFIG blocks and
the narration sentences, and nothing below them.
CLAUDE.md gains a pointer to the toolkit, and its "Record corrections"
protocol is generalised to say lessons belong in the most specific file
that owns the subject, with the reasoning attached.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
animations/, a self-contained folder that teaches an AI agent how to build the narrated animation connecting a Preceptor Table, the DGM formula, and the final answer.Nothing under
book/changes.git diff main -- book/is empty. No chapter, no rendered output, no book asset is touched.What the animation is
One continuous narrated video, not two clips. The table fills row by row, the filled values fly down and become a graph, and the table stays faintly visible under the finished histogram. That persistence is the argument: the graph did not replace the table, it is what the table becomes when you run it enough times. Cutting between two clips would destroy exactly that claim.
Two videos per chapter, not one
Every example chapter carries a primary question and its paired opposite framing, so one script builds both from a
framingargument:In the causal cut, one potential outcome per row is greyed and italic — the branch that unit did not live. The fundamental problem of causal inference, sitting in a table cell.
The quantity being graphed funnels through a single
valuecolumn, so no layer below the table knows which framing it is drawing. Forking the script to add a framing would guarantee the pair drifts apart, and drift between a chapter's primary and paired artefacts is the one thing it cannot afford.Narration drives the edit
Each beat is held for exactly as long as its sentence takes to say, measured from the synthesised audio at build time. There is no beat-length constant to tune — to change the pace, change the words. The spoken line and the on-screen caption are the same sentence, so a muted viewer loses nothing, which matters because tutorials often play muted.
Contents
~50 KB of text, no binaries:
Requires gganimate, av, ggtext, tuneR, plus
edge-ttsfor narration. No externalffmpeg.check_deps()fails early naming exactly what is missing, andnarrate = FALSEbuilds silent videos whenedge-ttsis unavailable. Runs from any working directory.On reproducibility — one honest caveat
The statistical content is deterministic:
set.seed(2026)sits inside the builder, so every error draw and every table value is identical run to run.The edit timing is not. Beats are cut to synthesised speech, and
edge-ttsis a network service that returns marginally different audio for the same sentence. A cold rebuild moved frame counts by up to 14 frames (0.7s) per video. This is documented inanimations.md§10 so nobody treats a differing frame count as a bug. Committing thenarration/cache would make rebuilds byte-identical, at ~25 MB.Verification
quarto renderof the book: exit 0, all 18 chaptersexample-embed.qmdlives outside the Quarto project, so it can never render into the book by accidentTwo things worth a reviewer's opinion
The worked example is the Senators net-worth question from
guide/tables.md§10.3, chosen as the simplest table in the guide. It is a demonstration, not any chapter's material. Adopting it for a real chapter means editing the twoCONFIGblocks and the narration sentences, and nothing below them. Which chapter should claim it is an open question.The causal cut gives Y(1) and Y(0) independent error draws, so the individual causal effect is τ + (ε₁ − ε₀), spread by σ√2. Reusing one error makes every unit's effect exactly τ, the distribution collapses to a spike, and Act 3 has nothing to show. If the Primer would rather teach constant treatment effects, Act 3 needs a different subject.
Also in this PR, and separable if you would rather it were:
CLAUDE.md's "Record corrections" protocol is generalised to say lessons belong in the most specific file that owns the subject, with the reasoning attached rather than just the rule.🤖 Generated with Claude Code