桑基图(Sankey Diagram) 是一种用于可视化数据流的图表类型,常用于展示数据、能量、物料、资金或其他资源在系统中不同部分之间的流动和分配情况。桑基图通过宽度可变的流线(即流动线)来表示流动的大小,流线越宽,表示的流动量越大。它非常适合展示复杂的系统、过程或多个类别之间的关系。
桑基图的主要组成部分
-
节点(Nodes):代表系统中的不同部分或类别,例如部门、阶段或类别等。
-
流线(Flows):连接不同节点的线条,表示资源或数量从一个节点流向另一个节点。流线的宽度反映了流动的大小或数量。
-
层级(Axes):通常桑基图会分成多个层级,用于展示资源在不同节点之间的转移。
桑基图的优点
-
直观展示复杂关系:通过宽度可变的流线,可以非常直观地展示不同部分之间的数量关系和流动情况。
-
易于比较:各个流线的宽度能清晰地展示不同路径的相对大小,方便比较和分析。
制作桑基图的工具
-
R语言:ggplot2、ggalluvial、ggsankey、networkD3等包都支持绘制桑基图。
-
Python:可以使用Plotly、matplotlib、Holoviews等库。
-
在线工具:如Excel、Google Data Studio、Tableau等可视化工具也支持桑基图的制作。
所以笔者不认为一定要执着于R,这种图的绘制可以怎么快速怎么来~
步骤流程
1、导入数据
rm(list = ls())
library(ggplot2)
library(tidyverse)
load("./data.Rdata")
2、数据展示
df1 <- data
head(df1)
# gender lymph_neck_dissection alcohol
# TCGA-CR-7374-01A FEMALE NO YES
# TCGA-CV-A45V-01A FEMALE NO NO
# TCGA-CV-7102-01A FEMALE YES YES
# TCGA-MT-A67D-01A MALE YES YES
# TCGA-P3-A6T4-01A MALE YES YES
# TCGA-CV-7255-01A FEMALE NO YES
3、三组桑基图
colnames(df1)
conver_res <- to_lodes_form(df1,
axes = 1:ncol(df1),
key = "x",
value = "stratum",
id = "alluvium")
color <- c("#9079ad","#7ebea5","#d8a373","#f09199",
"#8d6449","#4c6cb3","#fef263","#ce5242")
pdf(file="sankey_with.pdf", width=8, height=6)
ggplot(conver_res,
aes(x = x, stratum = stratum, alluvium = alluvium,
fill = stratum, label = stratum)) +
scale_fill_manual(values = color) +
geom_flow(width = 0.4, aes.flow = "forward") +
geom_stratum(alpha = 0.8, width = 0.4) +
# 调整节点标签的位置
geom_text(data = subset(conver_res, x != "status"),
stat = "stratum", size = 5, color = "black", family = "serif",
vjust = -1.5, hjust = 0.5) + # 调整 vjust 和 hjust 使标签与条带对齐
geom_text(data = subset(conver_res, x == "status"),
stat = "stratum", size = 5, color = "black", family = "serif",
vjust = -1.5, hjust = 0.5) + # 适当调整位置
# 调整百分比的位置,避免与标签重叠
geom_text(aes(label = sprintf("%.1f%%", after_stat(prop) * 100)),
stat = "stratum", size = 4.5, vjust = 1.5, hjust = 0.5, color = "black",
family = "serif", check_overlap = TRUE) +
theme_classic() +
theme(axis.line = element_blank(), axis.ticks = element_blank(),
axis.text.y = element_blank()) +
theme(panel.grid = element_blank()) +
theme(panel.border = element_blank()) +
theme(axis.text.x = element_text(size = 15, family = "serif", colour = "black")) +
xlab("") +
ylab("") +
ggtitle("") +
guides(fill = "none")
dev.off()
标签调整很关键! 百分比需要手动调整,其实蛮麻烦的。
调整标签的垂直对齐 (vjust) 和水平对齐 (hjust):
通过修改 vjust 可以控制标签和百分比的上下移动。
通过修改 hjust 可以控制标签和百分比的左右移动。
注:若对内容有疑惑或者有发现明确错误的朋友,请联系后台(欢迎交流)。更多内容可关注公众号:生信方舟
- END -