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

如何在ggplot2中结合geom_function与facet_wrap分面绘制多组分布

解决ggplot2分面后geom_function重复绘制曲线的问题

问题根源

geom_function()默认不会自动根据分面(centralYear)或分组(generation)筛选数据,函数中引用的mu/sigma/lambda会读取整个数据框的列向量,而非当前分面/分组对应的单个参数值,导致每个分面重复绘制所有分组的曲线。

可行解决方案

推荐采用提前生成各分组曲线数据的方式,完全贴合ggplot2的数据驱动逻辑,彻底避免参数传递问题。

步骤1:准备测试数据(模拟用户场景)

set.seed(123)
library(tidyverse)

test_data <- expand.grid(centralYear = c(2020, 2021, 2022),
                         generation = c("G1", "G2", "G3")) %>%
  mutate(mu = rnorm(n(), mean = centralYear, sd = 1),
         sigma = runif(n(), min = 0.5, max = 1.5),
         lambda = runif(n(), min = 0.8, max = 1.2))

步骤2:生成各分组的曲线数据

针对每个centralYear+generation组合,生成对应的正态分布曲线点数据:

curve_data <- test_data %>%
  group_by(centralYear, generation, mu, sigma, lambda) %>%
  group_modify(
    ~ tibble(x = seq(.x$mu - 3*.x$sigma, .x$mu + 3*.x$sigma, length.out = 100)) %>%
      mutate(y = .x$lambda * dnorm(x, mean = .x$mu, sd = .x$sigma))
  ) %>%
  ungroup()

步骤3:绘制分面曲线

用geom_line()直接读取预先生成的曲线数据,分面和分组会自动生效:

ggplot(curve_data, aes(x = x, y = y, color = generation)) +
  geom_line(linewidth = 1) +
  facet_wrap(~centralYear, scales = "free_x") +
  labs(x = "数值", y = "加权密度") +
  theme_bw()

替代方案(修复geom_function用法)

如果坚持使用geom_function(),需通过stat_function()配合分组参数传递,确保每个分组调用对应参数:

ggplot(test_data, aes(
  x = x,
  color = generation,
  group = interaction(centralYear, generation)
)) +
  stat_function(
    fun = function(x, mu, sigma, lambda) lambda * dnorm(x, mu, sigma),
    args = pmap(test_data, list),
    n = 100
  ) +
  facet_wrap(~centralYear) +
  labs(x = "数值", y = "加权密度")

注:此方法依赖purrr::pmap将每行参数打包传递,不如预生成曲线数据直观稳定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 02:15:35