如何用ggplot2绘制含细菌与真菌的单Y轴联合柱状图(带误差棒)
在同一ggplot2图中同时展示细菌和真菌的柱状图+误差棒
问题背景
你手上有这个R数据框:
structure(list(Site = c("aNon burn", "aNon burn", "aNon burn", "Long rotation", "Long rotation", "Long rotation"), Depth = c("0-20cm", "20-40cm", "40-60cm", "0-20cm", "20-40cm", "40-60cm"), bacteria = c(10.03, 8.46, 8.48, 9.34, 8.43, 8.45), bac_se = c(0.06, 0.06, 0.09, 0.08, 0.1, 0.05), fungi = c(8.18, 6.31, 6.45, 7.65, 5.88, 5.86), fun_se = c(0.21, 0.19, 0.17, 0.16, 0.17, 0.16)), row.names = c(NA, 6L), class = "data.frame")
已经用这段代码画出了细菌的柱状图(带误差棒):
ggplot(qpcrdata2, aes(x=Depth, y=bacteria, fill=Site)) + geom_bar(stat="identity", position=position_dodge()) + geom_errorbar(aes(ymin=bacteria-bac_se, ymax=bacteria+bac_se), width=.2,position=position_dodge(.9))
现在想在同一个Y轴的图里加上真菌的柱子和误差棒,怎么实现?
解决办法
最省心的方式是把宽格式数据转成长格式——ggplot天生更适配长数据,这样不用重复写多次geom_bar和geom_errorbar。具体步骤:
1. 加载所需工具包
确保已安装并加载tidyverse(包含处理数据的dplyr/tidyr和绘图的ggplot2):
library(tidyverse)
2. 转换数据格式为长格式
把细菌、真菌的丰度和对应的标准误整合到统一列中,新增标记列区分生物类型:
qpcr_long <- qpcrdata2 %>% # 合并丰度列,标记生物类型 pivot_longer(cols = c(bacteria, fungi), names_to = "Organism", values_to = "Abundance") %>% # 合并标准误列 pivot_longer(cols = c(bac_se, fun_se), names_to = "SE_col", values_to = "SE") %>% # 匹配丰度与对应的标准误 filter(str_remove(SE_col, "_se") == Organism) %>% # 删除无用的中间列 select(-SE_col)
3. 绘制合并后的图表
用转换后的长数据绘图,注意让误差棒和柱子的偏移宽度保持一致,避免错位:
ggplot(qpcr_long, aes(x = Depth, y = Abundance, fill = Site, group = interaction(Organism, Site))) + # 绘制柱状图,设置统一的偏移宽度 geom_bar(stat = "identity", position = position_dodge(width = 0.8)) + # 绘制误差棒,偏移宽度与柱状图保持一致 geom_errorbar(aes(ymin = Abundance - SE, ymax = Abundance + SE), width = 0.2, position = position_dodge(width = 0.8)) + # 添加图表标签 labs(title = "不同深度和位点的微生物丰度", y = "丰度值", fill = "采样位点") + # 使用预设配色方案 scale_fill_brewer(palette = "Set2") + # 应用简洁主题 theme_bw()
如果想让细菌和真菌的柱子在每个深度下分开展示,同时用颜色区分生物类型+位点,可以调整fill映射:
ggplot(qpcr_long, aes(x = Depth, y = Abundance, fill = interaction(Organism, Site))) + geom_bar(stat = "identity", position = position_dodge(width = 0.8)) + geom_errorbar(aes(ymin = Abundance - SE, ymax = Abundance + SE), width = 0.2, position = position_dodge(width = 0.8)) + labs(title = "不同深度和位点的微生物丰度", y = "丰度值", fill = "生物类型+采样位点") + scale_fill_brewer(palette = "Set2") + theme_bw()
关键注意点
- 宽转长是核心:让ggplot可以统一处理两类微生物的数据,避免重复代码。
- 偏移宽度要一致:
position_dodge的width参数在geom_bar和geom_errorbar中必须相同,保证误差棒与柱子精准对齐。
内容的提问来源于stack exchange,提问作者martyn
相关产品推荐
相关产品推荐

