使用渐变填充时如何在ggplot2绘图中区分不同分组?
解决思路与实现代码
要同时保留密度渐变填充和组别区分,我们可以通过以下几种方式解决fill映射的冲突问题:
方案一:用边框颜色区分组别,填充色表示密度
这种方法无需额外依赖包,通过color映射type组别,fill继续映射密度值,直观简洁:
library(tidyverse) set.seed(100) n <- 100 df <- data.frame(a=rnorm(n, mean=5, sd=1), b=rnorm(n, mean=10, sd=2), c=rnorm(n, mean=15, sd=3)) %>% pivot_longer(everything(), names_to = "group", values_to = "value") %>% mutate(group = factor(group), type = as.character(rbinom(seq(nrow(.)), 1, 0.5))) ggplot() + stat_ydensity(data = df, aes(x = group, y = value, fill = after_stat(density), color = type, # 边框颜色映射组别 xmin = stat(x) - 0.2, xmax = stat(x) + 0.2, ymin = stat(y) - 0.05, ymax = stat(y) + 0.05), geom = "rect", trim = TRUE, size = 0.3) + # 调整边框粗细增强辨识度 scale_fill_viridis_c(name = "密度") + scale_color_manual(values = c("0" = "darkred", "1" = "darkblue"), name = "类型") + theme_minimal()
方案二:用不同渐变调色板区分组别
如果希望填充色本身就能区分组别,可以借助ggnewscale包添加多组填充比例尺,为每个type设置独立的渐变色系,同时调整x轴位置避免重叠:
首先安装依赖包:
install.packages("ggnewscale")
然后运行绘图代码:
library(tidyverse) library(ggnewscale) set.seed(100) n <- 100 df <- data.frame(a=rnorm(n, mean=5, sd=1), b=rnorm(n, mean=10, sd=2), c=rnorm(n, mean=15, sd=3)) %>% pivot_longer(everything(), names_to = "group", values_to = "value") %>% mutate(group = factor(group), type = as.character(rbinom(seq(nrow(.)), 1, 0.5))) ggplot() + # 绘制type=0组,蓝色系渐变 stat_ydensity(data = filter(df, type == "0"), aes(x = group, y = value, fill = after_stat(density), xmin = stat(x) - 0.18, xmax = stat(x), # 左偏移避免重叠 ymin = stat(y) - 0.05, ymax = stat(y) + 0.05), geom = "rect", trim = TRUE) + scale_fill_viridis_c(limits = range(df$value), name = "密度(type=0)", option = "mako") + # 启动新的填充比例尺 new_scale_fill() + # 绘制type=1组,红色系渐变 stat_ydensity(data = filter(df, type == "1"), aes(x = group, y = value, fill = after_stat(density), xmin = stat(x), xmax = stat(x) + 0.18, # 右偏移避免重叠 ymin = stat(y) - 0.05, ymax = stat(y) + 0.05), geom = "rect", trim = TRUE) + scale_fill_viridis_c(limits = range(df$value), name = "密度(type=1)", option = "inferno") + theme_minimal()
方案三:用透明度区分组别(备选)
如果对颜色区分要求不高,也可以通过alpha映射type来区分组别,保留fill的密度渐变:
ggplot() + stat_ydensity(data = df, aes(x = group, y = value, fill = after_stat(density), alpha = type, xmin = stat(x) - 0.2, xmax = stat(x) + 0.2, ymin = stat(y) - 0.05, ymax = stat(y) + 0.05), geom = "rect", trim = TRUE) + scale_fill_viridis_c(name = "密度") + scale_alpha_manual(values = c("0" = 0.7, "1" = 1), name = "类型") + theme_minimal()
内容的提问来源于stack exchange,提问作者Jaken
相关产品推荐
相关产品推荐

