如何在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
相关产品推荐
相关产品推荐

