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

geom_grid标签错位修正及highcharter复现同图表可行性问询

问题描述

我绘制的分组堆叠条形图中,期望标签位于条形中心,但当前标签出现错位,请问该如何修正?此外,是否可以使用highcharter复现该图表?

模拟数据:

library(tidyverse)
library(plotly)
df = tibble(category = c('A', 'A', 'B', 'B', 'C', 'C', 'A', 'A', 'B', 'B', 'C', 'C'),
           targeting = c('Automatic', 'Manual','Automatic', 'Manual','Automatic', 'Manual', 'Automatic', 'Manual','Automatic', 'Manual','Automatic', 'Manual'),
           spend_percentage = c(35.3, 64.7, 12.9, 87.1, 73.9, 26.1, 73.3, 26.7, 50.4, 49.6, 35, 65),
           type = c('Unoptimized', 'Unoptimized', 'Unoptimized','Unoptimized', 'Unoptimized', 'Unoptimized','Optimized', 'Optimized', 'Optimized', 'Optimized', 'Optimized', 'Optimized')
)

我尝试的代码:

gg1 = df %>% 
  ggplot(aes(x = spend_percentage, y = category, fill = targeting)) + 
  geom_col() + 
  facet_grid(~type) + 
  ggtitle('Budget Percentage by Targetig Type ') + 
  theme(axis.title.y = element_text(colour="gray20", size=12,
                                    angle=90, hjust=.5, vjust=1),
        axis.title.x = element_text(colour="gray20"),
        plot.title = element_text(hjust=-0.5, size = 14),
        axis.text.x = element_text(size=12, angle=0, hjust=.5, vjust=-1.5)) + 
  xlab('Spend Percentage') + 
  geom_text(aes(x = spend_percentage, label = spend_percentage), 
            hjust = -1)

ggplotly(gg1)
一、修正ggplot标签错位问题

标签错位的核心原因是直接用spend_percentage作为geom_text的x坐标,没有考虑堆叠条形的位置偏移。需要先计算每个堆叠条形的中心位置,再调整对齐方式:

修正步骤与代码

# 计算每个条形的中心x坐标:累积求和后减去自身数值的一半
df_centered = df %>%
  group_by(type, category) %>%
  mutate(cum_spend = cumsum(spend_percentage) - spend_percentage/2) %>%
  ungroup()

gg1 = df_centered %>% 
  ggplot(aes(x = spend_percentage, y = category, fill = targeting)) + 
  geom_col(position = "stack") +  # 明确指定堆叠模式,避免歧义
  facet_grid(~type) + 
  ggtitle('Budget Percentage by Targeting Type ') + 
  theme(
    axis.title.y = element_text(colour="gray20", size=12, angle=90, hjust=.5, vjust=1),
    axis.title.x = element_text(colour="gray20"),
    plot.title = element_text(hjust=0.5, size = 14),  # 修正标题居左的问题
    axis.text.x = element_text(size=12, angle=0, hjust=.5, vjust=0)  # 修正x轴文本位置
  ) + 
  xlab('Spend Percentage') + 
  geom_text(
    aes(x = cum_spend, label = paste0(spend_percentage, "%")),  # 用计算出的中心坐标,添加百分号
    hjust = 0.5, color = "white", size = 4  # 居中对齐,白色文字提升可读性
  )

ggplotly(gg1)

关键说明

  • cum_spend列:通过分组累积求和,再减去自身的一半,得到每个堆叠条形的中心位置。
  • hjust=0.5:确保文字在条形内水平居中,配合中心坐标实现精准定位。
  • 额外优化:调整标题和x轴文本的位置,添加百分号让数据更直观,白色文字避免和条形背景冲突。
二、使用highcharter复现图表

highcharter可以更简洁地实现堆叠横向条形图,且默认支持中心标签,无需手动计算位置:

1. 安装并加载包

install.packages("highcharter")
library(highcharter)

2. 简洁实现代码(使用tidy接口)

highchart() %>%
  hc_chart(type = "bar", inverted = TRUE) %>%  # inverted=TRUE转为横向条形图
  hc_title(text = "Budget Percentage by Targeting Type") %>%
  hc_xAxis(title = list(text = "Spend Percentage"), max = 100) %>%
  hc_yAxis(categories = unique(df$category)) %>%
  hc_facet_wrap(~type) %>%  # 实现分面,对应ggplot的facet_grid
  hc_add_series_tidy(
    df, 
    y = spend_percentage, 
    group = targeting, 
    type = "bar", 
    stacking = "normal"
  ) %>%
  hc_plotOptions(
    bar = list(
      dataLabels = list(
        enabled = TRUE,
        format = "{y}%",  # 设置标签格式
        color = "white"
      )
    )
  ) %>%
  hc_colors(c("#007bff", "#28a745")) %>%  # 自定义条形颜色
  hc_legend(title = list(text = "Targeting"))

关键说明

  • inverted=TRUE:将条形图转为横向,对应ggplot中y=category的设置。
  • stacking="normal":开启堆叠模式,和ggplot的geom_col一致。
  • dataLabels:自动在条形中心生成标签,无需手动计算坐标,直接设置格式即可。
  • hc_facet_wrap:快速实现分面效果,语法和ggplot类似。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 23:28:00