surface

The same surface a contour traces, shaded instead: one expression in x AND y, grid-sampled over the visible window and drawn as a continuous wash of the mark's hue — bare where the value is low, full where it is high. The two marks compose: a surface under a contour shades the field and traces its level sets over it, and @let keeps the shared expression written once. As with contour, y is the vertical axis, not a parameter. Not a heatmap, which is a grid of cells you hand the values to rather than a function sampled over the window.

surfaceNode
Only withxyargandpolarplane
The field x·y painted on the blue-to-red temperature ramp, blue in two opposite quadrants and red in the others.The field x·y painted on the blue-to-red temperature ramp, blue in two opposite quadrants and red in the others.

A surface paints a function of the plane. Its expression may use y alongside x, which only a surface and a contour allow. It takes a colour that is a single hue or a ramp — multicolour (the full spectrum) or temperature (blue through white to red) — and exposes derived min and max over the visible window. A contour of the same expression draws its level sets over it.

It is not a heatmap: a surface is sampled from an expression over the whole window, where a heatmap is a grid of cells you hand the values to.

The field sin x · cos y painted on the blue-to-red temperature ramp, with its zero contour in grey.The field sin x · cos y painted on the blue-to-red temperature ramp, with its zero contour in grey.
canvas.graph{
    surface(expression: sin(x) * cos(y); colour: temperature)
    contour(expression: sin(x) * cos(y); at: 0; colour: grey)
}

#Attributes

expressionRequiredImplicitAnimatable
Math expression for the surface's value at (x, y). Free letters beyond x and y are parameters.
Also written: exp, f, func, functionCan be written as shorthand: surface:value
rangeAnimatable
The value window the ramp spans, e.g. [0, 40]; values outside clamp. Absent, the ramp spans the sampled extrema — which re-normalises as a parameter drags; an authored range holds still, exactly as an authored domain does.
invertAnimatable
Flip the ramp, putting deep colour at low values rather than high.
Defaultfalse
colourAnimatable
multicolour (the default) runs the full spectrum, violet low to red high; temperature is the blue → white → red wash — pair it with a symmetric range: to pin white at zero; any ordinary hue shades its own intensity ramp instead. Both ramps are fixed colours, identical in light and dark mode.
blueredorangeyellowtealgreenpinkpurplegreyhex()rgb()multicolourtemperature
Also written: color
Defaultmulticolour
opacityAnimatable
How heavy the wash sits over the plot.
Default0.75
hiddenAnimatable
Declared but not drawn — animatable, so hidden: true !cue.to{false}(at: 2) is its reveal.
Defaultfalse
lock
A reader may not edit it on an editable graph.
Also written: locked
Defaultfalse
layerAnimatable
Paint order among the marks: a higher layer is drawn later, on top; equal or omitted, the marks stack in document order (later on top). Written z: before the argand plane took that letter for its coordinate.

#Derived attributes

Computed while the element renders — read one with #id.name in attribute position or {{#id.name}} in prose, never set.

minDerived
The smallest value the surface takes over the sampled window. Cite it with {{#id.min}}.
maxDerived
The largest value the surface takes over the sampled window.

#Allowed in

#Examples

surface(expression: x*y; range: [-9, 9]; colour: temperature)
surface(expression: x^2 + y^2)
surface(expression: (x - 2)^2 + (y - 3)^2; colour: red; invert: true)
surface(expression: {{sse}}; opacity: 0.5)
contour(expression: {{sse}}; at: 1, 2, 4, 8, 16)

Last updated