Nightingale Rose

Nightingale Rose Chart

Categoría Composición

Qué es

También llamado Polar Area Chart, se popularizó a mediados del siglo XIX en un análisis de mortalidad hospitalaria. Sectores iguales en ángulo pero con radio proporcional al valor.

Para qué sirve

Para mostrar datos cíclicos (meses del año, horas del día) o cuando se necesita un impacto visual más memorable que las barras estándar.

Cómo leerlo

Anatomía

Este formato surgió en el siglo XIX como parte de un esfuerzo por documentar visualmente las causas de mortalidad en un ejército, con el objetivo explícito de forzar una reforma sanitaria ante una audiencia con poder de decisión pero sin formación estadística. La carpeta completa de diagramas recibió en su momento un nombre informal que terminó aplicándose también a cada gráfico individual. La diferencia estructural con un pie chart —la que le da su nombre técnico, "diagrama de área polar"— es que acá el ángulo de cada gajo es siempre el mismo, dividiendo el círculo en partes iguales (en el ejemplo original, doce, uno por mes), y es el radio —y por lo tanto el área— el que varía según el valor, midiendo la magnitud "área por área" desde el centro. Dentro de cada gajo, los colores se apilaban desde el centro: en el diagrama original, para separar muertes por enfermedad prevenible, por heridas de combate y por otras causas, la evidencia visual que se usó para demostrar que la insalubridad, no el combate, mataba a la mayoría de los soldados.

Una esfera cortada en gajos de distinto tamaño y color: variación de radio y ángulo a la vez, la misma doble codificación que usa un nightingale rose para exagerar diferencias entre categorías

Por qué funciona

Fundamento perceptivo

El formato circular comunica ciclicidad de forma natural. Históricamente fue el primer uso efectivo de la visualización de datos para influir en políticas públicas de salud.

Errores comunes

  • El área exagera las diferencias

    varía con el cuadrado del radio, así que los valores grandes parecen mucho mayores de lo que son en comparación directa; etiqueta siempre los valores.

Dónde se usa

Contextos de aplicación

Actividad por hora del día en formato circular
01

Actividad por hora del día en formato circular

Los pétalos crecen con la actividad; el reloj completo en una rosa.

Distribución de eventos por mes
02

Distribución de eventos por mes

Doce sectores fijos con radio variable: el patrón estacional salta a la vista.

Temperaturas medias mensuales
03

Temperaturas medias mensuales

El año en círculo, con el radio de cada mes según su valor.

Cómo construirlo

El mismo gráfico, en 11 librerías open source

Cada librería resuelve las mismas decisiones de diseño, como la escala, el espaciado entre barras o la inserción de la etiqueta de valor, de un modo distinto. Algunas las automatizan; otras las dejan explícitas en el código, a criterio de quien lo escribe. Comparar once implementaciones con los mismos datos y el mismo color de marca aísla esa diferencia, que de otro modo queda oculta detrás de estilos visuales distintos.

Matplotlib License (estilo BSD)
Matplotlib: gráfico de barras

bar() en un Axes polar acepta "bottom" igual que en coordenadas cartesianas —apilar radialmente es la misma técnica de un stacked bar común, solo que el Axes es polar.

import matplotlib.pyplot as plt
import numpy as np

dirs = ["N", "NE", "E", "SE", "S", "SW", "W", "NW"]
series = [
    {"name": "Suave (<10 kt)", "color": "#F5EFE4", "data": [511, 668, 520, 114, 614, 1678, 864, 281]},
    {"name": "Moderado (10-20 kt)", "color": "#D2601F", "data": [6, 5, 87, 1, 37, 571, 527, 4]},
    {"name": "Fuerte (>20 kt)", "color": "#490827", "data": [0, 0, 1, 0, 0, 2, 13, 0]},
]
n = len(dirs)

# bar() en un Axes polar acepta "bottom" igual que en coordenadas
# cartesianas -- apilar radialmente es la misma tecnica de un stacked
# bar comun, solo que el Axes es polar.
fig = plt.figure(figsize=(5.6, 5.6))
ax = fig.add_subplot(111, polar=True)
angulos = [2 * np.pi * i / n for i in range(n)]
bottom = np.zeros(n)
for s in series:
    ax.bar(angulos, s["data"], width=2 * np.pi / n * 0.95, bottom=bottom, color=s["color"], align="edge")
    bottom += np.array(s["data"])
ax.set_xticks(angulos); ax.set_xticklabels(dirs)
plt.show()

No disponible en estas librerías

Chart.js

Su tipo polarArea representa un valor por cuña —no admite apilar varias series dentro de la misma cuña, el requisito básico de una rosa de vientos con bandas de velocidad.

ApexCharts

Su tipo polarArea tiene la misma limitación que Chart.js: una serie por gráfico, sin soporte para apilar múltiples series dentro de cada cuña.

Observable Plot

No tiene un sistema de coordenadas polares ni una marca radial —la misma limitación que descarta la torta y el gauge deja sin base cualquier gráfico polar, apilado o no.

Plotnine

Esta versión no implementa coord_polar() —la misma ausencia que descarta la torta, el donut y el gauge también descarta la rosa de vientos.

Herramientas para construirlo

No-code, desktop y plataformas web, con su licencia visible, abierta o comercial.

No-code
Observable FreemiumFlourish Freemium
JavaScript
D3.js Open SourceECharts Open SourceHighcharts Comercial
Python
Plotly Open Source
R
ggplot2 Open Source

Con datos reales

Ejemplos de uso.