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

ggsankey桑基图标签与节点位置不匹配问题及参数调整咨询

桑基图节点标签错位问题修复与解析

问题1:标签与节点不匹配的修复方法及原因

原因

你手动用apply循环处理数据后,每条原始样本的非NA节点都会生成单独一行数据,导致同一个节点(比如Group1)对应多行重复记录。geom_sankey会自动聚合相同节点的流量,合并成一个可视化节点;但geom_sankey_text直接使用原始的重复数据绘制标签,就会出现一个节点上叠加多个标签、位置完全错位的情况。简单说:节点是聚合后的结果,标签却是拆分前的重复数据,二者的计算逻辑不统一。

修复方法

推荐使用ggsankey自带的make_long()函数处理数据,它会自动跳过NA并完成节点聚合,确保标签与节点一一对应:

library(ggsankey)
library(ggplot2)
library(dplyr)

set.seed(42)
size<-20
df<-data.frame(id=1:size,
               Inclusion=sample(c("Group1", "Group2", "Group3"), size, replace=T),
               t1=sample(c("Drug1","Drug2", NA), size, replace=T, prob = c(0.3,0.5, 0.2)),
               t2=sample(c("otherTherapy1", "otherTherapy2", NA), size, replace=T, prob = c(0.2,0.3, 0.5)), 
               outcome=sample(c("Dead","Or", "Alive"), size, replace=T, prob = c(0.3,0.38,0.32)))

# 用make_long自动处理NA并生成聚合后的节点关系数据
df_long <- df %>% 
  make_long(Inclusion, t1, t2, outcome, na.rm = TRUE)

ggplot(df_long, aes(x = x,
                    next_x = next_x,
                    node = node,
                    next_node = next_node,
                    fill = node,
                    label = node)) +
  geom_sankey(flow.alpha = 0.5,
              node.color = NA,
              show.legend = TRUE) +
  geom_sankey_text(size = 3, color = "black", fill = NA, hjust = 0, 
                   position = position_nudge(x = 0.1))+
  theme(legend.position = "none")

如果坚持用自己的循环处理逻辑,需要手动对数据按x和node分组去重,保留每个节点的唯一记录来绘制标签:

processed_df <- do.call(rbind, apply(df, 1, function(x) {
  x <- na.omit(x[-1])
  data.frame(x = names(x), node = x, 
             next_x = dplyr::lead(names(x)), 
             next_node = dplyr::lead(x), row.names = NULL)
})) %>%  
  mutate(x = factor(x, names(df)[-1]),
         next_x = factor(next_x, names(df)[-1]))

# 拆分绘图数据:聚合后的节点数据用于geom_sankey,去重后的标签数据用于geom_sankey_text
sankey_data <- processed_df
label_data <- processed_df %>% distinct(x, node, .keep_all = TRUE)

ggplot(sankey_data, aes(x = x,
                        next_x = next_x,
                        node = node,
                        next_node = next_node,
                        fill = node)) +
  geom_sankey(flow.alpha = 0.5,
              node.color = NA,
              show.legend = TRUE) +
  geom_sankey_text(data = label_data, aes(label = node),
                   size = 3, color = "black", fill = NA, hjust = 0, 
                   position = position_nudge(x = 0.1))+
  theme(legend.position = "none")

问题2:检查/修改geom_sankey_text的x&y位置

检查位置数据

可以通过ggplot_build()提取ggsankey计算后的位置参数,查看节点和标签的实际坐标:

# 先绘制基础图
p <- ggplot(df_long, aes(x = x,
                         next_x = next_x,
                         node = node,
                         next_node = next_node,
                         fill = node,
                         label = node)) +
  geom_sankey() +
  geom_sankey_text()

# 提取图层计算后的数据
build_result <- ggplot_build(p)

# 查看geom_sankey的节点位置数据(x、y、xmin/xmax、ymin/ymax等)
print(build_result$data[[1]])

# 查看geom_sankey_text的标签位置数据
print(build_result$data[[2]])

修改位置的方法

  1. 微调位置:用position_nudge(x = ..., y = ...)直接偏移标签,这是最常用的快速调整方式。
  2. 调整节点布局参数:通过geom_sankey()的node.width(节点宽度)、node.padding(节点间垂直间距)参数改变节点位置,间接影响标签的对应位置。
  3. 手动赋值坐标:如果需要精准控制,可以先提取聚合后的节点位置数据,手动计算标签的x/y值,再传递给geom_sankey_text()的aes参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 10:39:55