如何在facet_wrap的堆叠条形图顶部添加Revenue总计文本?
在堆叠条形图顶部添加Revenue总计文本
问题说明
需要给facet_wrap生成的每个堆叠条形图顶部,添加对应年份的Revenue数值作为总计文本,数值与数据中metric列的"Revenue"值一致。
当前代码
prof %>% filter(metric != "Revenue") %>% pivot_longer(!1:2, names_to = "group") %>% mutate(total_2024 = sum(value * (year == 2024)), .by = group) %>% mutate(group = reorder(group, -total_2024)) %>% mutate(year_group_total = sum(value), .by = c(year, group)) %>% ggplot() + aes(x = factor(year), y = value, fill = metric) + geom_bar(stat = "identity", position = "stack") + geom_text(aes(label = round(value, 0)), position = position_stack(vjust = 0.5), size = 3, color = "white") + facet_wrap(~ group, nrow = 1)
数据结构
structure(list(metric = c("Semi-direct/Indirect OPEX", "Direct OPEX", "Cogs", "EBITDA", "Semi-direct/Indirect OPEX", "Direct OPEX", "Cogs", "EBITDA", "Revenue", "Revenue"), year = c(2024, 2024, 2024, 2024, 2023, 2023, 2023, 2023, 2023, 2024), `B2C Mobile` = c(897.784296273134, 1553.75734792605, 2174.93374732592, 5755.54423659222, 998.273127452503, 1491.49788927451, 2577.32537561267, 5188.04527286322, 10255.1416652029, 10382.0196281173), `B2B Mobile` = c(556.814329695538, 910.678821511126, 1206.88678722175, 2974.74324198596, 551.422958887446, 886.952093722743, 1291.87657757128, 3091.66275796777, 5821.91438814924, 5649.12318041437 ), `B2C Fiber` = c(517.558827512705, 495.164268332664, 2047.61667685037, 471.94510699589, 412.859413724063, 454.877885907187, 1936.82417093636, 500.145306066416, 3304.70677663402, 3532.28487969163), `HFC B2C` = c(252.327289621926, 194.055038683145, 892.79869969144, 305.281096059764, 183.864737312406, 177.365375913805, 1020.84928874347, 403.547767116329, 1785.62716908601, 1644.46212405627), `B2B Fiber` = c(130.704875738789, 181.150718557421, 315.08402928116, 259.876581766672, 184.022162044549, 203.280264535604, 290.095491871566, 288.017740790265, 965.415659241984, 886.816205344042 ), Wholesale = c(335.66507766929, 81.3907132734683, 359.637328238667, 726.393721768013, 606.085398971104, -161.245692311656, 379.926654798916, 721.092000854812, 1545.85836231318, 1503.08684094944), Other = c(582.212942299726, 460.192151400037, 486.308969368716, 660.596166217528, 884.601699952072, 349.083787813294, 545.586302785773, 509.765926491606, 2289.03771704274, 2189.31022928601)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -10L))
当前效果

解决方案
核心思路是先从原始数据中提取每个group和year对应的Revenue数值,再将其作为文本标注在每个堆叠条形的顶部。
修改后完整代码
# 提取Revenue数据并整理格式 revenue_data <- prof %>% filter(metric == "Revenue") %>% pivot_longer(!1:2, names_to = "group", values_to = "revenue") %>% select(-metric) # 主数据处理+绘图 prof %>% filter(metric != "Revenue") %>% pivot_longer(!1:2, names_to = "group") %>% mutate(total_2024 = sum(value * (year == 2024)), .by = group) %>% mutate(group = reorder(group, -total_2024)) %>% # 合并Revenue数据 left_join(revenue_data, by = c("group", "year")) %>% ggplot() + aes(x = factor(year), y = value, fill = metric) + geom_bar(stat = "identity", position = "stack") + # 条形内部数值标签 geom_text(aes(label = round(value, 0)), position = position_stack(vjust = 0.5), size = 3, color = "white") + # 添加顶部Revenue总计文本 geom_text(aes(y = revenue, label = round(revenue, 0)), size = 3.5, color = "black", vjust = -0.5) + facet_wrap(~ group, nrow = 1) + # 调整y轴范围,避免顶部文本被截断 expand_limits(y = max(revenue_data$revenue) * 1.1)
关键步骤说明
- 提取并整理Revenue数据:从原始数据中筛选出
metric为"Revenue"的行,转成长格式后得到每个分组(group)和年份(year)对应的Revenue值。 - 合并数据:将Revenue数据与主数据通过
group和year关联,确保每个行都能拿到对应年份的Revenue数值。 - 添加顶部文本:用
geom_text指定y轴位置为revenue,标签为四舍五入后的Revenue值,通过vjust = -0.5将文本放在条形顶部上方。 - 调整y轴范围:使用
expand_limits扩展y轴上限,避免顶部的总计文本被图表边界截断。
内容的提问来源于stack exchange,提问作者HoelR
相关产品推荐
相关产品推荐

