如何将两个ggplot合并为单图:箱线图+右侧双Y轴柱状图
在ggplot2中实现箱线图与独立右侧Y轴柱状图的叠加(共享X轴)
我来帮你搞定这个双Y轴叠加的需求!你要的是箱线图用左侧Y轴、柱状图用右侧独立Y轴,共享X轴且柱状图在箱线图后方,还要保留分面效果对吧?咱们一步步来:
第一步:简化数据处理
你之前生成df2的代码有点绕,其实可以直接用group_by加summarise一步算出均值,更简洁高效:
library(dplyr) df2 <- test %>% group_by(group, type) %>% summarise(freq_mean = mean(freq), .groups = "drop")
第二步:创建叠加的双Y轴图
核心思路是用ggplot的sec_axis()创建右侧Y轴,同时注意图层顺序(先画柱状图,让它在底层),还要避免图层之间的aes冲突:
library(ggplot2) ggplot(test, aes(factor(group), value, fill = factor(key))) + # 先画柱状图(放在箱线图后面),用独立的aes,不继承主图的映射 geom_col(data = df2, aes(x = factor(group), y = freq_mean), alpha = 0.1, inherit.aes = FALSE) + # 再画箱线图,确保它在柱状图上方 geom_boxplot() + # 保留你的分面设置 facet_grid(~type) + # 设置双Y轴:左侧是value的轴,右侧是均值freq的轴 scale_y_continuous( name = "Value", # 左侧Y轴名称 sec.axis = sec_axis(~., name = "Mean Frequency") # 右侧Y轴名称 ) + # 主题调整,和你之前的设置对齐 theme_classic() + theme( axis.title.x = element_blank(), axis.ticks.x = element_blank(), # 可以给右侧轴加个灰色,和柱状图的alpha对应,更直观 axis.title.y.right = element_text(color = "gray50"), axis.text.y.right = element_text(color = "gray50") ) + # 给fill图例加个清晰的名称 labs(fill = "Key")
关键要点解释
- 图层顺序:先画柱状图再画箱线图,这样箱线图会自动覆盖在柱状图上方,满足你“柱状图在对应箱线图后方”的要求
inherit.aes = FALSE:这个参数很重要,避免柱状图继承主图的fill和y映射,防止出现错误- 双Y轴实现:
sec_axis()帮你创建独立的右侧Y轴,这里因为你的freq_mean和value数值范围不同,直接用~.表示不对数据做缩放,如果后续需要调整刻度比例,比如把右侧轴缩放10倍,可以改成~./10,同时调整轴标签说明就行 - 分面兼容:
facet_grid(~type)会自动应用到两个图层,不需要额外设置
这样就解决了你之前“共享Y轴导致箱线图被压缩”的问题,两个变量各自用自己的刻度范围,完美叠加!
内容的提问来源于stack exchange,提问作者Haakonkas
相关产品推荐
相关产品推荐

