You need to enable JavaScript to run this app. 如何用ggrepel或其他方法为ggalluvial冲积图层级设置对齐标签
优惠活动
大模型
产品
解决方案
定价
更多

如何用ggrepel或其他方法为ggalluvial冲积图层级设置对齐标签

R语言ggalluvial冲积图标签外移实现方案

我使用R语言的ggalluvial包生成了若干冲积图。
下方的代码示例输出的效果已经接近我的预期,示例如下:

library("ggalluvial")
par(mar = c(1,1,1,1)*12, cex = 0.6, xpd=NA)

# 生成示例数据
somelongnames <- c("homo sapiens", "homo sapiens", letters[18],
                   "some other long name", letters[seq(4)])

df <- data.frame(x = factor(somelongnames),
                 y = factor(c("this label is long", "Golgi", 
                       letters[13:18])),
                 count = c(2, 10, 4, 5, 5, 1, 9, 3))

ll <- unique(c(as.character(df$x), as.character(df$y)))
grid.col <- rainbow(length(ll))
grid.col <- setNames(grid.col, ll)

# 为冲积图设置配色(ggalluvial层级的配色需要按顺序设置,操作相对复杂)
names(df) <- c("Condition1", "Condition2", "value")
levs1 <- levels(df$Condition1) 
levs2 <- levels(df$Condition2)
res1 <- unique(df$Condition1)
res2 <- unique(df$Condition2)
cond1_cols <- grid.col[levs1[levs1 %in% res1]]
cond2_cols <- grid.col[levs2[levs2 %in% res2]]
columnCols <- c(cond1_cols, cond2_cols)
stratCols <- c(rev(cond1_cols), rev(cond2_cols))

# 绘制冲积图
q <- ggplot(df,
            aes(y = value, axis1 = Condition1, axis2 = Condition2)) +
  geom_alluvium(aes(fill = Condition1), width = 0) +
  scale_fill_manual(values = columnCols) +
  geom_stratum(width = 1/8, fill = paste0(stratCols), color = "white") +
  scale_x_discrete(limits = c("Condition1", "Condition2"), 
                   expand = c(.09, .09)) +
  scale_y_continuous(breaks = NULL) +
  theme_minimal() +
  theme(axis.ticks.y = element_blank(),
        axis.text.y = element_blank(),
        panel.grid.major.y = element_blank(),
        panel.grid.major.x = element_blank()) +
  theme(legend.position = "none") +
  ylab(NULL)

# 添加标签
  q +
    geom_label(stat = "stratum", aes(label = after_stat(stratum)),
               color = stratCols, fontface = "bold", size = 3)     

效果图
我希望将标签移动到层级的左右外侧,避免和图表重叠(标签较长时该问题尤其突出),我看到有案例使用ggrepel包实现该效果。
我参照相关方案,尝试在geom_text_repel的aes参数中使用for循环和ifelse语句,但没能写出正确的代码。请问有人可以提供帮助,或者有更优的解决方案吗?
使用ggrepel的失败代码示例如下:

q + ggrepel::geom_text_repel(
    aes(label = ifelse(Condition1 == as.character(res1)[1],as.character(res1)[1], NA)),
        stat = "stratum", size = 4, 
        direction = "y", nudge_x = -.5
) 

失败效果图
我理想的最终效果是标签全部置于冲积图左右两侧,不会和层级块重叠。


解决方案

你不需要使用循环或者逐条件判断,直接通过after_stat(x)识别当前标签所属的轴,再配合nudge_x的正负值控制左右偏移即可,完整实现代码如下:

library(ggrepel)
# 基于你已生成的绘图对象q直接添加标签
q +
  geom_text_repel(
    aes(
      label = after_stat(stratum),
      # 按所属轴设置x方向偏移:左侧轴向左挪,右侧轴向右挪
      nudge_x = after_stat(ifelse(x == 1, -0.3, 0.3))
    ),
    stat = "stratum",
    size = 3,
    fontface = "bold",
    color = stratCols,
    # 仅y方向调整避免横向偏移
    direction = "y",
    # 不需要引导线可将segment.color设为NA
    segment.color = "gray50",
    segment.size = 0.2,
    # 允许标签超出绘图区域
    xlim = c(NA, NA),
    ylim = c(NA, NA)
  ) +
  # 扩大x轴范围容纳外侧标签
  scale_x_discrete(
    limits = c("Condition1", "Condition2"),
    expand = c(0.3, 0.3)
  )

实现说明

  • 核心逻辑是用after_stat(x)读取stratum统计计算后得到的轴位置,1对应左侧Condition1轴,2对应右侧Condition2轴,自动适配偏移方向
  • 调整scale_x_discrete的expand参数,给左右两侧留出足够空间放置长标签
  • 如果不需要标签和层级块之间的引导线,将segment.color设为NA即可隐藏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 07:30:04