如何用R的ggplot与ggforce实现堆叠柱状图局部放大及定制
解决方案
1. 让Sold柱子显示总和
要实现Sold柱子显示所有值的总和,需先对数据按Status分组汇总,再绘图:
library(ggplot2) library(dplyr) # 原始数据 df <- data.frame(Product = c("A", "A", "A", "A", "A", "A"), Status = c("Bought", "Sold", "Sold", "Sold", "Sold", "Sold"), Month = c("April", "March", "May", "July", "October", "November"), N = c(48, 12, 11, 1, 2, 3)) # 生成汇总数据:按Product和Status分组求和 df_summary <- df %>% group_by(Product, Status) %>% summarize(N = sum(N), .groups = "drop") # 绘制修正后的chart1 (chart1_fixed <- ggplot(df_summary, aes(x = Product, y = N, fill = Status)) + geom_col(position = "stack") + geom_text(aes(label = N), size = 3, position = position_stack(vjust = 0.5)) + theme_bw())
此时Sold柱子会显示所有Sold值的总和(29),与Bought的48堆叠展示。
2. 实现带放大效果的镜像图表
要实现「右侧为总和柱(chart1样式)、左侧为Sold详细放大版」的效果,提供两种简便方法:
方法一:使用ggforce的facet_zoom(保留联动放大效果)
通过side参数控制放大面板位置,同时分别绘制总和数据与详细数据:
library(ggforce) (chart_final <- ggplot() + # 绘制右侧的总和柱(chart1样式) geom_col(data = df_summary, aes(x = Product, y = N, fill = Status), position = "stack") + geom_text(data = df_summary, aes(x = Product, y = N, label = N), size = 3, position = position_stack(vjust = 0.5)) + # 绘制左侧的Sold详细分月柱(仅在放大面板显示) geom_col(data = df %>% filter(Status == "Sold"), aes(x = Product, y = N, fill = Month), position = "stack") + geom_text(data = df %>% filter(Status == "Sold"), aes(x = Product, y = N, label = N), size = 3, position = position_stack(vjust = 0.5)) + theme_bw() + # 设置放大范围为0-27.5(覆盖Sold总和),放大面板放在左侧,原图(总和柱)在右侧 facet_zoom(ylim = c(0, 27.5), side = "left", split = TRUE) + # 统一填充色的图例标题 labs(fill = "分类") + # 隐藏facet的标题栏 theme(strip.background = element_blank(), strip.text = element_blank()))
若需让放大面板在右侧、总和柱在左侧,只需将side = "left"改为side = "right"。
方法二:使用patchwork拼接两个独立图表(更灵活)
如果不需要联动放大效果,直接用patchwork拼接两个图表,可自由调整左右顺序:
library(patchwork) # 绘制Sold详细放大图 chart_detail <- ggplot(df %>% filter(Status == "Sold"), aes(x = Product, y = N, fill = Month)) + geom_col(position = "stack") + geom_text(aes(label = N), size = 3, position = position_stack(vjust = 0.5)) + theme_bw() + ylim(0, 27.5) + # 固定y轴范围实现放大 labs(fill = "月份") # 绘制总和柱图 chart_total <- ggplot(df_summary, aes(x = Product, y = N, fill = Status)) + geom_col(position = "stack") + geom_text(aes(label = N), size = 3, position = position_stack(vjust = 0.5)) + theme_bw() + labs(fill = "状态") # 拼接:左侧放大详细图,右侧总和柱图 chart_detail + chart_total + plot_layout(ncol = 2) # 镜像效果:右侧放大图,左侧总和柱图 chart_total + chart_detail + plot_layout(ncol = 2)
这种方法可独立控制两个图表的样式,调整自由度更高。
内容的提问来源于stack exchange,提问作者mad10les
相关产品推荐
相关产品推荐

