Skip to content

ComplexPlot ​

<ComplexPlot value="PolyLog(2, z)"> -- domain-coloring of a complex-valued expression over the complex plane, one GPU invocation per pixel: color is the argument on a gradient (default phase, the hue wheel; any cyclic one such as sinebow has no seam at the negative real axis; reverse turns it round), brightness a compressed log-magnitude, poles white and zeros black.

Any expression the complex emitter can lower works, so this replaces a hand-written shader per function. Under <Manipulate> every constant becomes an axis:

``html <Manipulate params="{s, 0.5, 6, 0.05}"> <ComplexPlot value="PolyLog(_s, z)" mask="1" /> </Manipulate> ``

A slider moves a literal, not the expression's shape, so the compiled pipeline is reused and the frame costs one small uniform upload -- which is what lets Manipulate interpolate between slider steps and still hold frame.

mask dims everything outside that radius, for a series whose disk of convergence is part of the story (the polylog's |z| < 1). Drag to pan; ⌘/Ctrl + scroll to zoom.

Framing is manipulable too: extent="_e" takes a wildcard directly, and center accepts the Epsil list form [_c, 0] as well as a bare re,im.

packages/components/src/notatio-complex-plot.ts· draws ComplexPlot

Stories

A rational function

The three cube roots of unity are the black zeros; the poles at ±i are the points every hue spirals into. Reading the colour wheel around a point gives its order, and the direction of the winding says zero or pole.

source
ComplexPlot((z ^ 3 - 1) / (z ^ 2 + 1), (Extent, 4), (Height, 380))

notebook cells, the CLI

An essential singularity

Every hue, infinitely often, in any neighbourhood of the origin -- Picard's theorem as a picture.

source
ComplexPlot(Exp(1 / z), (Extent, 1.2), (Height, 380))

notebook cells, the CLI

The Riemann zeta function

The pole at z = 1, the trivial zeros marching left along the real axis, and the critical strip's zeros stacked up the imaginary axis.

source
ComplexPlot(Zeta(z), (Extent, 40), (Height, 380))

notebook cells, the CLI

A disk of convergence

Mask dims everything outside that radius -- for a series whose disk of convergence is part of the story. The polylogarithm's Lerch series reaches |z| < 1 only, so the lit disk is exactly its domain.

source
ComplexPlot(PolyLog(2, z), (Mask, 1), (Height, 380))

notebook cells, the CLI

The polylogarithm's order

Sweep the order and watch the disk go from the wound-up spirals of a small real part to the near-linear ramp where the first term dominates.

source
Manipulate(
            ComplexPlot(PolyLog(s, z), (Mask, 1), (Height, 380)),
            (s, 0.25, 6, 0.05),
            (Fps, True),
          )

notebook cells, the CLI

Two axes at once

Framing is manipulable too -- Center takes the list form [c, 0], and Extent a bare wildcard. The polygamma's poles sit at 0, −1, −2, …, of order m+1 -- raise the order and the hue winds more times around each.

source
Manipulate(ComplexPlot(
                        PolyGamma(m, z),
                        (Center, [c, 0]),
                        (Extent, 6),
                        (Height, 380),
                      ), (m, 1, 12, 1), (c, -4, 1, 0.1))

notebook cells, the CLI

The sinebow gradient instead of the phase wheel

Color is the argument on a gradient -- phase (the hue wheel) by default. sinebow is cyclic too, so it has no seam where the argument wraps at the negative real axis.

source
ComplexPlot((z - 1) / (z ^ 2 + z + 1), z, (ColorFunction, "Sinebow"))

notebook cells, the CLI

Props

PropTypeDefaultNotes
valuestring""The complex-valued expression to color, in Epsil.
varstring"z"The complex variable; defaults to z.
centerstring"0,0"Centre of the view in the complex plane, as re,im. Dragging pans it.
extentnumber2.4Half-width of the view. Scrolling zooms it.
masknumber0Dim everything outside this radius; 0 masks nothing.
gradientstring"phase"The gradient the argument is colored with: phase (the hue wheel), sinebow, turbo, viridis, ….
reversebooleanfalseRun the gradient from its last color to its first.
heightnumber460Canvas height in pixels.
fpsbooleanfalseShow a frame-rate readout.

As a web component

Plain custom elements, no framework required: import @enumeratio/frontend for the side effect and write <notatio-complex-plot> in any HTML. Attributes are kebab-case and always strings; the props table above names each one's attribute where it differs from its prop.

Settable only as a JS property, not an attribute -- bindings: bind with :bindings.prop="…" directly on the tag.