如何为ggMarginal()边际密度图添加均值或中位数线?
给ggExtra边际密度图添加均值/中位数线的方法
确实ggMarginal()没有内置参数来添加这类统计量线条,不过可以通过操作它生成的gtable对象手动添加,步骤如下:
1. 准备环境与示例数据
先加载所需包并构造可复现的示例数据(替换成你的实际数据即可):
library(ggplot2) library(ggExtra) library(gtable) library(grid) library(dplyr) # 用于统计量计算 # 构造示例数据 set.seed(123) my.data <- data.frame( det = c(rnorm(100, mean = 5), rnorm(100, mean = 8)), res = c(rnorm(100, mean = 2), rnorm(100, mean = 4)), data.type = rep(c("A", "B"), each = 100) )
2. 绘制基础散点图与边际密度图
先生成基础散点图,再用ggMarginal()添加边际密度图,得到gtable对象:
# 基础散点图 p <- ggplot(aes(x=det, y=res, fill=data.type, color=data.type), data=my.data) + geom_point() + scale_fill_manual(values=c("firebrick1", "deepskyblue4"))+ scale_color_manual(values=c("firebrick1", "deepskyblue4"))+ guides(fill=guide_legend(byrow = TRUE)) # 添加边际密度图,返回gtable对象 g <- ggMarginal(p, groupFill = TRUE)
3. 计算各组统计量
提前算出x轴(det)和y轴(res)的均值、中位数:
# x轴变量的各组统计量 x_stats <- my.data %>% group_by(data.type) %>% summarise( mean_val = mean(det), median_val = median(det) ) # y轴变量的各组统计量 y_stats <- my.data %>% group_by(data.type) %>% summarise( mean_val = mean(res), median_val = median(res) )
4. 给顶部边际图添加线条
顶部边际图对应x轴的密度分布,添加垂直的均值/中位数线:
# 提取顶部边际图的grob组件 top_grob <- g$grobs[[which(g$layout$name == "top")]] # 添加均值线(虚线)和中位数线(实线) top_grob <- top_grob + geom_vline(data = x_stats, aes(xintercept = mean_val, color = data.type), linetype = "dashed", linewidth = 1) + geom_vline(data = x_stats, aes(xintercept = median_val, color = data.type), linewidth = 1) # 更新gtable中的顶部组件 g$grobs[[which(g$layout$name == "top")]] <- top_grob
5. 给右侧边际图添加线条
右侧边际图对应y轴的密度分布,添加水平的均值/中位数线:
# 提取右侧边际图的grob组件 right_grob <- g$grobs[[which(g$layout$name == "right")]] # 添加均值线(虚线)和中位数线(实线) right_grob <- right_grob + geom_hline(data = y_stats, aes(yintercept = mean_val, color = data.type), linetype = "dashed", linewidth = 1) + geom_hline(data = y_stats, aes(yintercept = median_val, color = data.type), linewidth = 1) # 更新gtable中的右侧组件 g$grobs[[which(g$layout$name == "right")]] <- right_grob
6. 展示最终图形
用grid.draw()渲染修改后的gtable对象:
grid.draw(g)
额外说明
- 可以根据需求调整线条的
linetype(线型)、linewidth(线宽)、颜色等参数; - 如果只需要均值或中位数,删掉对应的
geom_vline/geom_hline代码即可; - 若你的边际图是直方图而非密度图,同样适用此方法,只需保持线条类型匹配(垂直/水平)。
内容的提问来源于stack exchange,提问作者Alexander Grimaudo
相关产品推荐
相关产品推荐

