Nightingale Rose Chart
chartAlso known as: coxcomb chart, polar area chart, rose diagram, Nightingale chart
설명 / Description
나이팅게일 로즈 차트(콕스콤 차트 또는 극좌표 면적 차트라고도 함)는 범주를 중심에서 방사형으로 뻗어나가는 동일 각도의 쐐기로 배열하며, 각 쐐기의 반지름(따라서 면적)은 데이터 값에 비례합니다. 각도가 변하고 반지름이 고정된 파이 차트와 달리, 로즈 차트는 각도를 고정하고 반지름을 변화시킵니다. 그 결과는 막대 차트의 범주형 구조와 방사형 레이아웃의 시각적 임팩트를 결합한 원형 디스플레이입니다.
The Nightingale rose chart -- also called a coxcomb chart or polar area chart -- arranges categories as equal-angle wedges radiating from a center, with the radius (and thus area) of each wedge proportional to the data value. Unlike a pie chart, where the angle varies and the radius is fixed, the rose chart holds the angle constant and varies the radius. The result is a circular display that combines the categorical structure of a bar chart with the visual impact of a radial layout.
이 차트는 플로렌스 나이팅게일(Florence Nightingale)의 이름을 따서 명명되었습니다. 그녀는 1858년 저작 「영국 육군의 건강, 효율성, 병원 행정에 영향을 미치는 문제에 관한 노트」에서 이 형식을 사용해 크림 전쟁 당시 전투 부상이 아니라 예방 가능한 질병이 주된 사망 원인이었음을 입증했습니다. 그녀의 "동방 육군 사망 원인 도표"는 역사상 가장 유명한 통계 그래픽 중 하나이며, 그 설득력은 주요 공중보건 개혁에 기여했습니다.
The chart is named after Florence Nightingale, who used this form in her 1858 publication "Notes on Matters Affecting the Health, Efficiency, and Hospital Administration of the British Army" to demonstrate that preventable diseases, not battle wounds, were the primary cause of death during the Crimean War. Her "Diagram of the Causes of Mortality in the Army in the East" is one of the most celebrated statistical graphics in history, and its persuasive power contributed to major public health reforms.
로즈 차트는 시각적으로 인상적이고 역사적으로 중요하지만, 알려진 지각적 한계를 가지고 있습니다: 면적은 반지름에 대해 이차적으로 증가하므로, 값이 두 배가 되면 쐐기의 면적은 네 배가 됩니다. 이는 큰 값과 작은 값 사이의 차이를 과장합니다. 신중한 스케일링(반지름에 값의 제곱근을 사용)을 통해 면적을 값에 비례하게 만들 수 있지만, 디자이너는 이 선택을 명시적으로 밝혀야 합니다.
While the rose chart is visually striking and historically important, it has a known perceptual limitation: area grows quadratically with radius, so a value twice as large produces a wedge four times the area. This exaggerates differences between large and small values. Careful scaling (using the square root of the value for the radius) can make areas proportional to values, but designers must be explicit about this choice.
언제 사용하나 / When to Use
- 순환적 데이터(월, 시간, 방위)를 제시할 때, 원형 레이아웃이 순환적 성격을 강화합니다
- Presenting cyclical data (months, hours, compass directions) where the circular layout reinforces the cyclical nature
- 편집, 대시보드, 발표 맥락에서 시각적으로 독특한 디스플레이를 만들 때
- Creating visually distinctive displays for editorial, dashboard, or presentation contexts
- 원형 형태가 주제적 공명을 더할 때 범주 간 크기를 비교할 때(예: 풍향, 계절 데이터)
- Comparing magnitudes across categories when the circular form adds thematic resonance (e.g., wind direction, seasonal data)
- 청중이 역사적 참조와 미적 매력을 높이 평가할 때
- When the audience will appreciate the historical reference and aesthetic appeal
이럴 땐 피하세요 / When NOT to Use
- 정확한 값 비교가 목표일 때 -- 막대 차트가 지각적으로 더 정확합니다
- When precise value comparison is the goal -- a bar chart is more perceptually accurate
- 범주가 순환적이지 않아 원형 레이아웃이 아무 의미도 더하지 못할 때 -- 방사형 왜곡은 순전한 비용입니다
- When categories are not cyclical and the circular layout adds no meaning -- the radial distortion is a net cost
- 범주가 많아서(12개 초과) 쐐기가 가늘어져 구분하기 어려울 때
- When there are many categories (>12) and wedges become thin and hard to distinguish
- 청중이 이 차트를 파이 차트로 오인해 부분-전체 관계로 잘못 해석할 수 있을 때
- When the audience may confuse the chart with a pie chart and misinterpret it as part-to-whole
구조 / Anatomy
- 쐐기(꽃잎): 범주별로 하나씩, 동일한 각도의 부채꼴이 중심에서 바깥으로 뻗어나갑니다. 반지름이 값을 인코딩합니다.
- Wedges (petals): Sectors of equal angle, one per category, extending outward from the center. The radius encodes the value.
- 중심점: 모든 쐐기가 뻗어나가는 공통 원점.
- Center point: The common origin from which all wedges radiate.
- 방사 축: 반지름 차원의 스케일을 보여주는 동심원이나 그리드선.
- Radial axis: Concentric circles or gridlines showing the scale of the radius dimension.
- 각도 배정: 범주는 원 둘레에 균등하게 배치되며, 보통 의미 있는 순서를 따릅니다(예: 상단부터 시계 방향으로 1월-12월).
- Angle assignment: Categories are evenly spaced around the circle, typically in a meaningful order (e.g., January-December clockwise from the top).
- 색상 인코딩: 각 쐐기는 범주별로 색이 다르게 칠해져 구분됩니다; 또는 순차형 채우기가 반지름과 중복으로 값을 인코딩할 수도 있습니다.
- Color encoding: Each wedge colored by category to distinguish them; alternatively, a sequential fill encodes the value redundantly with radius.
- 레이블: 각 쐐기의 바깥쪽 가장자리나 원둘레를 따라 배치된 범주 이름.
- Labels: Category names placed at the outer edge of each wedge or along the circumference.
변형 / Variations
- 누적 로즈 차트: 쐐기마다 여러 층을 쌓아 각 각도 구간 내의 하위 범주 구성을 보여줍니다(나이팅게일의 원본에서 세 가지 사망 원인을 쌓았던 방식과 같습니다).
- Stacked rose chart: Multiple layers per wedge, showing sub-category composition within each angular segment (as in Nightingale's original, which stacked three causes of death).
- 정규화 로즈 차트: 모든 쐐기가 동일한 최대 반지름까지 뻗어나가며, 대신 색상 강도나 레이어링이 값을 인코딩합니다.
- Normalized rose chart: All wedges extend to the same maximum radius; color intensity or layering encodes the value instead.
- 바람 장미(윈드 로즈): 풍속과 풍향 분포를 보여주는 기상학적 변형으로, 동심원이 빈도를, 각도 구간이 방위를 나타냅니다.
- Wind rose: A meteorological variant showing wind speed and direction distributions, with concentric rings for frequency and angular segments for compass directions.
- 극좌표 막대 차트: 중심에서 방사형으로 배열된 막대로, 로즈 차트와 유사하지만 쐐기 면적 대신 막대 길이를 사용합니다.
- Polar bar chart: Bars arranged radially from a center, similar to the rose chart but using bar length rather than wedge area.
- 스몰 멀티플 로즈 차트: 여러 로즈 차트를 나란히 비교하여(예: 연도별로 하나씩) 시간에 따른 변화를 보여줍니다.
- Small-multiple rose charts: Multiple rose charts compared side by side (e.g., one per year) to show change over time.
코드 레퍼런스 / Code Reference
// D3 - Nightingale rose chart
import * as d3 from "d3";
const angle = d3.scaleBand()
.domain(data.map(d => d.category))
.range([0, 2 * Math.PI]);
const radius = d3.scaleSqrt()
.domain([0, d3.max(data, d => d.value)])
.range([0, innerRadius]);
const arc = d3.arc()
.innerRadius(0)
.outerRadius(d => radius(d.value))
.startAngle(d => angle(d.category))
.endAngle(d => angle(d.category) + angle.bandwidth())
.padAngle(0.02);
const svg = d3.select("#chart").append("svg")
.attr("viewBox", [-width / 2, -height / 2, width, height]);
svg.selectAll("path").data(data).join("path")
.attr("d", arc)
.attr("fill", d => d3.schemeTableau10[d.index % 10])
.attr("stroke", "white");