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

如何在堆叠柱状图中放置无重叠标签?避免geom_text_repel误移动标签

解决堆叠柱状图标签无重叠且不移动正常标签的方案

核心思路是拆分标签组分别处理:对空间充足的标签直接居中放置,对空间狭小易重叠的标签用geom_text_repel仅调整这类标签的位置,避免影响其他正常标签。

步骤1:预处理数据,计算堆叠位置并分组

在原有数据处理基础上,先计算每个标签的堆叠中心位置,再根据产品的空间占比划分成"无需调整"和"需要调整"两组:

sales_labeled <- sales %>%
  group_by(year, product) %>%
  summarise(sales = sum(sales)) %>%
  mutate(
    pct_of_year_sales = sales / sum(sales),
    label = paste(
      scales::label_dollar(scale=1/1E6, suffix="M", accuracy=0.1)(sales),
      scales::label_percent(accuracy=0.1)(pct_of_year_sales),
      sep=", "
    ),
    # 计算堆叠中心的y坐标
    y_pos = cumsum(sales) - sales/2,
    # 定义分组:C、D占比小易重叠,需要调整;其余无需调整
    adjust_group = ifelse(product %in% c("C", "D"), "adjust", "no_adjust")
  ) %>%
  ungroup()

步骤2:绘制图表,分两组添加标签

用geom_text放置无需调整的标签,用geom_text_repel仅处理需要调整的标签,并设置参数限制移动范围:

ggplot(sales_labeled, aes(x=year, y=sales, fill=product)) + 
  geom_col() +
  # 放置无需调整的标签,居中对齐
  geom_text(
    data = filter(sales_labeled, adjust_group == "no_adjust"),
    aes(y = y_pos, label = label),
    size = 3.5
  ) +
  # 处理需要调整的标签,仅在垂直方向移动,避免干扰其他标签
  geom_text_repel(
    data = filter(sales_labeled, adjust_group == "adjust"),
    aes(y = y_pos, label = label),
    direction = "y",  # 仅允许上下移动
    nudge_x = 0.15,   # 轻微向右偏移,避免挡住柱子
    size = 3.5,
    box.padding = 0.2,
    point.padding = 0.3
  ) +
  scale_y_continuous(
    labels = scales::label_dollar(scale=1/1E6, suffix="M"),
    expand = expansion(mult = c(0, .05))
  ) +
  labs(
    title = "堆叠柱状图无重叠标签",
    subtitle = "仅调整狭小空间的标签,保留正常标签位置"
  )

关键参数说明

  • adjust_group:可根据实际数据灵活划分,比如用pct_of_year_sales < 0.05这类阈值自动识别需要调整的小占比标签
  • direction = "y":限制geom_text_repel仅在垂直方向调整,避免左右移动干扰其他年份的标签
  • nudge_x:给需要调整的标签轻微偏移,避免和柱子主体重叠

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 10:10:31