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

如何使用stat_summary在ggplot2多面板密度图中添加均值竖线

解决ggplot多面板密度图添加分组均值竖线的问题

正确实现代码(stat_summary方式)

使用stat_summary时,需要通过after_stat(x)获取计算后的均值,并为geom_vline指定y方向范围,确保竖线覆盖密度图的高度:

set.seed(42)
library(tidyverse)

data_frame(site = rep(LETTERS[1:4], each = 25),
           sex = rep(c("f", "m"), 50),
           mass = rnorm(100, 50, 5)) %>% 
  ggplot(aes(x = mass, col = sex)) +
  geom_density() +
  stat_summary(
    fun = mean,
    geom = "vline",
    aes(xintercept = after_stat(x)),  # 提取stat_summary计算出的均值
    yintercept = 0, yend = Inf,       # 竖线从底部延伸到顶部
    linetype = "dashed"               # 可选:用虚线区分均值线和密度曲线
  ) +
  facet_wrap(~site)

另一种直观方法(提前计算均值)

先按site和sex分组计算均值,再用geom_vline直接添加,逻辑更清晰:

set.seed(42)
library(tidyverse)

# 预处理:计算每个分组的均值
mean_df <- data_frame(site = rep(LETTERS[1:4], each = 25),
                      sex = rep(c("f", "m"), 50),
                      mass = rnorm(100, 50, 5)) %>% 
  group_by(site, sex) %>% 
  summarise(mean_mass = mean(mass), .groups = "drop")

# 绘图
data_frame(site = rep(LETTERS[1:4], each = 25),
           sex = rep(c("f", "m"), 50),
           mass = rnorm(100, 50, 5)) %>% 
  ggplot(aes(x = mass, col = sex)) +
  geom_density() +
  geom_vline(data = mean_df, aes(xintercept = mean_mass, col = sex),
             linetype = "dashed") +
  facet_wrap(~site)

之前错误的原因解析

  1. 第一次尝试:stat_summary搭配geom_vline时,既没指定xintercept的来源(需要映射计算后的均值),也没给geom_vline设置y方向范围,导致报错缺少y美学。
  2. 第二次尝试:添加y=0但未正确映射xintercept,geom_vline必须明确xintercept参数,而这里需要用stat_summary生成的统计值,不是原始数据。
  3. 第三次尝试:直接将xintercept映射到原始数据的mass字段,导致每个数据点都生成一条竖线,而非分组计算后的均值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 16:52:32