如何在ggplot2中通过scale_fill_viridis实现颜色循环?
问题
绘制含大量代谢物的比例堆叠条形图时,用scale_fill_viridis(discrete=TRUE)会导致相邻代谢物颜色区分度极低。需要从viridis库选6种差异明显的颜色循环使用,且图例严格按照代谢物在图中的出现顺序排列,通过图例顺序就能轻松对应循环的颜色。
颜色循环逻辑示例:
前6种代谢物对应颜色:
Ala = 深紫
allo.ille = 紫色
Ans = 蓝色
Arg = 绿色
Asp = 浅绿
Car = 黄色后续代谢物循环复用上述颜色:
Citr = 深紫
Cys = 紫色
Cyst.1 = 蓝色
Cyst.2 = 绿色
Eth = 浅绿
GABA = 黄色
原代码(已注释尝试过的无效方案):
library(viridis) library(ggplot2) # 尝试过但无效的代码 #color_mapping <- rep(viridis(6),100) ggplot(df, aes(fill=group, y=value, x=Species)) + geom_bar(position="fill", stat="identity") + #scale_color_manual(values=color_mapping[1:n_distinct(df$group)])+ #scale_colour_brewer(palette="Set5") + scale_fill_viridis(discrete=TRUE, name="NEFA Content") + theme_ipsum() + theme(axis.text.x=element_text(angle=90, hjust=1,vjust=0.25)) + theme(axis.title.x=element_blank()) + theme(axis.title.y=element_blank()) + theme(panel.background=element_rect(colour="black")) + theme(panel.grid.major=element_blank())
解决方案
要实现需求,核心是锁定代谢物的显示顺序和构建循环颜色映射,具体步骤如下:
- 固定代谢物的因子顺序,避免ggplot自动按字母排序(这是图例顺序正确的关键):
# 按df中group的出现顺序设置因子水平 df$group <- factor(df$group, levels = unique(df$group))
- 生成6种viridis颜色的循环映射:
# 提取6种差异明显的viridis颜色 viridis_colors <- viridis(6) # 按代谢物总数循环生成颜色向量 color_mapping <- rep(viridis_colors, length.out = n_distinct(df$group))
- 替换原代码中的
scale_fill_viridis为自定义的手动颜色映射:
完整修改后的代码:
library(viridis) library(ggplot2) # 锁定代谢物的出现顺序为图例顺序 df$group <- factor(df$group, levels = unique(df$group)) # 创建6种viridis颜色的循环映射 viridis_colors <- viridis(6) color_mapping <- rep(viridis_colors, length.out = n_distinct(df$group)) ggplot(df, aes(fill=group, y=value, x=Species)) + geom_bar(position="fill", stat="identity") + scale_fill_manual(values = color_mapping, name = "NEFA Content") + # 替换为手动颜色映射 theme_ipsum() + theme(axis.text.x=element_text(angle=90, hjust=1, vjust=0.25), axis.title.x=element_blank(), axis.title.y=element_blank(), panel.background=element_rect(colour="black"), panel.grid.major=element_blank())
补充说明
- 若想调整颜色风格,可修改
viridis(6)的option参数,比如viridis(6, option = "A")(viridis内置A-F共6种调色板,默认是D)。 - 必须先设置因子水平,否则ggplot会自动对
group按字母排序,导致图例顺序和预期不符,颜色循环的对应关系也会混乱。
内容的提问来源于stack exchange,提问作者Katherine Chau
相关产品推荐
相关产品推荐

