R ggplot2实现facet_wrap子图独立图例、R²及斜率值展示方法
解决方案
要实现你的两个需求,因为ggplot2原生分面不支持每个子图独立图例,我们采用「按id拆分数据单独绘图+patchwork拼接」的方案实现,具体代码如下:
首先需要安装加载依赖包:
# 未安装的话先执行 install.packages(c("tidyverse", "patchwork", "ggpmisc")) library(tidyverse) library(patchwork) library(ggpmisc)
绘图代码:
# 按id拆分数据集,逐个生成子图 plot_list <- low_rd %>% group_split(id) %>% map(function(df) { # 提取当前id包含的所有source类别 valid_source <- unique(df$source) ggplot(df, aes(x = x, y = y)) + geom_point(aes(color = factor(source))) + # 全局深蓝色回归线,不进入图例 geom_smooth(method = "lm", se = FALSE, color = "darkblue", show.legend = FALSE) + # 按source分组的回归线 geom_smooth(method = "lm", aes(color = factor(source)), se = FALSE) + # 添加全局回归的R²和斜率值,标签位置默认右上角 stat_poly_eq(use_label(c("R2", "slope")), label.x = "right", label.y = "top", digits = 2) + # 调整图例位置到子图右上角,缩小尺寸适配子图 theme( legend.position = c(0.92, 0.92), legend.justification = c("right", "top"), legend.key.size = unit(0.4, "cm"), legend.title = element_text(size = 8), legend.text = element_text(size = 7) ) + # 强制图例仅展示当前id的source类别 scale_color_discrete(name = "source", limits = valid_source) }) # 拼接所有子图,按3列排布,可按需调整ncol参数 wrap_plots(plot_list, ncol = 3, axis_titles = "collect")
代码说明
- 按id拆分数据后逐个绘图,每个子图的图例天然只会包含当前id对应的source类别,完全符合需求1
stat_poly_eq默认基于全图数据计算回归统计值,正好对应你需要的全局回归R²和斜率,可通过digits参数调整显示精度- 图例位置通过相对坐标调整,
c(0.92,0.92)对应子图区域的右上角,不会遮挡数据点和拟合线 - 最终拼接时设置
axis_titles = "collect"可以统一显示坐标轴标题,避免重复冗余
内容的提问来源于stack exchange,提问作者AP_98
相关产品推荐
相关产品推荐

