在ggplot单站点绘图中叠加组均值曲线的实现方法
解决方案:为每个站点绘制带组均值曲线的单独图形
首先咱们先把你的示例数据补全,确保能完整测试:
library(tidyverse) # 补全后的示例数据 tb <- tribble( ~x, ~y, ~group, ~site_name, ~site_id, 1, 1.2, 'a', 'aa', 1, 2, 1.4, 'a', 'ab', 2, 3, 1.6, 'a', 'ac', 3, 4, 1.8, 'a', 'aa', 1, 5, 2.0, 'a', 'ab', 2, 6, 2.2, 'a', 'ac', 3, 7, 1.9, 'a', 'aa', 1, 8, 1.7, 'a', 'ab', 2, 9, 1.5, 'a', 'ac', 3, # 补充b组数据让演示更全面 1, 0.8, 'b', 'ba', 4, 2, 1.0, 'b', 'bb', 5, 3, 1.2, 'b', 'bc', 6, 4, 1.4, 'b', 'ba', 4, 5, 1.6, 'b', 'bb', 5, 6, 1.8, 'b', 'bc', 6 )
接下来,咱们先计算组均值数据——也就是每个group下,对应x值的y的平均值,这是后续叠加曲线的基础:
# 计算组均值 group_mean <- tb %>% group_by(group, x) %>% summarise(mean_y = mean(y), .groups = "drop")
然后就可以写自定义函数啦!这个函数会接收你的数据框,为每个站点生成单独的图形,同时叠加对应组的均值曲线:
plot_site_with_group_mean <- function(data, group_mean_data) { # 按站点拆分数据 site_data_list <- split(data, data$site_id) # 为每个站点生成图形 site_plots <- map(site_data_list, function(site_df) { # 获取当前站点所属的组 current_group <- unique(site_df$group) # 筛选当前组的均值数据 current_group_mean <- filter(group_mean_data, group == current_group) # 绘制图形 ggplot(site_df, aes(x = x, y = y)) + geom_point(color = "#2c3e50", size = 2) + # 站点原始数据点 geom_line(color = "#e74c3c", linewidth = 1) + # 站点自身的曲线 geom_line(data = current_group_mean, aes(y = mean_y), color = "#3498db", linewidth = 1.2, linetype = "dashed") + # 组均值曲线 labs( title = paste("站点:", unique(site_df$site_name)), subtitle = paste("所属组:", current_group), x = "X值", y = "Y值" ) + theme_minimal() + theme(plot.title = element_text(face = "bold")) }) return(site_plots) }
现在调用这个函数就能得到所有站点的图形啦:
# 生成所有站点的图形 all_site_plots <- plot_site_with_group_mean(tb, group_mean) # 查看其中一个站点的图,比如站点aa(site_id=1) all_site_plots[["1"]]
如果你想把所有图形保存到本地,可以加个循环:
# 保存每个图形到本地 iwalk(all_site_plots, function(plot, site_id) { ggsave( filename = paste0("站点_", site_id, ".png"), plot = plot, width = 6, height = 4, dpi = 300 ) })
几个小说明:
- 我用了
tidyverse全家桶(dplyr、ggplot2、purrr),都是R数据处理和绘图的常用包,确保你已经安装并加载了它们 - 组均值曲线用了蓝色虚线,和站点自身的红色实线区分开,你可以根据需求调整颜色、线型这些参数
- 图形标题自动带上了站点名称和所属组,不用手动修改
内容的提问来源于stack exchange,提问作者kray
相关产品推荐
相关产品推荐

