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

使用ggplot2绘制正负值条形图时如何正确对齐条形顶部标签

Align geom_text Labels to Outside of Both Left/Right Bars in Flipped ggplot2 Chart

Got it, the issue here is that a fixed hjust value can't handle both the negative (left-facing) and positive (right-facing) bars at once. The fix is to set a dynamic hjust parameter that adjusts based on which bar group each label belongs to (or the sign of the value, which is even more flexible).

Here's the updated code that will align all labels to the outside edge of their respective bars:

library(tidyverse)

# Your dataset
df <- structure(list(Letter = c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S"), X = c(3099, 14201, 18901, 17351, 29498, 28928, 32284, 31536, 25334, 20008, 39242, 35856, 43317, 53765, 44652, 32876, 26142, 18567, 8836), Y = c(9482, 22669, 11159, 9506, 12113, 12805, 10570, 10199, 9190, 9217, 10674, 10894, 11986, 15664, 12793, 10552, 8050, 8609, 7717)), row.names = c(NA, -19L), class = c("tbl_df", "tbl", "data.frame"))

# Updated plot with properly aligned labels
df %>% 
  pivot_longer(-c(Letter)) %>% 
  mutate(value = ifelse(name == 'X', value * -1, value)) %>% 
  ggplot(aes(x = Letter, y = value, fill = name)) +
  geom_bar(stat = 'identity', color = 'black', alpha = 0.7) +
  # Key fix: dynamic hjust based on value sign (or variable name)
  geom_text(
    aes(
      label = format(abs(value), big.mark = '.'),
      hjust = ifelse(value < 0, 1, 0)  # Align left bars' labels to left, right bars' to right
    ),
    size = 3, 
    fontface = 'bold'
  ) +
  scale_x_discrete(limits = rev(unique(df$Letter))) +
  scale_y_continuous(labels = function(x) scales::comma(abs(x)), breaks = scales::pretty_breaks(10)) +
  coord_flip()

How this works:

  • For negative values (your X bars, pointing left after flipping), hjust = 1 aligns the right edge of the label to the bar's tip, pushing the label outside the bar to the left.
  • For positive values (your Y bars, pointing right after flipping), hjust = 0 aligns the left edge of the label to the bar's tip, pushing the label outside the bar to the right.

If you prefer to use the variable name instead of value sign (e.g., if your data logic changes later), you can replace the hjust line with:
hjust = ifelse(name == 'X', 1, 0)

Either approach will give you the clean, aligned labels you're looking for.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 18:52:35