ggplot分组柱状图:弃用facet_wrap实现单X轴无空白布局
替代facet_wrap的堆叠百分比柱状图分组方案
原代码使用facet_wrap(~env)出现空白区域是因为每个面板会强制显示所有Sample,部分环境下无对应样本数据就会留空;X轴不统一则是默认面板X轴范围一致,但实际各环境样本数量不同导致显示混乱。以下是三种可行替代方案:
方案1:用facet_grid自适应X轴(消除空白+统一Y轴)
替换facet_wrap为facet_grid,通过参数让每个面板只显示对应环境的样本,同时保持Y轴统一:
library(ggplot2) library(scales) ggplot(dat, aes(x = Sample, fill = phylum, y = Abundance)) + geom_bar(position="fill", stat = "identity") + theme_bw() + # 替换分面函数,scales/space=free_x让X轴自适应样本数量 facet_grid(. ~ env, scales = "free_x", space = "free_x") + theme(axis.text.x = element_text(angle = 90, size = 13, colour = "black", vjust = 0.5, hjust = 1), axis.title.x = element_text(size = 15), axis.text.y = element_text(size = 13, vjust = 0.5, hjust = 1), axis.title.y = element_text(size = 15), legend.title = element_text(size = 15), legend.text = element_text(size = 15, colour = "black")) + ggtitle("Minion samples: Proteobacteria Phyla") + scale_y_continuous(labels = percent_format(), limits=c(0,1)) + scale_fill_manual(values = c("Acidobacteria"="#3288bd", "Actinobacteria" = "#99d594", "Candidatus Rokubacteria" = "#74c476", "Chloroflexi"= "#e6f598", "Planctomycetes"="#fee08b", "Proteobacteria" = "#fc8d59", "Verrucomicrobia" = "#a50f15", "Taxa less than 1%" = "#d53e4f"))
说明:scales="free_x"让每个面板仅显示当前环境的样本,space="free_x"让面板宽度根据样本数量自适应,彻底消除空白区域,同时Y轴保持统一便于对比。
方案2:将环境与样本合并为X轴变量(无需分面)
把环境和样本合并成一个X轴标签,直接在同一面板展示所有分组样本:
library(ggplot2) library(scales) library(stringr) # 合并环境与样本标签,用换行区分 dat$env_sample <- str_c(dat$env, "\n", dat$Sample) ggplot(dat, aes(x = env_sample, fill = phylum, y = Abundance)) + geom_bar(position="fill", stat = "identity") + theme_bw() + theme(axis.text.x = element_text(angle = 90, size = 13, colour = "black", vjust = 0.5, hjust = 1), axis.title.x = element_text(size = 15), axis.text.y = element_text(size = 13, vjust = 0.5, hjust = 1), axis.title.y = element_text(size = 15), legend.title = element_text(size = 15), legend.text = element_text(size = 15, colour = "black")) + ggtitle("Minion samples: Proteobacteria Phyla") + scale_y_continuous(labels = percent_format(), limits=c(0,1)) + scale_fill_manual(values = c("Acidobacteria"="#3288bd", "Actinobacteria" = "#99d594", "Candidatus Rokubacteria" = "#74c476", "Chloroflexi"= "#e6f598", "Planctomycetes"="#fee08b", "Proteobacteria" = "#fc8d59", "Verrucomicrobia" = "#a50f15", "Taxa less than 1%" = "#d53e4f")) + xlab("环境 & 样本")
说明:所有样本在同一面板展示,无空白区域,通过X轴标签的换行清晰区分不同环境组。
方案3:用patchwork手动拼接子图(完全自定义布局)
如果需要更灵活的排版,可以单独绘制每个环境的子图,再用patchwork拼接:
library(ggplot2) library(scales) library(patchwork) # 按环境拆分数据集 env_list <- split(dat, dat$env) # 批量生成每个环境的子图 plot_list <- lapply(names(env_list), function(env_name) { ggplot(env_list[[env_name]], aes(x = Sample, fill = phylum, y = Abundance)) + geom_bar(position="fill", stat = "identity") + theme_bw() + ggtitle(env_name) + theme(axis.text.x = element_text(angle = 90, size = 13, colour = "black", vjust = 0.5, hjust = 1), axis.title.x = element_text(size = 15), axis.text.y = element_text(size = 13, vjust = 0.5, hjust = 1), axis.title.y = element_text(size = 15), legend.title = element_text(size = 15), legend.text = element_text(size = 15, colour = "black")) + scale_y_continuous(labels = percent_format(), limits=c(0,1)) + scale_fill_manual(values = c("Acidobacteria"="#3288bd", "Actinobacteria" = "#99d594", "Candidatus Rokubacteria" = "#74c476", "Chloroflexi"= "#e6f598", "Planctomycetes"="#fee08b", "Proteobacteria" = "#fc8d59", "Verrucomicrobia" = "#a50f15", "Taxa less than 1%" = "#d53e4f")) }) # 拼接子图,共享图例并添加总标题 wrap_plots(plot_list, ncol = 2) + plot_layout(guides = "collect") + plot_annotation(title = "Minion samples: Proteobacteria Phyla")
说明:每个子图仅展示对应环境的样本,完全消除空白,可自定义子图排列行数/列数,布局灵活性最高。
内容的提问来源于stack exchange,提问作者Valentina
相关产品推荐
相关产品推荐

