Fractals

Mandelbrot Set

Iterate z² + c — keep points where the sequence stays bounded — get an infinitely complex fractal

The Mandelbrot set is the set of complex numbers c for which the iteration z₀ = 0, zₙ₊₁ = zₙ² + c stays bounded forever. Plotted in the complex plane, it forms a famously beautiful fractal — a black blob with infinite filigree, miniature copies of itself everywhere, and a boundary of infinite detail. Discovered by Mandelbrot in 1980 (with computer plots), it became an icon of chaos theory, complex dynamics, and the surprising beauty hidden in simple equations.

  • Definitionc ∈ M if iteration z → z² + c starting at 0 stays bounded
  • Equivalent — bounded|zₙ| stays ≤ 2 forever (escape radius)
  • DiscoveredBenoit Mandelbrot, 1980 (computer-plotted)
  • ConnectedThe Mandelbrot set is connected (Douady-Hubbard 1982)
  • Boundary dimensionHausdorff dimension 2 (Shishikura 1991)
  • Self-similarityContains infinitely many "mini-Mandelbrots" — quasi-self-similar

Interactive visualization

Press play, or step through manually. The visualization is yours to drive — try it before reading on.

Open visualization fullscreen ↗

Watch the 60-second explainer

A condensed visual walkthrough — narrated, captioned, under a minute.

The set

For each complex number c, consider the iteration:

z₀ = 0
z₁ = z₀² + c = c
z₂ = z₁² + c = c² + c
z₃ = z₂² + c
...
zₙ₊₁ = zₙ² + c

The Mandelbrot set M is the set of all c for which this sequence stays bounded — |zₙ| doesn't escape to infinity.

Plotted in the complex plane (real part horizontal, imaginary vertical), the Mandelbrot set forms a black region with an instantly recognizable shape — a heart-shaped main body (the cardioid), a smaller circular bulb to its left, and infinite filigree along the boundary.

The escape radius — 2

Theorem — if |zₙ| > 2 for any n, then the sequence escapes (|zₙ| → ∞).

Proof sketch — if |z| > 2 and |c| ≤ |z|, then |z² + c| ≥ |z|² − |c| ≥ |z|² − |z| = |z|(|z| − 1) > |z|. So once |z| exceeds 2, each subsequent z is larger.

This gives the practical escape-time algorithm — iterate; if |z| ever exceeds 2, c is outside M. If after many iterations |z| stays ≤ 2, c is (probably) in M.

Escape-time visualization

StepWhat happens
1For each pixel, compute c (complex coordinate).
2Initialize z = 0.
3Iterate z → z² + c, up to N times.
4Stop early if |z|² > 4 (i.e., |z| > 2). Note iteration count n.
5If never exceeded — color pixel black (in M).
6If exceeded at step n — color pixel based on n (often a gradient).

Higher N reveals finer detail — boundary appears more intricate. Inner detail (within M) doesn't change much; the action is at the boundary.

Self-similarity and mini-Mandelbrots

Zoom into the boundary anywhere — and you find smaller copies of the entire Mandelbrot set, slightly distorted. Zoom into one of those mini-Mandelbrots — find still smaller copies. This goes on forever; the set is quasi-self-similar.

This is different from strict self-similarity (like the Koch snowflake), where exact copies appear at smaller scales. The Mandelbrot set's copies are slightly warped — but unmistakably the same shape.

The exact, infinite-fold self-similar replication is part of why the set captivates — beauty arising from a 2-line iteration formula.

Cardioid and bulbs — periodicity structure

The main body of the Mandelbrot set has structure:

  • The main cardioid (heart shape) — the set of c where z → z² + c has an attracting fixed point (period 1).
  • The big period-2 bulb on the left — attracting period-2 cycles. (Centered at c = −1.)
  • Smaller period-3, period-4, period-5, ... bulbs branch off the main cardioid.
  • The bulbs are arranged following the Farey sequence — between bulb periods p and q, the next prominent bulb has period p+q (mediant).

This connects the Mandelbrot set to deep number-theoretic structures — Farey fractions, continued fractions, hyperbolic geometry.

Julia sets — the dual picture

For each fixed c, the filled Julia set K_c is the set of starting points z₀ for which the iteration z → z² + c stays bounded. The Julia set J_c is the boundary of K_c.

Key duality:

  • If c ∈ M (Mandelbrot), J_c is connected — a single piece.
  • If c ∉ M, J_c is a Cantor set ("Cantor dust") — totally disconnected, infinitely many pieces.

So the Mandelbrot set is exactly the parameter space where Julia sets are connected. Discovered by Adrien Douady and John Hubbard (1982).

JavaScript — Mandelbrot set rendering

// Compute escape time for one point
function mandelbrotEscape(cReal, cImag, maxIter = 256) {
  let zReal = 0, zImag = 0;
  for (let n = 0; n < maxIter; n++) {
    const zRealSq = zReal * zReal;
    const zImagSq = zImag * zImag;
    if (zRealSq + zImagSq > 4) return n;  // escaped
    const newReal = zRealSq - zImagSq + cReal;
    const newImag = 2 * zReal * zImag + cImag;
    zReal = newReal;
    zImag = newImag;
  }
  return maxIter;  // didn't escape — likely in M
}

// Render at 800x600
function renderMandelbrot(width, height, xMin, xMax, yMin, yMax, maxIter) {
  const result = new Uint8Array(width * height);
  for (let py = 0; py < height; py++) {
    const cImag = yMin + (py / height) * (yMax - yMin);
    for (let px = 0; px < width; px++) {
      const cReal = xMin + (px / width) * (xMax - xMin);
      const escape = mandelbrotEscape(cReal, cImag, maxIter);
      result[py * width + px] = Math.min(escape, 255);
    }
  }
  return result;
}

// Standard view: real ∈ [-2.5, 1], imag ∈ [-1.25, 1.25]
const pixels = renderMandelbrot(800, 600, -2.5, 1, -1.25, 1.25, 256);
console.log(`First pixel escape time: ${pixels[0]}`);

// Smooth coloring — fractional iteration count for continuous gradient
function smoothEscape(cReal, cImag, maxIter = 256) {
  let zReal = 0, zImag = 0;
  for (let n = 0; n < maxIter; n++) {
    const zRealSq = zReal * zReal;
    const zImagSq = zImag * zImag;
    const mag = zRealSq + zImagSq;
    if (mag > 256) {  // larger escape radius for smoother colors
      const log_zn = Math.log(mag) / 2;
      const nu = Math.log(log_zn / Math.log(2)) / Math.log(2);
      return n + 1 - nu;
    }
    const newReal = zRealSq - zImagSq + cReal;
    const newImag = 2 * zReal * zImag + cImag;
    zReal = newReal;
    zImag = newImag;
  }
  return maxIter;
}

// Test point: c = -0.75 + 0.1i — slowly escaping
console.log(smoothEscape(-0.75, 0.1));  // larger fractional value

Where the Mandelbrot set shows up

  • Complex dynamics — pure mathematics. Foundation of complex dynamical systems theory. Provides examples of chaos, bifurcations, periodic orbits, and renormalization.
  • Fractal geometry. Iconic example of fractals — non-integer dimension, self-similarity, infinite detail. Influenced Mandelbrot's broader theory of fractals (1975 book).
  • Computer graphics and visualization. Beautiful imagery; common in art, screensavers, demoscene. Real-time rendering benchmarks.
  • Education. Demonstrates how simple rules generate immense complexity. Used to introduce complex numbers, iteration, escape-time algorithms, and fractals.
  • Image analysis. Fractal-based compression algorithms (early 1990s) compress images by storing fractal "rules" rather than pixels — though largely superseded by JPEG/wavelet methods.
  • Chaos theory. Shows how chaotic systems can have organized structure (the Mandelbrot set is highly organized, despite arising from "chaotic" iteration).
  • Number theory. Connections to Farey sequences, continued fractions, hyperbolic geometry. Modern research relates Mandelbrot to Riemann hypothesis, p-adic analysis.

Common mistakes

  • Iterating with the wrong starting point. Always start z₀ = 0, not z₀ = c. The "0 starts" is what defines Mandelbrot vs Julia.
  • Using too small a max iteration count. Coarse images show "thick" boundaries; you need 256+ (or 1000+) iterations to see fine detail. Each tenfold zoom typically requires ~10× more iterations to render correctly.
  • Confusing Mandelbrot set with Julia set. Mandelbrot — vary c, fix z₀ = 0. Julia — fix c, vary starting z. Different sets, related by deep duality.
  • Believing Mandelbrot is "totally" self-similar. It's quasi-self-similar — copies are slightly distorted, not exact. Strict self-similarity (Koch snowflake) and quasi-self-similarity (Mandelbrot) are different.
  • Missing the escape radius optimization. Once |z|² > 4 (i.e., |z| > 2), bail out — guaranteed to escape. Skipping this wastes massive compute.
  • Believing the boundary is "1-dimensional." Hausdorff dimension is 2 — boundary is so dense it fills space like an area, despite being a curve. Surprising but proven.

Frequently asked questions

How is the Mandelbrot set defined exactly?

For each complex number c, define the sequence z₀ = 0, z₁ = z₀² + c = c, z₂ = z₁² + c = c² + c, z₃ = z₂² + c, etc. The Mandelbrot set M is the set of all c for which this sequence stays bounded — |zₙ| doesn't go to infinity. Equivalently, the set of c such that |zₙ| ≤ 2 for all n (a theorem — once |z| &gt; 2, escape is guaranteed).

How is it visualized — what's the escape-time algorithm?

For each pixel representing complex number c, run the iteration up to N steps (say N = 256). Track how quickly |zₙ| exceeds 2 (escapes). Color pixel based on n at escape — the "escape time." Pixels never escaping (after N iterations) are colored black; these are the points "in" the set. Higher N gives finer detail near the boundary; computational cost grows linearly with N.

What's the connection to Julia sets?

Julia set J_c (for fixed c) is the boundary between points whose iteration under z → z² + c stays bounded vs escapes — same iteration, but varying z (not c). Mandelbrot set is the "parameter space" — the set of c for which the corresponding Julia set is connected. Beautiful duality — for c outside Mandelbrot, J_c is "Cantor dust" (totally disconnected); for c inside, J_c is connected.

Are there miniature copies of the Mandelbrot set inside itself?

Yes — infinitely many. The Mandelbrot set is "quasi-self-similar" — zoom in anywhere on the boundary and you find smaller copies of the entire set, slightly distorted. These mini-Mandelbrots can themselves be zoomed into, revealing more mini-Mandelbrots. This goes forever — at every scale, more detail.

What is the dimension of the boundary?

The boundary's Hausdorff dimension is 2 — proven by Mitsuhiro Shishikura in 1991. This is striking — even though the boundary is a "1-dimensional curve" in some sense (the boundary of a 2D region), its detail is so dense it has the dimension of a 2D area. Says — the boundary fills space "almost like an area" despite being a curve.

How is the Mandelbrot set computed efficiently?

Escape-time algorithm with optimizations — early bail-out (once |z|² &gt; 4, escape), period checking (detect cycles for points inside), distance estimation (smooth coloring via dz/dc derivative), perturbation methods for deep zooms (precision arithmetic + perturbation around a high-precision orbit). Modern interactive zooms use perturbation theory to render zooms 10⁻¹⁰⁰⁰ deep.

What's the cardioid and the bulbs?

The main heart-shaped region (cardioid) is the set of c for which z² + c has an attracting fixed point. Equation — c = e^(iθ)/2 − e^(2iθ)/4. The big circular bulb on the left of the cardioid corresponds to attracting period-2 orbits. Smaller bulbs around the cardioid correspond to attracting periods 3, 4, 5, ... — and the periods follow a beautiful pattern (Farey sequence rationals).