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

R语言堆叠条形图添加文本的三类问题及代码求助

R语言堆叠条形图百分比标注优化方案

问题说明

尝试为ggplot2中的横向堆叠条形图添加百分比文本标注时,遇到以下三个问题:

  • 标注文本未正确居中对齐
  • 部分类别(如WC)各占比相等时需按图例顺序排列,其余场景需按Contribution值降序排序堆叠
  • 0%占比的标注需要隐藏

原始数据与代码

数据

df <- structure(list(QT = c("BMI", "BMI", "BMI", "BMI", "BMI", "WHR", 
"WHR", "WHR", "WHR", "WHR", "BF", "BF", "BF", "BF", "BF", "WC", 
"WC", "WC", "WC", "WC"), E = c("HD", "NS", "PA", "PALC", "SMK", 
"HD", "NS", "PA", "PALC", "SMK", "HD", "NS", "PA", "PALC", "SMK", 
"HD", "NS", "PA", "PALC", "SMK"), Contribution = c(21.73913043, 
0, 21.73913043, 34.7826087, 21.73913043, 24.13793103, 24.13793103, 
20.68965517, 13.79310345, 17.24137931, 16.66666667, 16.66666667, 
20, 20, 26.66666667, 20, 20, 20, 20, 20)), row.names = c(NA, 
20L), class = "data.frame")

原始代码

library(ggplot2)

ggplot(df, aes(x = Contribution, y = QT,  fill = E)) +
  geom_col(size=0.5, color="black", 
           position = position_fill(reverse = TRUE)) +
  scale_fill_brewer(palette = "Set2") +
  theme_minimal()+
  theme(axis.text=element_text(size=12, colour = "black"),
        axis.title = element_text(size=13),
        axis.text.x = element_blank(),
         legend.text = element_text(size=12))+
  geom_text(aes(label = paste0(round(Contribution), "%")),
            position = position_fill(vjust = 0.5))

当前效果

当前效果截图

解决方案

步骤1:数据预处理(实现分组排序)

使用dplyr对数据分组处理,针对不同组设置排序规则:

library(dplyr)

df_sorted <- df %>%
  group_by(QT) %>%
  mutate(
    # 判断组内所有占比是否相等
    all_equal = n_distinct(Contribution) == 1,
    # 定义排序依据:相等则按图例顺序,否则按占比降序
    sort_key = if(all_equal) as.integer(factor(E, levels = c("HD", "NS", "PA", "PALC", "SMK"))) else desc(Contribution)
  ) %>%
  ungroup() %>%
  # 按分组和排序键重新排序
  arrange(QT, sort_key) %>%
  # 将E转换为排序后的因子,确保堆叠顺序正确
  mutate(E = factor(E, levels = unique(E)))

步骤2:优化绘图代码(解决居中和隐藏0%标注)

调整geom_text参数,与geom_col保持一致的堆叠设置,并隐藏0%标注:

library(ggplot2)

ggplot(df_sorted, aes(x = Contribution, y = QT, fill = E)) +
  geom_col(size = 0.5, color = "black",
           position = position_fill(reverse = TRUE)) +
  scale_fill_brewer(palette = "Set2") +
  theme_minimal() +
  theme(
    axis.text = element_text(size = 12, colour = "black"),
    axis.title = element_text(size = 13),
    axis.text.x = element_blank(),
    legend.text = element_text(size = 12)
  ) +
  geom_text(
    # 隐藏0%标注,仅显示非零占比的百分比文本
    aes(label = ifelse(Contribution == 0, "", paste0(round(Contribution), "%"))),
    # 与geom_col使用完全一致的堆叠参数,保证文本居中
    position = position_fill(reverse = TRUE, vjust = 0.5),
    size = 4 # 可根据需求调整文本大小
  )

方案说明

  1. 标注居中:geom_text的position_fill参数与geom_col完全匹配(包含reverse = TRUE),确保文本位置与堆叠块对齐。
  2. 分组排序:通过预处理数据,给每个分组设置差异化排序规则,占比相等的组按图例顺序排列,其他组按占比降序堆叠。
  3. 隐藏0%标注:使用ifelse判断占比,为0时返回空字符串,不显示标注。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 03:45:03