如何为基于3种X轴值的12个geom_bar分别设置自定义颜色?
问题描述
我用给定数据生成了堆叠柱状图(代码如下),当前图表里有12个堆叠的geom_bar,原本是按speclib的两个因子分组上色,现在想手动给这12个柱子的每个堆叠分段都设置独立颜色,预期效果是每个分段都有专属的自定义色彩(参考样图中每个堆叠部分颜色各不相同,没有统一的分组配色)。
原始生成代码
ggplot(q, aes(x = digest_method, y = diff, color = forcats::fct_rev(speclib), fill = forcats::fct_rev(speclib))) + geom_bar(stat = "identity", position = "stack") + geom_text(aes(y = protein_total, label = protein_total), vjust = rep(c(1.5, -0.5), 6), show.legend = FALSE) + facet_wrap(~ frak, nrow = 1)
数据
q <- structure(list(digest_method = c("Direct", "Direct", "Direct", "Direct", "In solution", "In solution", "In solution", "In solution", "PAC", "PAC", "PAC", "PAC"), protein_total = c(780L, 1173L, 948L, 1526L, 891L, 1444L, 1442L, 1880L, 947L, 1704L, 1598L, 2433L), speclib = c("No", "SpecLib", "No", "SpecLib", "No", "SpecLib", "No", "SpecLib", "No", "SpecLib", "No", "SpecLib"), frak = structure(c(1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L), levels = c("Raw", "20K Vesicles", "120K Vesicles", "Vesicles depleted"), class = "factor"), diff = c(780L, 393L, 948L, 578L, 891L, 553L, 1442L, 438L, 947L, 757L, 1598L, 835L)), class = c("grouped_df", "tbl_df", "tbl", "data.frame"), row.names = c(NA, -12L), groups = structure(list(frak = structure(c(1L, 1L, 1L, 2L, 2L, 2L), levels = c("Raw", "20K Vesicles", "120K Vesicles", "Vesicles depleted"), class = "factor"), digest_method = c("Direct", "In solution", "PAC", "Direct", "In solution", "PAC"), .rows = structure(list(1:2, 5:6, 9:10, 3:4, 7:8, 11:12), ptype = integer(0), class = c("vctrs_list_of", "vctrs_vctr", "list"))), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"), .drop = TRUE))
解决方案
要实现每个堆叠分段单独设色,关键是给每个分段创建唯一标识,再用这个标识映射颜色,手动指定对应色彩。
第一步:给每个分段加唯一ID
给数据框q新增一列segment_id,每行对应一个唯一的堆叠分段(正好12个):
q <- q %>% mutate(segment_id = row_number())
第二步:准备自定义颜色向量
准备12个颜色,数量和分段数一致,你可以替换成自己想要的色值:
custom_colors <- c("#E69F00", "#56B4E9", "#009E73", "#F0E442", "#0072B2", "#D55E00", "#CC79A7", "#999999", "#E69F00", "#56B4E9", "#009E73", "#F0E442")
第三步:修改ggplot代码
把fill和color的映射从speclib改成segment_id,再用scale_fill_manual和scale_color_manual绑定自定义颜色:
ggplot(q, aes(x = digest_method, y = diff, color = factor(segment_id), fill = factor(segment_id))) + geom_bar(stat = "identity", position = "stack") + geom_text(aes(y = protein_total, label = protein_total), vjust = rep(c(1.5, -0.5), 6), show.legend = FALSE) + facet_wrap(~ frak, nrow = 1) + scale_fill_manual(values = custom_colors) + scale_color_manual(values = custom_colors) + guides(fill = "none", color = "none") # 不需要图例就保留这行,要的话删掉
补充说明
segment_id的顺序和数据框行顺序一致,所以颜色向量的顺序要对应,确保每个分段颜色匹配正确- 如果需要保留图例,去掉最后一行的
guides代码即可
内容的提问来源于stack exchange,提问作者cmirian
相关产品推荐
相关产品推荐

