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

如何从带阴影区域的ggplot对象提取Loess曲线边界坐标及了解其内部结构?

问题描述

给定如下ggplot2绘图代码:

library(ggplot2)
library(gcookbook)   # heightweight data set is from gcookbook

# Two loess lines, one for males and for females; factor is in aes():
ggplot(data = heightweight, aes(x = ageYear, y = heightIn, color = sex)) +
  theme_bw() +
  # females with Venus symbol in red, males with Mars symbol in blue:
  geom_point( shape = if_else(heightweight$sex=="f", "♀", "♂"),
              size = 3,
              color = if_else(heightweight$sex=="f", "red", "blue")) +
  geom_smooth() -> p

需求是从绘图对象p中提取6组(x,y)坐标:

  • 女性Loess拟合曲线的坐标
  • 女性拟合曲线的上置信边界坐标
  • 女性拟合曲线的下置信边界坐标
  • 男性Loess拟合曲线的坐标
  • 男性拟合曲线的上置信边界坐标
  • 男性拟合曲线的下置信边界坐标

直接用str(p)查看对象结构时内容过于复杂,无法明确提取路径,比如不知道如何写出类似p.Loess.F.upper <- p$<..>的正确代码。同时想了解:是否有关于ggplot对象内部元素的详细说明?或其他类似非ggplot绘图对象的相关说明?


解决方案

一、提取Loess曲线及置信边界的坐标

ggplot对象的绘图数据可以通过官方提供的ggplot_build()函数提取,它会把绘图所需的所有计算后的数据整理成结构化列表:

  1. 先将ggplot对象转为构建后的对象:
p_build <- ggplot_build(p)
  1. 查看p_build的核心结构,其中data元素包含所有图层的计算数据:
str(p_build$data)

p_build$data是一个列表,每个元素对应一个图层:

  • 索引1对应geom_point的散点数据
  • 索引2对应geom_smooth的Loess拟合及置信区间数据
  1. 提取geom_smooth的计算数据:
smooth_data <- p_build$data[[2]]

这个数据框包含关键列:

  • x:年龄(ageYear)
  • y:拟合身高(Loess曲线值)
  • ymin:下置信边界
  • ymax:上置信边界
  • colour:分组颜色(红色对应女性,蓝色对应男性)
  1. 拆分出男女对应的6组数据:
# 女性相关数据
female_fit <- subset(smooth_data, colour == "red", select = c(x, y))
female_upper <- subset(smooth_data, colour == "red", select = c(x, ymax))
female_lower <- subset(smooth_data, colour == "red", select = c(x, ymin))

# 男性相关数据
male_fit <- subset(smooth_data, colour == "blue", select = c(x, y))
male_upper <- subset(smooth_data, colour == "blue", select = c(x, ymax))
male_lower <- subset(smooth_data, colour == "blue", select = c(x, ymin))

二、关于绘图对象内部结构的说明

  1. ggplot对象的内部结构:ggplot2官方并未详细公开对象的底层私有结构,因为这些属于实现细节,可能随版本更新发生变化,不建议直接通过p$xxx的方式访问。推荐使用ggplot_build()、ggplot_gtable()这类官方工具函数来提取数据或修改绘图元素。

  2. 非ggplot绘图对象的参考:对于基础绘图(base plot)生成的对象,其内部结构同样属于底层实现,没有统一的公开详细文档。通常可以用str()查看结构,或用recordPlot()捕获绘图状态后分析,但这类操作依赖具体版本,稳定性较差。

  3. 更可控的替代思路:如果只是需要Loess拟合结果,完全可以不依赖ggplot对象,直接用loess()函数手动拟合并计算置信区间,这种方式更灵活:

# 手动拟合女性Loess曲线
loess_female <- loess(heightIn ~ ageYear, data = subset(heightweight, sex == "f"))
# 生成预测序列
x_seq <- seq(min(heightweight$ageYear), max(heightweight$ageYear), length.out = 100)
female_pred <- predict(loess_female, newdata = data.frame(ageYear = x_seq), se = TRUE)
# 提取拟合值和置信边界
female_fit_manual <- data.frame(x = x_seq, y = female_pred$fit)
female_upper_manual <- data.frame(x = x_seq, y = female_pred$fit + 1.96*female_pred$se.fit)
female_lower_manual <- data.frame(x = x_seq, y = female_pred$fit - 1.96*female_pred$se.fit)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 03:34:52