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

如何绘制不同组分箱值占比图且不堆叠?

实现非堆叠的密度占比图(基线从0开始)

你需要的是将各组的密度占比归一化后,从y=0基线开始绘制而非堆叠,这样能直接对比同一x值下不同组的占比高低。以下是两种可行的实现方法:

方法1:手动预处理数据计算占比

先单独计算每个组的密度,对齐x轴点位后计算各组在每个x点的占比,再用geom_area绘制非堆叠图形:

library(ggplot2)
library(dplyr)
library(purrr)

set.seed(200)
df <- data.frame(
  value = c(rnorm(100, 0, 1), rnorm(100, 0, 2), rnorm(100, 1, 2)),
  group = rep(c("A", "B", "C"), each = 100)
)

# 按组计算密度
density_list <- df %>%
  split(.$group) %>%
  map(~density(.$value, n = 200)) # n参数控制x轴采样点数,可按需调整

# 转换为统一格式的数据框
density_df <- map_dfr(density_list, ~data.frame(x = .$x, density = .$y), .id = "group")

# 计算每个x点的组占比:当前组密度 / 该x点所有组密度总和
density_df <- density_df %>%
  group_by(x) %>%
  mutate(percent = density / sum(density)) %>%
  ungroup()

# 绘制非堆叠面积图
ggplot(density_df, aes(x = x, y = percent, fill = group)) +
  geom_area(alpha = 0.5, position = "identity") +
  labs(y = "占比", x = "value", title = "非堆叠密度占比图") +
  theme_minimal()

方法2:用stat_density直接计算占比

利用ggplot的after_stat函数,在统计密度后直接归一化计算占比,无需提前处理数据:

library(ggplot2)

set.seed(200)
df <- data.frame(
  value = c(rnorm(100, 0, 1), rnorm(100, 0, 2), rnorm(100, 1, 2)),
  group = rep(c("A", "B", "C"), each = 100)
)

ggplot(df, aes(x = value, fill = group)) +
  stat_density(
    aes(y = after_stat(density / sum(density))),
    position = "identity", # 关键:关闭堆叠,从0基线绘制
    alpha = 0.5,
    geom = "area"
  ) +
  labs(y = "占比", x = "value", title = "非堆叠密度占比图") +
  theme_minimal()

两种方法的效果一致:每个组的面积/曲线都从y=0开始,同一x值对应的y值就是该组的占比,能直观对比各组在不同x位置的占比高低。

内容的提问来源于stack exchange,提问作者Nikolas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 05:07:29