You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用渐变填充时如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 21:18:16