南丁格尔图(玫瑰图)绘制

  南丁格尔玫瑰图(Nightingale Rose Chart)是数据可视化史上的经典图表之一,由现代护理学奠基人弗洛伦斯·南丁格尔(Florence Nightingale)于1858年首创。南丁格尔玫瑰图作为数据可视化史上的里程碑,不仅改变了19世纪的医疗政策,至今仍启发着数据叙事(Data Storytelling)的艺术。在当今精准分析需求下,其价值更多体现在:如何用数据讲好一个改变决策的故事。现代数据工作者可在保留其视觉冲击力的同时,通过交互设计和多维补充信息,赋予这一经典形式新的生命力。

下面是用python绘制南丁格尔图

# -*- coding: utf-8 -*-
"""
南丁格尔玫瑰图可视化案例
使用Matplotlib实现极坐标系下的堆叠玫瑰图
"""

# 导入必要库
import matplotlib.pyplot as plt  # 可视化库
import numpy as np  # 数值计算库
import pandas as pd  # 数据处理库

# ================== 中文字体配置 ==================
# 设置中文字体显示(根据操作系统选择)
plt.rcParams['font.sans-serif'] = ['SimHei']  # Windows系统中文显示
# plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']  # Mac系统中文显示
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示为方块的问题

# ================== 数据准备 ==================
# 创建模拟数据(仿照克里米亚战争医疗数据格式)
months = ['2023-04', '2023-05', '2023-06', '2023-07', '2023-08', '2023-09']  # 月份数据
categories = {
    '战斗负伤': [25, 42, 35, 28, 50, 38],  # 战斗相关伤亡数据
    '疾病感染': [120, 135, 162, 148, 200, 175],  # 疾病导致的伤亡数据
    '其他原因': [15, 22, 18, 25, 30, 28]  # 其他因素导致的伤亡数据
}

# 转换为Pandas DataFrame格式
df = pd.DataFrame(categories, index=months)
df['月份'] = df.index  # 添加月份列

# ================== 极坐标参数设置 ==================
N = len(df)  # 数据点数量(月份数量)
theta = np.linspace(0.0, 2 * np.pi, N, endpoint=False)  # 将圆周分为N等分,生成角度值
width = 2 * np.pi / N  # 计算每个扇形的宽度(弧度)

# ================== 可视化配置 ==================
# 颜色设置(模仿南丁格尔原始配色风格)
colors = ['#FFB3BA', '#BAFFC9', '#BAE1FF']  # 粉红/浅绿/浅蓝配色方案

# 创建画布和极坐标系
fig = plt.figure(figsize=(10, 10))  # 创建10x10英寸的画布
ax = fig.add_subplot(111, polar=True)  # 添加极坐标系子图

# ================== 绘制堆叠玫瑰图 ==================
bottom = np.zeros(N)  # 初始化堆叠条形图的底部位置
for i, (category, color) in enumerate(zip(categories.keys(), colors)):
    # 获取当前分类的数据
    values = df[category].values

    # 绘制极坐标堆叠条形图
    bars = ax.bar(
        x=theta,  # 角度位置
        height=values,  # 条形高度(数据值)
        width=width,  # 条形宽度
        bottom=bottom,  # 堆叠起始高度
        color=color,  # 填充颜色
        edgecolor='white',  # 边框颜色
        linewidth=0.5,  # 边框粗细
        label=category  # 图例标签
    )
    bottom += values  # 更新堆叠基线位置

# ================== 添加月份标签 ==================
for month, angle, value in zip(months, theta, bottom):
    rotation = np.degrees(angle + width / 2)  # 计算标签旋转角度(转换为角度制)
    ax.text(
        angle + width / 2,  # 角度位置(中心对齐)
        bottom.max() * 1.1,  # 半径位置(超出最大半径10%)
        month,  # 显示的月份文本
        ha='center',  # 水平居中
        va='center',  # 垂直居中
        # 自动调整标签旋转方向(保证文字可读)
        rotation=rotation - 90 if rotation < 180 else rotation + 90,
        fontsize=10  # 字体大小
    )

# ================== 极坐标系参数调整 ==================
ax.set_theta_offset(np.pi / 2)  # 设置起始角度(从正上方开始)
ax.set_theta_direction(-1)  # 设置方向为顺时针
ax.set_rlabel_position(0)  # 设置半径标签位置(0度方向)
plt.ylim(0, bottom.max() * 1.2)  # 设置半径轴显示范围(留出20%空白)

# ================== 添加图例和标题 ==================
plt.legend(
    loc='upper right',  # 图例主位置
    bbox_to_anchor=(1.15, 1.15),  # 图例框偏移量(右侧外对齐)
    frameon=False  # 取消图例框
)
plt.title('医疗情况分析 - 南丁格尔玫瑰图\n(模拟克里米亚战争医疗数据)',
          pad=40,  # 标题与图的间距
          fontsize=14)  # 标题字号

# ================== 美化设置 ==================
ax.spines['polar'].set_visible(False)  # 隐藏极坐标的边界线
ax.grid(False)  # 隐藏极坐标网格线

# ================== 显示图表 ==================
plt.tight_layout()  # 自动调整子图参数
plt.show()  # 显示最终图表

结果如下: 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值