You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 12:48:21