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

ggplot中geom_text标签位置异常求助:正确显示2020年despesamonetaria_gr带%

问题描述

拥有数据集despesa_anys_ESP_decilsllar,需要在ggplot分组柱状图中,仅给2020年的柱子添加despesamonetaria_gr数值的百分比标签,但现有代码生成的标签位置错位,无法对应到正确年份的柱子。

数据集结构如下:

structure(list(Any = c("2019", "2019", "2019", "2019", "2019", 
"2019", "2019", "2019", "2019", "2019", "2020", "2020", "2020", 
"2020", "2020", "2020", "2020", "2020", "2020", "2020"), decils_renda = c("1r", 
"2n", "3r", "4t", "5è", "6è", "7è", "8è", "9è", "10è", 
"1r", "2n", "3r", "4t", "5è", "6è", "7è", "8è", "9è", "10è"), despesatotal = c(13866.4, 18324.6, 21495.5, 24455.3, 28460.8, 29818, 33897, 37897.3, 43373.1, 57458.4, 13280.3, 17337.7, 20666.9, 22900.4, 25972.2, 27152.6, 30469.6, 32036.5, 37087.2, 49570.1), despesamonetaria = c(9493.2, 13622.9, 16488.8, 19245.1, 22622.4, 23780.2, 27213.5, 30793.5, 35457.3, 46773.7, 9006.1, 12629.2, 15337.3, 17209.8, 19882.8, 20736.3, 23711.3, 24780.6, 28962.6, 38315.8), proporcio_despesatotal = c(45.9, 60.6, 71.1, 80.9, 94.1, 98.6, 112.1, 125.3, 143.4, 190, 49.2, 64.2, 76.6, 84.8, 96.2, 100.6, 112.9, 118.7, 137.4, 183.6), proporcio_despesamonetaria = c(39.6, 56.8, 68.8, 80.3, 94.4, 99.2, 113.5, 128.4, 147.9, 195.1, 43.9, 61.5, 74.7, 83.9, 96.9, 101, 115.5, 120.8, 141.1, 186.7), despesatotal_gr = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, -4.2, -5.4, -3.9, -6.4, -8.7, -8.9, -10.1, -15.5, -14.5, -13.7), despesamonetaria_gr = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, -5.1, -7.3, -7, -10.6, -12.1, -12.8, -12.9, -19.5, -18.3, -18.1)), row.names = c(NA, -20L), class = c("tbl_df", "tbl", "data.frame"))

原代码如下:

plot_despesa_decils_ESP <- ggplot(despesa_anys_ESP_decilsllar, aes(x = decils_renda, y = despesamonetaria, fill = Any)) +
  geom_bar(position="dodge", stat="identity", width=0.8) +
  scale_y_continuous("", labels=function(x) format(x, big.mark = ".", scientific = FALSE), limits=c(0, 50000), breaks=seq(from=0, to=50000, by=5000),
                     expand = expansion(mult = c(0, 0))) +
  geom_text(aes(label = paste(ifelse(!Any == "2019", despesamonetaria_gr, ""), "%"), family = "serif", size=6.5, hjust = -1.5, vjust = -2),
             show.legend = FALSE)
问题原因
  • geom_text未设置与geom_bar一致的position=dodge,导致标签无法对齐分组柱子
  • 保留了2019年的空标签,冗余的空元素干扰了标签的位置计算
  • 将size、hjust、vjust等非映射类视觉参数放在aes()内部,不符合ggplot规范且可能引发异常
修正后的代码
plot_despesa_decils_ESP <- ggplot(despesa_anys_ESP_decilsllar, aes(x = decils_renda, y = despesamonetaria, fill = Any)) +
  geom_bar(position = position_dodge(width = 0.8), stat = "identity", width = 0.8) +
  scale_y_continuous("", 
                     labels = function(x) format(x, big.mark = ".", scientific = FALSE), 
                     limits = c(0, 50000), 
                     breaks = seq(from = 0, to = 50000, by = 5000),
                     expand = expansion(mult = c(0, 0))) +
  # 仅过滤2020年的数据添加标签,设置与柱子匹配的dodge位置
  geom_text(data = subset(despesa_anys_ESP_decilsllar, Any == "2020"),
            aes(label = paste0(despesamonetaria_gr, "%")),
            position = position_dodge(width = 0.8),
            family = "serif",
            size = 6.5,
            hjust = -0.1,  # 调整水平位置,避免和柱子重叠
            vjust = 0.5,   # 垂直居中于柱子顶部
            show.legend = FALSE)

# 查看图表
plot_despesa_decils_ESP
关键修改说明
  1. 给geom_bar和geom_text统一设置position_dodge(width = 0.8),确保标签与对应年份的柱子严格对齐
  2. 使用subset()提前过滤2020年的数据,避免空标签干扰位置
  3. 将size、hjust、vjust等视觉参数移到aes()外部,符合ggplot语法规范
  4. 调整hjust和vjust的数值,让标签更美观地显示在2020年柱子的右侧(或顶部,可根据需求微调)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 19:15:03