ggplot2堆叠geom_bar如何保留全部分类颜色仅显示指定图例项
问题原因
调用scale_fill_manual()时传入无命名的颜色向量+仅指定目标分类为breaks,会导致ggplot仅为legend_list列表内的分类建立颜色映射,不在列表内的分类因无匹配颜色无法正常显示填充。
修复方案
核心逻辑是给所有分类建立稳定的命名颜色映射,再单独指定图例要展示的分类,不会影响图上的堆叠填充效果:
- 先提取数据中全部分类单元,生成和分类名一一对应的命名颜色向量,保证每个分类都有专属填充色
- 再在标度或图例参数中指定仅展示
legend_list内的图例项
修正后的可运行代码:
# 提前固定随机种子,保证每次运行生成的配色一致,可按需修改种子数值 set.seed(123) # 取出数据集中所有的分类单元 all_taxa <- unique(df[[fill]]) # 生成带分类名命名的颜色向量,建立分类-颜色的固定映射 fill_colors <- setNames( sample(col_vector, size = length(all_taxa), replace = T), all_taxa ) ggplot(df, aes_string(x = x, y = y, fill = fill)) + geom_bar(stat = "identity", position = "stack") + scale_fill_manual( values = fill_colors, # 传入全量命名颜色映射,保证所有分类都有填充色 breaks = legend_list # 仅指定图例中要展示的目标分类 ) + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1))
如果需要更灵活调整图例参数,也可以把图例展示项的控制放到guides()层,效果完全等价:
ggplot(df, aes_string(x = x, y = y, fill = fill)) + geom_bar(stat = "identity", position = "stack") + scale_fill_manual(values = fill_colors) + # 单独控制填充图例的展示项 guides(fill = guide_legend(breaks = legend_list)) + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1))
注意事项
- 不要直接传入无命名的随机颜色向量,否则会出现颜色和分类错位、非图例分类无填充的问题
- 如果你的
col_vector长度小于全部分类的数量,记得给sample()加replace = T参数,避免采样报错
内容的提问来源于stack exchange,提问作者Max Qiu
相关产品推荐
相关产品推荐

