Scales & aesthetics
An aesthetic maps a data column to a visual channel. A scale turns the
mapped values into pixels or colors. Both are inferred automatically; you only
reach for .scale(channel, options) when you want to override the default.
Aesthetic channels
Section titled “Aesthetic channels”Every channel value is an Aes<T, V> — a column-name string, an accessor
(row, index) => value, or a constant. The available channels (the Channel
union) are:
| Channel | Role | Typical value type |
|---|---|---|
x, y | position | number, Date, or string (band) |
color | fill / stroke color | any (categorical) or number (continuous) |
size | mark radius | number |
alpha | mark opacity | number |
shape | point glyph | categorical → shape palette |
borderStyle | point border treatment | categorical → solid | open | dashed | dotted |
overlayGlyph | secondary point glyph | categorical → glyph palette |
Which channels a geom honors is geom-specific — see Geoms.
Position scales (x, y)
Section titled “Position scales (x, y)”.scale("x", options) / .scale("y", options). The type (and the whole
options shape) follows the data:
type | For | domain |
|---|---|---|
"linear" (default for numbers) | numeric | [number, number] or "nice" |
"log" | positive numeric | [number, number] |
"sqrt" | numeric | [number, number] |
"time" (default for dates) | Date | [Date, Date] |
"band" (default for strings) | categorical | readonly string[] |
Common options: range ([number, number] pixel range), nice (pad numeric
domains to round values — domain: "nice" is sugar for the same), and padding
(band inner padding).
plot<Row>({ data }) .layer(point({ x: "income", y: "lifeExp" })) .scale("x", { type: "log" }) .scale("y", { domain: "nice" });When domain is omitted it’s inferred from the data. With pan/zoom enabled the
x/y position-scale domain is overridden each frame from the viewport — don’t
re-thread it through .scale() yourself.
Color scale
Section titled “Color scale”.scale("color", options). Two families:
- Categorical —
{ type: "categorical", domain?, palette? }. Each distinct value gets a palette color. - Continuous / diverging —
{ type: "continuous" | "diverging", domain?, palette?, nice?, blendSpace? }. Numeric values interpolate the palette;domain: "quantile"(withquantiles?: number, default 5) buckets the data into ordinal quantile bins.
import { plot, point } from "insomni-plot";import { viridis } from "insomni-plot/core";
plot<Row>({ data }) .layer(point({ x: "lon", y: "lat", color: "elevation" })) .scale("color", { type: "continuous", palette: viridis });The continuous color bar legend renders automatically; categorical scales render swatches.
Size, alpha
Section titled “Size, alpha”.scale("size", { type?: "linear" | "sqrt", domain?, range? })— maps a numeric column to mark radius.rangeis[minRadius, maxRadius]..scale("alpha", { domain?, range? })— maps a numeric column to opacity.
Categorical visual scales
Section titled “Categorical visual scales”These map categorical values to non-color visual properties, each with a default palette you can override:
.scale("shape", { domain?, palette? })—PointShapeKind[](defaultPOINT_SHAPE_PALETTE)..scale("borderStyle", { domain?, palette? })—PointBorderStyle[](defaultDEFAULT_BORDER_STYLE_PALETTE)..scale("overlayGlyph", { domain?, palette? })— secondary glyphs (defaultDEFAULT_OVERLAY_GLYPH_PALETTE);nullpalette entries suppress an overlay.
Palettes
Section titled “Palettes”Individual named palettes live in insomni-plot/core, not the grammar barrel.
Categorical: category10, tableau10, set1, set2, set3, dark2,
paired, pastel, accent. Continuous / diverging: viridis, magma,
inferno, plasma, cividis, blues, greens, reds, oranges,
purples, greys, coolwarm, spectral, rdbu, brbg, piyg, prgn,
puor. The grammar barrel (insomni-plot) exposes only the palettes
combinator object and distinguishable.
The palettes object and distinguishable(...) combinator provide categorical
encodings tuned for visual separation. For a hand-wired color scale, see
colorScale in the core API.
Legends
Section titled “Legends”A legend is auto-generated from the active categorical / continuous scales.
Configure it with .legend(spec) or disable it with .legend(false):
plot<Row>({ data }) .layer(point({ x: "x", y: "y", color: "group", shape: "group" })) .legend({ position: "right", title: "Group", merge: ["color", "shape"] });| Option | Type | Notes |
|---|---|---|
show | boolean | Disable the auto-legend. |
position | "top" | "right" | "bottom" | "left" | { inside: { x, y } } | Outer slot or over-plot placement (x/y in 0..1). |
title | string | |
merge | ("color" | "shape" | "size" | "borderStyle" | "overlayGlyph")[] | Combine channels that encode the same field into one legend. |
For continuous (color-bar) legends, length, thickness, ticks,
tickValues, minorTicks, labelStep, format, and blendSpace tune the
gradient bar.
- Axes & coordinates — turning scales into drawn axes.
- Geoms — which channels each geom reads.