Skip to main content
Radial charts bend the plane into a circle with 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 a geom.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 for geom.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:
Area fills draw at 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:
The vertex dots draw at the built-in 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 keeps theta: '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 positiondodge 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 with theta: '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:
Here 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:
On a stacked ring only the outer corners of the whole arc round, so the segments inside it stay flush. A border in the background color separates them instead:

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 categorical x mapping, so both axes render by default. Turn the category axis off when the legend already names the spokes: