coord.polar, just like pie & donut — but here the category sweeps around the circle instead of the value.
With theta: 'x', each category takes a spoke and its value grows outward along the radius. The geom then sets the shape: geom.line() traces a radar, geom.area() fills it, geom.bar() draws a rose.
With theta: 'y', the value sweeps the angle instead, and each category becomes its own concentric track — a radial bar.
They read best for a small, fixed set of categories compared across a few series — a skills profile, a weekly cycle, activity by hour.
Radar
A radar (or spider) chart is ageom.line() under coord.polar({ theta: 'x' }). Map the axis category to x, the value to y, and a series column to color.
Two scale settings carry the chart. A discrete x scale gives each category an evenly-spaced spoke. zero: true on y is effectively required: it anchors the centre of the circle at zero, so the radius stays proportional to the value — without it the domain starts at the data minimum, which lands at the centre and exaggerates the differences arbitrarily. A non-interactive geom.point() layer marks each vertex:
Filled radar
Swap the line forgeom.area({ position: 'identity' }) to fill each series polygon. Keep position: 'identity' so the areas overlap at their true values rather than stacking; the vertex points still sit on top:
alpha: 0.3. With more than two or three series they still obscure each other — reach for the outline radar above, or take the fill down further through the stylesheet:
size: 8, which is heavy for a radar. Give the point layer an id and scope a style entry to it:
Rose / coxcomb
A rose (or coxcomb) chart keepstheta: 'x' but draws bars instead of a line: each category is an angular wedge and the value sets how far the wedge reaches. Map a series to color and pick a position — dodge splits each wedge into side-by-side petals, stack grows the series outward along the radius:
params.width sets a petal’s angular thickness as a fraction of its category band, in (0, 1] and defaulting to 0.7 — drop it to open a gap between wedges, raise it to 1 for a solid ring of petals.
Radial bar
A radial bar (or race-track) chart flips the angle back to the value withtheta: 'y': each category becomes its own concentric ring and the value sweeps around it. An innerRadius opens up the centre so the innermost track isn’t crushed into a point. Stack a series to read each ring as consecutive coloured segments:
params.width is the radial thickness of each track. What gives a racetrack its capsule ends is borderRadius: 'full', which rounds an arc to half its radial span:
Where the first spoke lands
coord.polar takes a startAngle in degrees, defaulting to 0. On a rose it decides which spoke sits at the top; on a racetrack it decides where every arc begins sweeping:
Axes
Unlike pie and donut, these charts keep a real categoricalx mapping, so both axes render by default. Turn the category axis off when the legend already names the spokes:
Related
- Styling — fill opacity, marker size, corner radius and per-layer scoping
- Coordinate systems — the polar plane,
theta,startAngleandinnerRadius - Pie & donut — the
theta: 'y'parts-of-a-whole family - Chart types overview — geoms, positions and the full recipe list

