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

如何在ggplot2并排条形图上居中显示顶部数值标签

问题描述

我在R中导入了一张汇总每周猫和狗计数的表格,新增一周数据时会添加对应行。但使用ggplot2绘制并排条形图时,顶部计数标签未居中:第一个标签略偏右,第二个略偏左。我已尝试以下方案:

  • 为position_dodge()设置width参数
  • 增大width值至1.8
    这些方案要么导致条形图消失,要么无法解决问题。请查看下方数据和绘图代码,告诉我需要修改哪部分代码才能让标签精准居中于条形图顶部。

数据框

df <- structure(list(Week = structure(c(1672704000, 1672704000, 1673222400, 1673222400, 1673827200, 1673827200, 1674432000, 1674432000, 1675036800, 1675036800, 1675641600, 1675641600, 1676246400, 1676246400, 1676851200, 1676851200, 1677456000, 1677456000, 1678060800, 1678060800, 1678665600, 1678665600, 1679270400, 1679270400, 1679875200, 1679875200, 1680480000, 1680480000, 1681084800, 1681084800, 1681689600, 1681689600, 1682294400, 1682294400, 1682985600, 1682985600, 1683590400, 1683590400), class = c("POSIXct", "POSIXt"), tzone = "UTC"), Animal = structure(c(1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L), .Label = c("Cat", "Dog"), class = "factor"), count = c(63L, 100L, 56L, 210L, 40L, 200L, 102L, 40L, 60L, 240L, 105L, 130L, 102L, 89L, 162L, 54L, 160L, 50L, 160L, 75L, 160L, 75L, 120L, 80L, 124L, 85L, 136L, 60L, 110L, 60L, 155L, 123L, 197L, 144L, 175L, 110L, 65L, 82L)), class = c("grouped_df", "tbl_df", "tbl", "data.frame"), row.names = c(NA, -38L), groups = structure(list(Week = structure(c(1672704000, 1673222400, 1673827200, 1674432000, 1675036800, 1675641600, 1676246400, 1676851200, 1677456000, 1678060800, 1678665600, 1679270400, 1679875200, 1680480000, 1681084800, 1681689600, 1682294400, 1682985600, 1683590400), class = c("POSIXct", "POSIXt"), tzone = "UTC"), .rows = list(1:2, 3:4, 5:6, 7:8, 9:10, 11:12, 13:14, 15:16, 17:18, 19:20, 21:22, 23:24, 25:26, 27:28, 29:30, 31:32, 33:34, 35:36, 37:38)), row.names = c(NA, -19L), class = c("tbl_df", "tbl", "data.frame"), .drop = TRUE))

原绘图代码

df %>% ggplot(aes(x=Week, y=count, fill= Animal)) + 
  geom_bar(position = "dodge", stat = "identity")+ 
  labs(x = "Date", y = 'Number of animals',title = "Cats and dogs data")+ 
  geom_text(aes(label = count), position = position_dodge(width=0.9), vjust = -0.5, size = 2)+ 
  theme_classic()+ 
  labs(fill=NULL)+ 
  scale_y_continuous(expand = c(0, 0), limits=c(0, max(df$count)*1.1))

解决方案

问题根源在于数据框的分组状态与position_dodge参数未统一,修改如下:

修改步骤

  1. 取消数据分组:原数据框是grouped_df类型,分组信息会干扰ggplot的位置计算,需用ungroup()移除分组。
  2. 统一偏移参数:将geom_bar的position从字符串"dodge"改为显式的position_dodge(width=0.9),与geom_text的偏移参数保持完全一致。

修改后完整代码

df %>% 
  ungroup() %>% 
  ggplot(aes(x=Week, y=count, fill= Animal)) + 
  geom_bar(position = position_dodge(width=0.9), stat = "identity")+ 
  labs(x = "Date", y = 'Number of animals',title = "Cats and dogs data")+ 
  geom_text(aes(label = count), position = position_dodge(width=0.9), vjust = -0.5, size = 2)+ 
  theme_classic()+ 
  labs(fill=NULL)+ 
  scale_y_continuous(expand = c(0, 0), limits=c(0, max(df$count)*1.1))

原理说明

  • 分组数据框会让ggplot优先使用内置分组规则,与fill=Animal的分组逻辑冲突,导致标签位置偏移。
  • position_dodge的width参数必须在条形图和标签中完全匹配,才能保证标签与对应条形图精准对齐。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 03:47:20