如何在多幅ggplot图中保持细菌家族的一致配色?
问题
需要绘制多幅柱状图,每幅展示一种植物对应的前10种细菌,以细菌所属的**Family(科)**为柱子填充颜色。单图绘制正常,但后续要合并为多面图,要求同一家族在所有图中使用相同配色(比如Pantoea所属的Erwiniaceae科在两幅示例图中当前颜色不同)。由于数据集可能包含上百个家族,且各图前10种细菌的家族存在差异,希望避免手动为每个家族指定颜色。
示例数据
植物Cintybus的前10种细菌数据
dput(top10_cintybus) structure(list(Order = c("Enterobacterales", "Enterobacterales", "Enterobacterales", "Sphingomonadales", "Enterobacterales", "Bacillales", "Hyphomicrobiales", "Bacillales", "Xanthomonadales", "Hyphomicrobiales" ), Family = c("Enterobacteriaceae", "Erwiniaceae", "Yersiniaceae", "Sphingomonadaceae", "Morganellaceae", "Bacillaceae", "Methylobacteriaceae", "Bacillaceae", "Xanthomonadaceae", "Rhizobiaceae"), MKC132 = c(0L, 0L, 27L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), MKC146 = c(33L, 8L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), MKC227 = c(11L, 0L, 0L, 0L, 6L, 2L, 0L, 3L, 0L, 0L), MKC231 = c(37L, 0L, 0L, 20L, 0L, 0L, 3L, 0L, 2L, 2L), MKC242 = c(0L, 7L, 0L, 0L, 0L, 2L, 0L, 0L, 0L, 0L ), MKC276 = c(9L, 0L, 7L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), MKC351 = c(6L, 19L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), Total = c(96, 34, 34, 20, 6, 4, 3, 3, 2, 2), Genus = structure(c(10L, 8L, 9L, 7L, 6L, 5L, 4L, 3L, 2L, 1L), levels = c("Allorhizobium", "Xanthomonas", "Bacillus", "Methylobacterium", "Heyndrickxia", "Arsenophonus", "Sphingomonas", "Pantoea", "Serratia", "???.1"), class = "factor")), row.names = c(NA, 10L), class = "data.frame")
植物Alappa的前10种细菌数据
dput(top10_alappa) structure(list(Order = c("Enterobacterales", "Xanthomonadales", "Enterobacterales", "Enterobacterales", "Enterobacterales", "Enterobacterales", "Enterobacterales", "Hyphomicrobiales", "Enterobacterales", "Burkholderiales" ), Family = c("Erwiniaceae", "Xanthomonadaceae", "Enterobacteriaceae", "Erwiniaceae", "Enterobacteriaceae", "Enterobacteriaceae", "Enterobacteriaceae", "Rhizobiaceae", "Morganellaceae", "Oxalobacteraceae"), MKC154 = c(11L, 0L, 36L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), MKC167A = c(14105L, 0L, 5810L, 13055L, 1223L, 2316L, 1276L, 0L, 550L, 13L), MKC167B = c(18L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), MKC214 = c(83842L, 5L, 22936L, 175L, 6828L, 94L, 0L, 7L, 0L, 0L), MKC226 = c(0L, 0L, 11L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), MKC233 = c(55L, 0L, 13L, 14L, 0L, 0L, 0L, 0L, 0L, 0L), MKC314 = c(0L, 0L, 0L, 3L, 0L, 0L, 0L, 0L, 0L, 0L), MKC364 = c(32L, 8L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), MKC366 = c(38L, 46599L, 0L, 10L, 62L, 0L, 0L, 549L, 0L, 512L), Total = c(98101, 46612, 28806, 13257, 8113, 2410, 1276, 556, 550, 525), Genus = structure(10:1, levels = c("Janthinobacterium", "Morganella", "Allorhizobium", "Citrobacter", "Siccibacter", "Enterobacter", "Erwinia", "???.1", "Stenotrophomonas", "Pantoea" ), class = "factor")), row.names = c(NA, 10L), class = "data.frame")
原绘图代码
species="Cintybus" ggplot(data=top10_cintybus,aes(x=Genus, y=Total, fill=Family)) + geom_bar(stat = "identity", colour="black") + coord_flip() + theme_bw() + scale_y_continuous(trans="log10", limits=c(1,1000000), labels=scales::comma, expand=expansion(mult=c(0,.05))) + theme(axis.title.x = element_text(size=18)) + theme(axis.text.x = element_text(colour="black", face="bold", size=15)) + theme(axis.title.y = element_text(size=18, vjust=2.5)) + theme(axis.text.y = element_text(face="bold.italic", colour="black", size=15)) + geom_text(aes(label=format(Total, big.mark=",")), hjust=1.5, color="white", fontface="plain", size=5) + xlab("Genus") + ylab("Abundance") + ggtitle(species) + theme(plot.title = element_text(size=18))
解决方案
1. 统一所有家族的颜色映射
先收集所有数据集里的Family,为每个家族分配固定颜色,避免单图绘图时ggplot自动生成不同配色。
# 合并所有数据集,获取完整的家族列表 all_families <- unique(c(top10_cintybus$Family, top10_alappa$Family)) # 为每个家族生成唯一颜色(可替换为其他配色函数,比如viridis系) family_colors <- scales::hue_pal()(length(all_families)) names(family_colors) <- all_families
2. 调整单图代码,应用统一颜色映射
在绘图时通过scale_fill_manual指定预先生成的颜色映射,确保同一家族颜色一致:
# 绘制Cintybus的图 p_cintybus <- ggplot(data=top10_cintybus,aes(x=Genus, y=Total, fill=Family)) + geom_bar(stat = "identity", colour="black") + coord_flip() + theme_bw() + scale_y_continuous(trans="log10", limits=c(1,1000000), labels=scales::comma, expand=expansion(mult=c(0,.05))) + theme(axis.title.x = element_text(size=18)) + theme(axis.text.x = element_text(colour="black", face="bold", size=15)) + theme(axis.title.y = element_text(size=18, vjust=2.5)) + theme(axis.text.y = element_text(face="bold.italic", colour="black", size=15)) + geom_text(aes(label=format(Total, big.mark=",")), hjust=1.5, color="white", fontface="plain", size=5) + xlab("Genus") + ylab("Abundance") + ggtitle("Cintybus") + theme(plot.title = element_text(size=18)) + scale_fill_manual(values = family_colors) # 应用统一颜色映射 # 绘制Alappa的图 p_alappa <- ggplot(data=top10_alappa,aes(x=Genus, y=Total, fill=Family)) + geom_bar(stat = "identity", colour="black") + coord_flip() + theme_bw() + scale_y_continuous(trans="log10", limits=c(1,1000000), labels=scales::comma, expand=expansion(mult=c(0,.05))) + theme(axis.title.x = element_text(size=18)) + theme(axis.text.x = element_text(colour="black", face="bold", size=15)) + theme(axis.title.y = element_text(size=18, vjust=2.5)) + theme(axis.text.y = element_text(face="bold.italic", colour="black", size=15)) + geom_text(aes(label=format(Total, big.mark=",")), hjust=1.5, color="white", fontface="plain", size=5) + xlab("Genus") + ylab("Abundance") + ggtitle("Alappa") + theme(plot.title = element_text(size=18)) + scale_fill_manual(values = family_colors) # 应用统一颜色映射
3. 高效生成多面图:合并数据集后用facet_wrap
将所有植物的前10数据合并到一个数据框,添加植物标识列,直接用facet_wrap生成多面图,无需单独绘制每张图:
# 为每个数据集添加植物标识列 top10_cintybus$Species <- "Cintybus" top10_alappa$Species <- "Alappa" # 合并数据集 combined_data <- rbind(top10_cintybus, top10_alappa) # 绘制多面图 ggplot(data=combined_data,aes(x=Genus, y=Total, fill=Family)) + geom_bar(stat = "identity", colour="black") + coord_flip() + theme_bw() + scale_y_continuous(trans="log10", limits=c(1,1000000), labels=scales::comma, expand=expansion(mult=c(0,.05))) + theme(axis.title.x = element_text(size=18)) + theme(axis.text.x = element_text(colour="black", face="bold", size=15)) + theme(axis.title.y = element_text(size=18, vjust=2.5)) + theme(axis.text.y = element_text(face="bold.italic", colour="black", size=15)) + geom_text(aes(label=format(Total, big.mark=",")), hjust=1.5, color="white", fontface="plain", size=5) + xlab("Genus") + ylab("Abundance") + facet_wrap(~Species, scales = "free_y") + # 根据植物拆分面板,y轴自由缩放 scale_fill_manual(values = family_colors) + theme(plot.title = element_text(size=18))
说明
- 若有更多植物数据集,只需重复添加
Species列并合并到combined_data即可,无需修改绘图代码。 - 若默认配色区分度不足,可替换配色函数,比如
scales::viridis_pal(option = "D")(length(all_families))。
内容的提问来源于stack exchange,提问作者Katherine Chau
相关产品推荐
相关产品推荐

