A resting human heart at 60 BPM, animated from one English sentence. You asked Claude. Glyph drew it. A relaxation oscillator from 1961 produces the same spike-and-recover rhythm your heart is making right now.
"Draw me a heartbeat — a resting human heart at 60 beats per minute. Use the Glyph viz grammar. Use a FitzHugh-Nagumo relaxation oscillator so the trace shows the real spike-and-recover rhythm, not a sine wave. Make it beautiful — a child should recognize the lub-dub, a grandparent should feel the rhythm of their own pulse."
— what to say to your AI agent. Claude translates the prompt into a Glyph JSON spec; the Glyph compiler integrates the ODE and renders the trace.
Each heartbeat is three coordinated electrical events. Both the ECG trace above and the FitzHugh-Nagumo ODE that Glyph compiles reproduce the same pattern.
The sinoatrial node fires. Both atria contract, pushing blood into the ventricles. On the trace: a small smooth bump above the baseline.
The ventricles contract. The biggest electrical event in your body — visible as the sharp spike on every monitor. About 70 mL of blood leaves the heart in one beat.
The ventricles relax and reset their voltage. By 1000 ms (one full second) the cycle begins again. Awake, asleep, walking, dreaming — every second, all life long.
Claude writes the JSON; Glyph integrates the ODE with RK4 and renders the trace. Same spec → byte-identical SVG, every platform, every run.
// heartbeat.json — FitzHugh-Nagumo relaxation oscillator { "version": "glyph/0.1", "title": "Heartbeat", "data": { "trajectory": { "shape": "trajectory", // dV/dt = V − V³/3 − W + 0.5 "dxdt": "x - x*x*x/3 - y + 0.5", // dW/dt = ε(V + a − bW), with ε=0.08, a=0.7, b=0.8 "dydt": "0.08*(x + 0.7 - 0.8*y)", "initial": { "x": -1.2, "y": -0.6 }, "time": { "min": 0, "max": 200, "samples": 2000 } } }, "layers": [{ "mark": "line", "encoding": { "x": { "field": "t" }, // time across "y": { "field": "x" } // membrane V up } }] }
Two coupled ODEs solved with 4th-order Runge-Kutta. The slow recovery variable W is what gives the trace its sharp spike followed by a long recovery — a real heart, not a sine wave. View on GitHub.
Byte-stable across Ubuntu / macOS / Windows × Node 20 / 22. The 200-second integration window shows ~12 full FHN cycles — the same number of cycles a resting heart completes in 12 seconds at 60 BPM.
Tell Claude what living thing or rhythm you want to see. Name the model, name the audience.
"Show me the difference between a healthy heart and one with arrhythmia. Use FitzHugh-Nagumo for both; in the second, change the I parameter to a value that breaks the rhythm. Side by side, same x-axis."
"Draw me a neuron firing. Use the Hodgkin-Huxley or FitzHugh-Nagumo model. Animate one action potential, then a burst of three in quick succession."
"Show me a van der Pol oscillator at three different μ values — small (almost sine), medium, and large (sharp relaxation). Three traces, same axes."
"Draw me the heartbeat alongside a metronome ticking at the same tempo. Show how a healthy heart isn't a clock — small natural variations in the inter-beat interval are a sign of life."