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

如何使用ggsankey单独调整桑基图各节点的标签位置?

解决ggsankey桑基图标签与节点重叠的问题

要实现不同位置节点的标签分别左对齐、居中、右对齐,核心思路是给不同x位置的节点分配独立的对齐方式和偏移量,具体有两种可行方法:

方法一:通过数据映射直接调整标签位置

先给数据框添加对应x位置的对齐参数,再通过ggplot的美学映射实现差异化调整:

library(tidyverse)
library(ggsankey)

df <- mtcars %>%
  make_long(cyl, vs, am, gear, carb) %>%
  # 根据x位置定义对齐方式和偏移量
  mutate(
    hjust_val = case_when(
      x == 1 ~ 1,          # 最左侧节点:标签右对齐(贴在节点左边)
      x %in% c(2,3) ~ 0.5, # 中间节点:标签居中
      x %in% c(4,5) ~ 0    # 最右侧节点:标签左对齐(贴在节点右边)
    ),
    # 调整标签的x偏移量,避免和节点重叠
    label_x = case_when(
      x == 1 ~ x - 0.1,
      x %in% c(2,3) ~ x,
      x %in% c(4,5) ~ x + 0.1
    )
  )

ggplot(df, aes(x = x, next_x = next_x, node = node, next_node = next_node, fill = factor(node), label = node)) +
  geom_sankey(flow.alpha = .6, node.color = "gray30", space = 20) +
  geom_sankey_label(
    aes(x = label_x, hjust = hjust_val), # 映射自定义的x位置和对齐方式
    size = 3, color = "white", fill = "gray40",
    space = 20
  ) +
  scale_hjust_identity() + # 启用自定义的hjust值
  scale_fill_viridis_d() +
  theme_sankey(base_size = 18) +
  labs(x = NULL) +
  theme(legend.position = "none", plot.title = element_text(hjust = .5)) +
  ggtitle("Car features")

方法二:提取节点坐标手动添加标签

如果第一种方法效果不够理想,可以先提取桑基图节点的精确坐标,再用带背景的标签精准放置:

library(tidyverse)
library(ggsankey)

df <- mtcars %>%
  make_long(cyl, vs, am, gear, carb)

# 先绘制基础桑基图
base_plot <- ggplot(df, aes(x = x, next_x = next_x, node = node, next_node = next_node, fill = factor(node))) +
  geom_sankey(flow.alpha = .6, node.color = "gray30", space = 20) +
  scale_fill_viridis_d() +
  theme_sankey(base_size = 18) +
  labs(x = NULL) +
  theme(legend.position = "none", plot.title = element_text(hjust = .5)) +
  ggtitle("Car features")

# 提取节点的坐标数据
node_coords <- layer_data(base_plot, i = 1) %>%
  mutate(
    # 定义标签位置和对齐方式
    label_x = case_when(
      x == 1 ~ xmin - 0.1,  # 左节点标签放在节点左侧
      x %in% c(2,3) ~ x,    # 中间节点标签居中
      x %in% c(4,5) ~ xmax + 0.1 # 右节点标签放在节点右侧
    ),
    label_y = (ymin + ymax)/2, # 标签垂直居中于节点
    hjust_val = case_when(
      x == 1 ~ 1,
      x %in% c(2,3) ~ 0.5,
      x %in% c(4,5) ~ 0
    ),
    node = as.character(node) # 确保标签文本匹配
  )

# 添加自定义标签
base_plot +
  geom_label(
    data = node_coords,
    aes(x = label_x, y = label_y, label = node, hjust = hjust_val),
    size = 3, color = "white", fill = "gray40",
    label.padding = unit(0.2, "lines"), # 调整标签内边距
    label.r = unit(0.1, "lines") # 调整标签圆角
  )

两种方法都能实现你要的布局:左侧节点标签左移、中间居中、右侧右移,彻底解决标签和节点重叠的问题。你可以根据自己的节点数量(比如你提到的三个节点)调整case_when里的x值范围即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 01:06:08