ggplot绘制核密度图时如何让对应分组填充色保持一致
修改ggplot核密度图填充色、实现跨图颜色匹配的方法
两张图同语义分组颜色不统一的核心原因是:ggplot的离散填充色默认按照因子本身的水平顺序映射,仅通过breaks调整图例显示顺序和标签,不会改变颜色和分组值的绑定关系,最终导致语义相同的分组匹配到了不同颜色。
以下两种方法都可以实现需求:
方法1:手动指定固定配色映射(最稳妥)
直接给两张图的每个分组值绑定固定色值,不管因子顺序、图例顺序怎么调整,颜色都不会错位,是最推荐的方案。
可以直接沿用ggplot默认离散色板的基础色保证风格统一:
- 非重新分配组(第一张的「Will not reallocate」、第二张的「Did not reallocate」)统一用
#F8766D(默认色板第一色) - 重新分配组(第一张的「Will reallocate」、第二张的「Reallocated」)统一用
#00BFC4(默认色板第二色)
把原来的scale_fill_discrete替换为scale_fill_manual即可,修改后的完整代码:
library(ggplot2) N = 10000 totalinc_02 <- rnorm(N) totalinc_04 <- rnorm(N) remained_agri <- rbinom(n = N, size = 1, prob = 0.05) reallocated_manu <- rbinom(n = N, size = 1, prob = 0.05) inc0204_p_agri <- data.frame(totalinc_02 , totalinc_04 , remained_agri, reallocated_manu) # 绘制2001年收入核密度图 ggplot(inc0204_p_agri, aes(log(totalinc_02), fill = factor(remained_agri))) + geom_density(alpha = 0.2) + labs(x = "(log) Annual Income in 2001", y = "Density") + scale_fill_manual(name="", breaks=c("1", "0"), labels=c("Will not reallocate", "Will reallocate"), values = c("1" = "#F8766D", "0" = "#00BFC4")) # 手动绑定分组值和对应颜色 # 绘制2003年收入核密度图 ggplot(inc0204_p_agri, aes(log(totalinc_04), fill = factor(reallocated_manu))) + geom_density(alpha = 0.2) + labs(x = "(log) Annual Income in 2003", y = "Density") + scale_fill_manual(name="", breaks=c("0", "1"), labels=c("Did not reallocate", "Reallocated"), values = c("0" = "#F8766D", "1" = "#00BFC4")) # 同语义分组保持色值一致
如果需要自定义配色,只要把values里的色值替换为目标颜色即可,两张图保持对应关系就行。
方法2:提前统一因子水平(代码更简洁)
如果不想手动配置色值,可以提前把两个分组变量转为因子,让相同语义的分组对应相同的因子水平顺序,ggplot会自动给同水平的分配置相同颜色。
代码示例:
# 提前统一两个分组的因子水平和标签 inc0204_p_agri$remained_agri <- factor( inc0204_p_agri$remained_agri, levels = c(1, 0), labels = c("Non-reallocated", "Reallocated") ) inc0204_p_agri$reallocated_manu <- factor( inc0204_p_agri$reallocated_manu, levels = c(0, 1), labels = c("Non-reallocated", "Reallocated") ) # 直接绘图即可,同标签分组自动匹配相同颜色 ggplot(inc0204_p_agri, aes(log(totalinc_02), fill = remained_agri)) + geom_density(alpha = 0.2) + labs(x = "(log) Annual Income in 2001", y = "Density") + scale_fill_discrete(name = "") ggplot(inc0204_p_agri, aes(log(totalinc_04), fill = reallocated_manu)) + geom_density(alpha = 0.2) + labs(x = "(log) Annual Income in 2003", y = "Density") + scale_fill_discrete(name = "")
两种方法输出效果完全一致:手动指定配色的方式灵活性更高,适合需要严格统一视觉规范的场景;提前处理因子的方式代码更简洁,适合快速探索数据、批量出图的场景。
内容的提问来源于stack exchange,提问作者anrisakaki96
相关产品推荐
相关产品推荐

