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

如何在分面翻转堆叠条形图中对齐geom_text()文本

堆叠条形图文本对齐问题解决

测试数据

dat1 <- structure(list(A_B = c("A", "B", "A", "B", "A", "B", "A", "B", 
"A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", 
"B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", 
"A", "B", "A", "B", "A", "B"), percentage = c(49.2629769158808, 
50.7370230841193, 64.4899165250794, 35.5100834749206, 59.3111128788481, 
40.6888871211519, 85.3899516501997, 14.6100483498003, 80.5933773112794, 
19.4066226887206, 84.3750256827502, 15.6249743172498, 62.8269574848769, 
37.1730425151231, 69.5582018265724, 30.4417981734276, 56.5840999142665, 
43.4159000857335, 100, 0, 67.4302746354917, 32.5697253645083, 
27.3784794349813, 72.6215205650187, 58.0885854897603, 41.9114145102397, 
100, 0, 89.005829015544, 10.994170984456, 57.1694599627561, 42.8305400372439, 
100, 0, 54.2251244585246, 45.7748755414754, 74.4838466287125, 
25.5161533712875, 74.6413724456935, 25.3586275543065), facet = c("Facet 1", 
"Facet 1", "Facet 1", "Facet 1", "Facet 1", "Facet 1", "Facet 1", 
"Facet 1", "Facet 1", "Facet 1", "Facet 2", "Facet 2", "Facet 2", 
"Facet 2", "Facet 2", "Facet 2", "Facet 2", "Facet 2", "Facet 2", 
"Facet 2", "Facet 2", "Facet 2", "Facet 1", "Facet 1", "Facet 2", 
"Facet 2", "Facet 2", "Facet 2", "Facet 1", "Facet 1", "Facet 1", 
"Facet 1", "Facet 2", "Facet 2", "Facet 1", "Facet 1", "Facet 1", 
"Facet 1", "Facet 1", "Facet 1"), id = c(1L, 1L, 2L, 2L, 3L, 
3L, 4L, 4L, 5L, 5L, 6L, 6L, 7L, 7L, 8L, 8L, 9L, 9L, 10L, 10L, 
11L, 11L, 12L, 12L, 13L, 13L, 14L, 14L, 15L, 15L, 16L, 16L, 17L, 
17L, 18L, 18L, 19L, 19L, 20L, 20L)), row.names = c(NA, -40L), class = c("tbl_df", 
"tbl", "data.frame"))

原始绘图代码

library(ggplot2)

ggplot(dat1, aes(id, percentage, fill = factor(A_B))) + 
  geom_col(position = position_fill()) +
  scale_fill_manual(values = c("coral", "lightblue"),
                    breaks=c('A', 'B'))+
  coord_flip() +
  facet_wrap(. ~ facet, scale= "free")+ 
  geom_text(data = subset(dat1, percentage != 0), aes(label = sprintf("%.1f%%", percentage), group = A_B), position = position_fill(vjust=0.5), size = 5) 

问题描述

当前生成的图表中,尝试调整position_fill()里的vjust参数,让A和B对应的百分比文本在同一垂直线上对齐,但遇到问题:设置vjust=1时最接近预期,但文本会超出图表边界;设置其他vjust值则会导致百分比数字排列错位。

解决方案

问题根源在于position_fill()会根据每个堆叠块的位置自动调整文本位置,导致A、B的文本无法对齐在同一线。我们可以放弃用position_fill()定位文本,改为手动固定文本的位置:

方案1:文本在条形右侧对齐(不遮挡条形)

将文本固定在条形右侧的同一垂直线上,避免遮挡条形内容,也不会超出边界:

library(ggplot2)

ggplot(dat1, aes(id, percentage, fill = factor(A_B))) + 
  geom_col(position = position_fill()) +
  scale_fill_manual(values = c("coral", "lightblue"),
                    breaks=c('A', 'B'))+
  coord_flip() +
  facet_wrap(. ~ facet, scale= "free")+ 
  geom_text(data = subset(dat1, percentage != 0), 
            aes(label = sprintf("%.1f%%", percentage), 
                x = 1.05), # 固定文本在条形外侧右侧
            hjust = 0, # 文本左对齐,紧贴条形
            size = 5)

方案2:文本在条形内部中间对齐

如果希望文本在条形内部的同一垂直线上(比如中间位置),可以把x设置为0.5:

library(ggplot2)

ggplot(dat1, aes(id, percentage, fill = factor(A_B))) + 
  geom_col(position = position_fill()) +
  scale_fill_manual(values = c("coral", "lightblue"),
                    breaks=c('A', 'B'))+
  coord_flip() +
  facet_wrap(. ~ facet, scale= "free")+ 
  geom_text(data = subset(dat1, percentage != 0), 
            aes(label = sprintf("%.1f%%", percentage), 
                x = 0.5), # 固定文本在条形中间位置
            hjust = 0.5, # 文本居中对齐
            size = 5)

这两种方案都能让A和B的百分比文本完美对齐在同一垂直线上,不会出现错位或超出边界的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 05:42:02