You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Alluvial/Sankey图中设置Y轴为百分比刻度?

解决ggplot2冲积图Y轴百分比刻度问题

我来帮你搞定这个Y轴百分比设置的问题~

问题根源

你遇到的核心问题是:冲积图的Y轴原始数值是类别频数(比如某个分组有14个样本,Y轴就显示14),直接用scales::percent()会把这个频数当成比例值(比如14变成1400%),完全不符合你的需求。我们需要把频数转换成「占该时间点总样本数的百分比」,同时保证刻度正好是0%、10%…100%。

解决方案

你的数据里每个time组都有20个样本(time=1和time=2各20行),所以我们可以基于这个总样本数来转换Y轴的显示标签:

  1. 先定义每个时间点的总样本数:n <- 20
  2. 在scale_y_continuous里做两个关键设置:
    • breaks:设置为频数对应的10%间隔点(0、2、4…20,分别对应0%、10%…100%)
    • labels:用自定义函数把频数转换成百分比(比如2→10%,20→100%)

完整可运行代码

library(ggplot2)
library(ggalluvial) # 必须加载这个包才能用geom_flow/geom_stratum
library(scales)

# 你的数据集
PIPPO <- data.frame(
  "ID"=rep(c(1:20),2), 
  "time"=c(rep(1,20),rep(2,20)), 
  "value"=c("B","G","B","G","B",rep("G",3),rep("B",2),"G",rep("B",3),"G",rep("B",6),"G","B","G","B",rep("G",3),rep("B",2),"G",rep("B",3),"G","B","switch",rep("B",2),"switch")
)

n <- 20 # 每个time组的总样本数

ggplot(PIPPO, aes(x = time, stratum = value, alluvium = ID, fill = value, label = value)) +
  scale_fill_brewer(type = "qual", palette = "Set3") +
  geom_flow(stat = "flow", knot.pos = 1/4, aes.flow = "forward", color = "gray") +
  geom_stratum() +
  theme(legend.position = "bottom") +
  scale_y_continuous(
    breaks = seq(0, n, by = n*0.1), # 对应10%间隔的频数位置
    labels = function(x) percent(x/n), # 将频数转为百分比标签
    limits = c(0, n) # 锁定Y轴范围为0到总样本数,对应0%到100%
  )

为什么这个方法有效

这样设置后,Y轴的底层计算还是用原始频数(保证冲积图的高度、流向完全正确),但显示给你的是百分比标签,而且刻度严格按照每10%的间隔排列,完美匹配你的需求。

如果你的数据中不同time组的样本数不一样,可以先用dplyr分组计算每个time的总样本数,再动态映射到Y轴设置里——不过你的当前数据是固定20个样本,所以直接用n=20就足够啦。

内容的提问来源于stack exchange,提问作者jeff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 17:52:29