背景
在数据分析领域,桑基图是一种重要的可视化工具,常用于展示数据的流动和转移情况,特别适用于多阶段、多路径的复杂系统,它通过宽度不等的流线,直观地展示了从一个节点到另一个节点的数据量变化,这种图表广泛应用于能源流动、资金流向、物流链分析等多个领域,在医学研究中也有显著的应用价值
在医学领域,尤其是在如脓毒症这样复杂的疾病管理中,桑基图可以帮助研究人员和临床医生可视化病人的病程轨迹,展示从病情变化到出院或死亡的动态流动,通过此图,医学研究者能够明确地看出哪些病人在治疗过程中康复,哪些病人持续恶化,甚至哪些病人在短时间内不幸离世,通过这种方式,桑基图为数据分析提供了极具洞察力的表现形式
接下来,将展示如何通过Python代码绘制出与文章类似的脓毒症病人预后路径的桑基图
代码实现
数据集定义
import plotly.graph_objects as go
# 数据集定义,包含从Sepsis到最终Alive/Death的转移路径
data = [
# 从 Day 1 到 Day 3
('Sepsis', 'Recovery', 5835),
('Sepsis', 'Persistent ill', 2937),
('Sepsis', 'Rapid death', 363),
# 从 Day 3 到出院情况
('Recovery', 'Alive', 5497),
('Persistent ill', 'Alive', 2137),
('Recovery', 'Death', 338),
('Persistent ill', 'Death', 800),
('Rapid death', 'Death', 363)
]
这里定义脓毒症患者的病程数据,表示每个阶段的患者数量,数据结构为三元组:
- 源(Source):表示患者的当前状态(如 Sepsis、Recovery 等)
- 目标(Target):表示患者在后续阶段的状态(如 Recovery、Alive 等)
- 值(Value):表示该状态之间的患者数量
例如,第一个数据 ('Sepsis', 'Recovery', 5835) 表示5835名脓毒症患者在入院后进入了康复状态,其它桑基图绘制也如此定义,用于描述从一个阶段或节点到另一个阶段的数量变化和转移
准备桑基图的源、目标、值
# 准备Sankey图所需的源、目标、值
sources = []
targets = []
values = []
labels = []
这里初始化了四个列表,分别用于存储:
- sources:数据流动的源节点索引(即从哪个状态开始)
- targets:数据流动的目标节点索引(即流向哪个状态)
- values:流动的数值,即每个源和目标之间的患者数量
- labels:节点的标签,存储病程的不同状态
填充 sources、targets 和 values 列表
for i in data:
source_label = i[0]
target_label = i[1]
# 如果label还没在labels中,添加它
if source_label not in labels:
labels.append(source_label)
if target_label not in labels:
labels.append(target_label)
# 获取对应的索引
source_idx = labels.index(source_label)
target_idx = labels.index(target_label)
# 添加源、目标和值
sources.append(source_idx)
targets.append(target_idx)
values.append(i[2])
遍历数据集,将每个源状态和目标状态的标签添加到 labels 列表中(如果尚未存在),并获取它们的索引,将这些索引对应的源、目标、以及它们之间的值分别存储在 sources、targets 和 values 列表中,用于后续生成桑基图
设置节点、流动线的颜色和透明度
# 节点颜色
node_colors = [
'#87CEEB', # Sepsis 天蓝色
'#F5B895', # Recovery 淡橙色
'#90EE90', # Persistent ill 非常淡的绿色
'#F2B3B3', # Rapid death 非常柔和的浅粉色
'#D3D3D3', # Recovery to Alive/Death 非常经典的淡灰色,柔和且中性
'#D8BFD8', # Persistent ill to Alive/Death 淡紫色,带有柔和的紫色调
]
# 线条颜色,并设置透明度
colors = [
'rgba(163, 193, 218, 0.6)', # Sepsis to Recovery (淡蓝色, 60% 透明度)
'rgba(163, 193, 218, 0.6)', # Sepsis to Persistent ill (淡蓝色, 60% 透明度)
'rgba(163, 193, 218, 0.6)', # Sepsis to Rapid death (淡蓝色, 60% 透明度)
'rgba(248, 212, 157, 0.6)', # Recovery to Alive (淡橙色, 60% 透明度)
'rgba(171, 221, 164, 0.6)', # Persistent ill to Alive (淡绿色, 60% 透明度)
'rgba(248, 212, 157, 0.6)', # Recovery to Death (淡橙色, 60% 透明度)
'rgba(171, 221, 164, 0.6)', # Persistent ill to Death (淡绿色, 60% 透明度)
'rgba(244, 168, 168, 0.6)' # Rapid death to Death (淡粉色, 60% 透明度)
]
为不同状态的节点(例如 Sepsis、Recovery 等)设置颜色,为不同节点间的连接线设置颜色和透明度
桑基图绘制
# 创建桑基图
fig = go.Figure(go.Sankey(
node = dict(
pad = 15,
thickness = 20,
line = dict(color = "rgba(0, 0, 0, 0)", width = 0),
label = [],
color = node_colors # 设置节点颜色
),
link = dict(
source = sources, # 源
target = targets, # 目标
value = values, # 值
color = colors # 设置流动颜色和透明度
)))
# 更新布局和显示图表
fig.update_layout(title_text="Sepsis Recovery Flow", font_size=10)
# 保存为html文件
file_path = "sankey_sepsis_recovery_flow.html"
fig.write_html(file_path)
# 显示图表
fig.show()
最后创建一个桑基图并保存为 HTML 文件,关闭了所有 label 的显示,原因是这个可视化实际上是一个交互式图表,关闭 label 是为了方便后续使用其他图像处理软件添加标签显示(P图等),相比直接在代码中调整更为简便,因此这里只生成了基础的图形,下面为添加标签后的最终结果
到这里,就成功复现了文章中的桑基图,通过这种方法,能够清晰地展示脓毒症患者从入院到出院之间的不同状态转移过程,虽然市面上有很多在线的桑基图绘制工具,允许用户快速生成图表,但通过编写代码来进行绘制能够提供更大的灵活性,使得能够自定义颜色、线条、透明度等图表细节,并且最后生成的结果更加美观且具有高可操作性,这种方法尤其适用于复杂的科研图表绘制或需要对图表进行精细调整的场景
往期推荐
基于SHAP值的 BorutaShap 算法在特征选择中的应用与优化
复现SCI文章 SHAP 依赖图可视化以增强机器学习模型的可解释性
微信号|deep_ML
欢迎添加作者微信进入Python、ChatGPT群
进群请备注Python或AI进入相关群
无需科学上网、同步官网所有功能、使用无限制
如果你对类似于这样的文章感兴趣。
欢迎关注、点赞、转发~
个人观点,仅供参考