Skip to content
Sample of Stochastic Recursive Fractal Tree

shiffman_pearson_textbook · recursiveTree

Stochastic Recursive Fractal Tree

Stack-based stochastic fractal tree from Shiffman's Nature of Code Ch. 8. Each generation spawns n_branches child branches, each rotated by a random angle drawn from a uniform distribution centered on branch_angle_deg with spread angle_jitter_deg (or a Gaussian when jitter_mode='normal'). Child length = parent_length * length_decay; thickness also decays. Recursion stops when length < 0.5 or levels > N. The deterministic version (jitter=0) reproduces Example 8.6; the stochastic version with leaf_size > 0 adds a red dot at each terminal branch tip, giving a flowering-tree look.

Original: https://natureofcode.com/fractals/

▶ 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
shiffman_pearson_textbook
Source
shiffman · pearson
Evolution
recursive_fractal
Render
stroked_lines_with_thickness
Complexity
medium
Agents
1
Year
2012
Author
Daniel Shiffman (Nature of Code Ch. 8, Example 8.7 'A Stochastic Tree', 2012); also in Pearson Generative Art

Math essence

Iterative stack-based recursion (avoids Python recursion limit). For each branch at heading h and length L: x2 = x + L*cos(h), y2 = y + L*sin(h). Children: n = randint(n_min, n_max+1), angle = +/- jitter_angle drawn from uniform[a-j, a+j] or normal(a, j). Branch stamped to canvas with a disk brush of thickness that decays geometrically per level. Leaves stamped when leaf_size>0 at terminal branches.

Parameters

Name Type Default Range Description
dim int 600 200–1400
root_length float 130 20–400 Trunk length (pixels).
length_decay float 0.72 0.4–0.95 Per-level length multiplier.
branch_angle_deg float 25 5–90 Mean branch angle from parent.
angle_jitter_deg float 15 0–60 Per-branch angle jitter.
jitter_mode str uniform —
n_branches_min int 2 1–5
n_branches_max int 3 1–6 Each parent spawns a random integer in [min, max] children.
levels int 8 3–12
trunk_thickness float 4 1–14
thickness_decay float 0.72 0.4–0.95
leaf_size float 0 0–12 0 = no leaves; otherwise radius in pixels.
bg_color tuple 245,240,230 —
ink_color tuple 50,35,25 —
leaf_color tuple 180,70,60 —
seed int null 0–999999

Reference

First 60 lines of reference.py. Full source: library_external/shiffman_pearson_textbook/recursiveTree/reference.py

from __future__ import annotations

from typing import ClassVar

import numpy as np


class RecursiveTree:
    """Stochastic recursive fractal tree — Nature of Code Ch. 8, Example 8.7.

    Builds a branching fractal tree from a stack-based recursion. The root
    trunk grows upward; at each generation it produces ``n_branches`` child
    branches, each rotated by an angle drawn from a normal distribution
    centered at ``branch_angle_deg`` with spread ``angle_jitter_deg`` (or a
    uniform distribution in ``[-angle_jitter_deg, +angle_jitter_deg]`` when
    ``jitter_mode='uniform'`` — the textbook default). Each child's length
    is the parent's length multiplied by ``length_decay``. Recursion stops
    when the branch length drops below ``min_length`` (8 levels by default).

    This is the textbook stochastic fractal tree from Shiffman's Example 8.7
    'A Stochastic Tree', and is also covered in Pearson's *Generative Art*
    as a Python/Processing canonical motif.

    ``step(n)`` does not strictly evolve — the tree is grown once and the
    canvas is reused — but each call advances the random seed and re-grows
    the tree, producing a new stochastic tree image so the corpus has
    variation across step indices.
    """

    family: ClassVar[str] = "shiffman_pearson_textbook"
    sketch: ClassVar[str] = "recursiveTree"

    def __init__(
        self,
        dim: int = 600,
        root_length: float = 130.0,
        length_decay: float = 0.72,
        branch_angle_deg: float = 25.0,
        angle_jitter_deg: float = 15.0,
        jitter_mode: str = "uniform",
        n_branches_min: int = 2,
        n_branches_max: int = 3,
        levels: int = 8,
        trunk_thickness: float = 4.0,
        thickness_decay: float = 0.72,
        bg_color: tuple[int, int, int] = (245, 240, 230),
        ink_color: tuple[int, int, int] = (50, 35, 25),
        leaf_color: tuple[int, int, int] | None = None,
        leaf_size: float = 0.0,
        seed: int | None = None,
    ) -> None:
        self.dim = dim
        self.root_length = root_length
        self.length_decay = length_decay
        self.branch_angle_deg = branch_angle_deg
        self.angle_jitter_deg = angle_jitter_deg
        self.jitter_mode = jitter_mode
        self.n_branches_min = n_branches_min
        self.n_branches_max = n_branches_max
        self.levels = levels

Try running it locally

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

python library_external/shiffman_pearson_textbook/recursiveTree/reference.py

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

More from shiffman · pearson

Sample of Genetic Algorithm (Evolve Toward Target String)

Genetic Algorithm (Evolve Toward Target String)

shiffman_pearson_textbook · geneticAlgorithmString

A textbook genetic algorithm that evolves a population of binary strings toward a target ASCII string (default 'HELLO WORLD!').

View →
Sample of Lindenmayer L-System (Textbook Formulation)

Lindenmayer L-System (Textbook Formulation)

shiffman_pearson_textbook · lindenmayerTextbook

Lindenmayer L-system string rewriting with a 2-D turtle interpreter, the canonical textbook formulation used in both Shiffman's Nature of Code Ch.

View →
Sample of Mandelbrot Set (Escape-Time Fractal)

Mandelbrot Set (Escape-Time Fractal)

shiffman_pearson_textbook · mandelbrotSet

The Mandelbrot set rendered by escape-time iteration of z = z^2 + c on a window of the complex plane.

View →
Sample of Perlin Noise Flow Field

Perlin Noise Flow Field

shiffman_pearson_textbook · perlinFlowField

A 2-D scalar field of Perlin gradient noise is sampled on a coarse grid; each cell is assigned a heading theta = 2*pi * n.

View →
Sample of Random Walk / Drunkard's Walk

Random Walk / Drunkard's Walk

shiffman_pearson_textbook · randomWalkDrunkard

Many random walkers each start at the canvas center and take a stochastic 2-D step every tick.

View →
Sample of Reynolds Boids (Separation / Alignment / Cohesion)

Reynolds Boids (Separation / Alignment / Cohesion)

shiffman_pearson_textbook · boidsClassic

Reynolds' classic boids flocking model.

View →

See all shiffman_pearson_textbook artworks →