Skip to content
Sample of P5Live sin/cos Spirograph Sketch

live_coding_synth · P5LiveSketch

P5Live sin/cos Spirograph Sketch

A pure-numpy port of the canonical p5.js sin/cos live-coding sketch: a spirograph-like cloud of points whose polar coordinates are themselves nested sin/cos chains. Three rings morph over time, each ring's instantaneous radius is a sin(t*omega_k + phi_k) added to a base radius, and every point is drawn as a soft disc whose hue is HSV((i + t*speed) / N, 0.65, 1.0). The whole canvas trails with persistence 0.93 per step so past frames leave a soft ghost — the same look you get in P5Live when you call `background(8, 12, 24, 30)` instead of `background(0)` each frame. Re-creates the live-coding session that Ted Davis (P5Live) and the Coding Train demonstrate in their 'sin/cos for generative art' lessons — exactly the kind of sketch a beginner writes on stage while narrating 'now I'm going to change that 0.13 to 0.21'.

Original: https://p5js.org

▶ Try the live demo (JS port) ▶ Run reference.py via Pyodide 10 formulas have instant JS ports. The Pyodide path runs the actual Python in your browser — first load is ~6 MB, then instant.

Family
live_coding_synth
Source
live_coding_synth
Evolution
sketch
Render
live_sketch
Complexity
low
Agents
240
Year
2024
Author
p5.js / P5Live community (The Coding Train, Ted Davis; live-coding sin/cos demos)

Math essence

For each point i in [0, N): a_i = i*point_freq + t*0.01; ring_mod = (1/R) Σ ring_radii[k] * sin(t*ring_freqs[k] + ring_phases[k] + jitter*0.5); r0 = 0.55*max_r + ring_mod; x = cx + r0*cos(a_i); y = cy + r0*sin(a_i); sz = 4 + 4*sin(t*size_freq + i*0.21); hue = (i/N + t*hue_speed/360) mod 1; canvas = max(canvas, falloff*HSV2RGB(hue, 0.65, 1.0)).

Parameters

Name Type Default Range Description
dim int 480 256–720 Output side length in pixels (HxW).
n_points int 240 40–800 Number of sin/cos-driven points per frame.
n_rings int 3 1–6 Number of nested sin/cos rings (radius-morph chains).
ring_radii tuple 0.36,0.2,0.1 — Per-ring amplitude as fraction of max radius.
ring_freqs tuple 0.07,0.13,0.21 — Per-ring sin time-frequency.
ring_phases tuple 0,1.7,3.4 — Per-ring sin phase offset.
point_freq float 0.31 0.05–1.5 Angular step per point (radians).
size_freq float 0.13 0.02–0.5 Time-frequency of the per-point size oscillation.
hue_speed float 30 0–120 How fast the per-point hue cycles (degrees per tick).
trail float 0.93 0–0.99 Per-step canvas persistence.
bg_color tuple 8,12,24 — Background colour.
seed int null 0–999999 RNG seed (controls the per-point jitter).

Reference

First 60 lines of reference.py. Full source: library_external/live_coding_synth/P5LiveSketch/reference.py

"""P5LiveSketch — a p5.js-style live-coding sketch in pure numpy.

A sin/cos-driven parametric animation that re-creates the visual
a P5Live session produces when a coder types lines like:

    function setup() { createCanvas(W, W); }
    function draw() {
        background(8, 12, 24);
        translate(W/2, W/2);
        for (let i = 0; i < 200; i++) {
            const r = 80 + 60 * sin(t * 0.07 + i * 0.13);
            const a = i * 0.31 + t * 0.01;
            const x = r * cos(a);
            const y = r * sin(a);
            const sz = 6 + 4 * cos(t * 0.13 + i * 0.2);
            fill(200 + 50*sin(t + i), 100 + 100*cos(t*0.5), 200);
            noStroke();
            ellipse(x, y, sz, sz);
        }
    }

In numpy form: a single `step()` advances the clock, every frame
rebuilds a vectorised cloud of 200 sin/cos-driven ellipses on a
trail-decaying canvas — the canonical "p5.js sin/cos generative
art" sketch that the live-coding community has run for a decade.
The default sketch is a *hypotrochoid-style spirograph* of 3
nested sin/cos rings whose radii morph over time, exactly the
"circle of circles" pattern that appears in the Coding Train's
"sin/cos" lessons and in P5Live demo reels.
"""

from __future__ import annotations

from typing import ClassVar

import numpy as np


class P5LiveSketch:
    """A p5.js-style sin/cos generative sketch rendered in numpy.

    The default sketch draws a spirograph-like cloud of points
    whose polar coordinates are themselves nested sin/cos chains:

        ring_k(θ_i) = R_k + r_k * sin(t * ω_k + φ_k)
        a(θ_i)     = θ_i * n + t * 0.01
        x = Σ ring_k * cos(a + δ_k)
        y = Σ ring_k * sin(a + δ_k)
        sz = 4 + 4 * sin(t * 0.13 + i * 0.21)
        hue = HSV( (i + t * 30) / N, 0.6, 1.0 )

    The full canvas is redrawn every step on a low-trail background
    so past frames leave a soft ghost — the same trail-accumulation
    look that P5Live / p5.js sketches produce when you `background(0, 5)`
    instead of `background(0)` each frame.
    """

    family: ClassVar[str] = "live_coding_synth"
    sketch: ClassVar[str] = "P5LiveSketch"

Try running it locally

The reference implementation is self-contained Python with numpy. Install the package and run:

python library_external/live_coding_synth/P5LiveSketch/reference.py

Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.

More from live_coding_synth

Sample of Hydra Video Synth (numpy port of Olivia Jack's Hydra)

Hydra Video Synth (numpy port of Olivia Jack's Hydra)

live_coding_synth · HydraVisualSynth

A pure-numpy port of the core Hydra video-synth API: chains of sources (osc, noise, shape, gradient, solid, voronoi) composed with geometry modifiers (rotate, scale, scroll, kaleid, pixelate, repeat) and color/blend modifiers (invert, posterize, thresh, color, brightness, contrast, luma, saturate, hue, add, diff, mult, blend) — including the signature modulate operator a.modulate(b, scale), which uses b's red and green channels to displace a's x and y coordinates (with modulateRotate, modulateScale, modulatePixelate, modulateKaleid variants).

View →
Sample of Strudel 16-Step Pattern Visualiser (4x4 grid of sample-typed shapes)

Strudel 16-Step Pattern Visualiser (4x4 grid of sample-typed shapes)

live_coding_synth · StrudelVisualizer

A pure-numpy port of Strudel's signature 4×4 (16-step) pattern grid.

View →
Sample of TidalCycles Mini-Notation Pattern Visualiser

TidalCycles Mini-Notation Pattern Visualiser

live_coding_synth · TidalCyclesPattern

A pure-numpy port of TidalCycles' rhythm mini-notation, expanded per cycle into a row of (sample, variant) tuples and visualised as a row of pulsing shapes that scroll horizontally.

View →
Sample of Topolectures (Olivia Jack) — 2D cell grid + text snippets + audio-amplitude pulse

Topolectures (Olivia Jack) — 2D cell grid + text snippets + audio-amplitude pulse

live_coding_synth · TopolecturesOliviaJack

A pure-numpy port of Olivia Jack's Topolectures: a 2D grid of cells, each cell holding a 1–2 character text snippet from a topology-mathematics corpus (sheaf, locale, frame, open, closed, cover, limit, point, net, filter, basis, ideal, prime, ring, mod, field, topos, yoneda, etale, sieve, …) and brightness pulsed by a synthetic audio-amplitude signal.

View →

See all live_coding_synth artworks →