Skip to contents

A Nightingale rose (also called a coxcomb or polar area chart) divides a circle into equal-angle wedges, one per category, and encodes each value by how far its wedge extends from the center. The form is credited to Florence Nightingale, who used it in 1858 to show that far more British soldiers in the Crimean War died of preventable disease than of wounds.

Radii follow a square-root scale so that the area of each wedge, not its length, is proportional to the value, keeping the visual honest. When a group column is supplied, each wedge is split into stacked segments whose areas are again proportional to their values. Dashed radial grid circles carry value labels, and category labels sit outside the wedges. The look is inspired by the polar-interval "rose" chart of the AntV G2 library, reimplemented in plain D3.

The chart is interactive: wedges grow out from the center on first render, hovering a wedge pops it outward and shows a tooltip (with a per-group breakdown when stacked), and, when stacked, hovering a legend entry focuses that group while clicking it toggles the group on or off.

Usage

rose_chart(
  data,
  category,
  value,
  group = NULL,
  colors = NULL,
  sort = c("none", "desc", "asc"),
  innerRadius = 0,
  startAngle = 0,
  padAngle = 0,
  cornerRadius = 0,
  opacity = 0.9,
  strokeCol = "white",
  strokeWidth = 1,
  gridLines = 4,
  gridCol = "#e0e0e0",
  gridFontSize = 10,
  showLabels = TRUE,
  labelFontSize = 11,
  valueFormat = ",.0f",
  hover = TRUE,
  animate = TRUE,
  legend = TRUE,
  legendFontSize = 11,
  title = NULL,
  titleFontSize = 16,
  font = "Verdana, Geneva, Tahoma, sans-serif",
  bgcol = "white",
  axisCol = "black",
  width = NULL,
  height = NULL
)

Arguments

data

The data frame containing the variables to consider. Rows that share the same category (and group) are summed.

category

The name of the column holding the categories (one wedge per category). If it is a factor, its levels set the order of the wedges; otherwise they appear in the order found in the data.

value

The name of the numeric column holding the (non-negative) values.

group

Optional. The name of a categorical column used to split each wedge into stacked segments. If it is a factor, its levels set the stacking order (first level innermost). Defaults to NULL.

colors

Optional. A vector of colors, one per group when group is supplied, otherwise one per category (recycled if needed). A single color paints every wedge alike. Defaults to NULL, which uses an AntV-style ten-color palette.

sort

How to order the wedges: "none" (data or factor order, the default), "desc" or "asc" by category total.

innerRadius

Size of an empty hole in the middle, as a fraction of the outer radius (between 0 and 0.9). Defaults to 0.

startAngle

Angle, in degrees clockwise from 12 o'clock, at which the first wedge starts. Defaults to 0.

padAngle

Gap between adjacent wedges, in radians. Defaults to 0.

cornerRadius

Corner rounding of the wedges, in pixels. Defaults to 0.

opacity

Fill opacity of the wedges (0 to 1). Defaults to 0.9.

strokeCol

Color of the wedge outlines. Defaults to "white".

strokeWidth

Width of the wedge outlines in pixels. Defaults to 1.

gridLines

Approximate number of radial grid circles (value rings). Use 0 to hide them. Defaults to 4.

gridCol

Color of the grid circles and spokes. Defaults to "#e0e0e0".

gridFontSize

Font size of the grid value labels. Defaults to 10.

showLabels

Whether to display the category labels around the chart. Defaults to TRUE.

labelFontSize

Font size of the category labels. Defaults to 11.

valueFormat

A d3-format specifier used to display values in the tooltip (e.g. ",.0f", ".1f", "$,.2s"). Defaults to ",.0f".

hover

Whether hovering a wedge pops it outward and shows a tooltip. Defaults to TRUE.

animate

Whether wedges grow out from the center on first render. Defaults to TRUE.

legend

Whether to display a legend of the groups (only used when group is supplied). Defaults to TRUE.

legendFontSize

Font size of the legend text. Defaults to 11.

title

Optional. Title of the chart.

titleFontSize

Font size of the chart title. Defaults to 16.

font

The font family used for all text. Defaults to "Verdana, Geneva, Tahoma, sans-serif".

bgcol

Background color of the SVG. Defaults to "white".

axisCol

Color of the title, labels and grid value labels. Defaults to "black".

width

Optional. The width of the SVG output.

height

Optional. The height of the SVG output.

Value

An SVG Nightingale rose chart.

Examples

# Florence Nightingale's data: deaths in the British army in the East,
# April 1854 to March 1855, by cause (as in the HistData package)
mon <- c("Apr 1854", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov",
            "Dec", "Jan 1855", "Feb", "Mar")
crimea <- data.frame(
  month = factor(rep(mon, times = 3), levels = mon),
  cause = factor(rep(c("Preventable disease", "Wounds", "Other causes"),
                     each = 12),
                 levels = c("Preventable disease", "Wounds", "Other causes")),
  deaths = c(1, 12, 11, 359, 828, 788, 503, 844, 1725, 2761, 2120, 1205,
             0, 0, 0, 0, 1, 81, 132, 287, 114, 83, 42, 32,
             5, 9, 6, 23, 30, 70, 128, 106, 131, 324, 361, 172)
)

rose_chart(
  data     = crimea,
  category = "month",
  value    = "deaths",
  group    = "cause",
  colors   = c("#7fa7c9", "#e0645c", "#4d4d4d"),
  title    = "Causes of death in the army in the East, 1854-55",
  height   = 560
)
# A simple rose: one wedge per category, sorted by value rose_chart( data = data.frame(state = rownames(USArrests)[1:12], murder = USArrests$Murder[1:12]), category = "state", value = "murder", sort = "desc", valueFormat = ".1f", title = "Murder arrests per 100,000 residents (1973)" )
# Donut-style rose with a hole, gaps and rounded corners rose_chart( data = as.data.frame(table(cyl = mtcars$cyl, gear = mtcars$gear)), category = "gear", value = "Freq", group = "cyl", innerRadius = 0.25, padAngle = 0.03, cornerRadius = 4, title = "Cars by number of gears and cylinders" )