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

ggplot2中geom_area绘制AUC阴影:移除xlim后图形异常的原因

ggplot2中移除xlim参数后geom_area绘制AUC图形异常的原因与解决办法

我尝试用ggplot2的geom_area()绘制AUC(曲线下面积),使用的代码如下:

set.seed(1234)
df <- data.frame(
  sex=factor(rep(c("F", "M"), each=200)),
  weight=round(c(rnorm(200, mean=55, sd=5),
             rnorm(200, mean=65, sd=5)))
 )
dat <- with(density(df$weight), data.frame(x, y))
ggplot(data = dat, mapping = aes(x = x, y = y)) +
 geom_line()+
    geom_area(mapping = aes(x = ifelse(x>65 & x< 70 , x, 0)), fill = "red") +
    xlim(30, 80)

疑问:移除xlim(30, 80)参数后,生成的图形会出现明显差异,这是为什么?

原因解释

核心问题在于ggplot2的图层绘制顺序与xlim()的作用机制:

  • xlim()并不是提前筛选数据,而是在所有图层绘制完成后,对图形的可视范围进行裁剪。
  • 当你移除xlim(30,80)时,dat中由密度函数生成的x值范围远大于30-80(会覆盖从远低于30到远高于80的区间)。而你在geom_area的x映射里用了ifelse(x>65 & x<70, x, 0),这会让所有不在65-70区间的x被设为0,这些大量x=0的点会和65-70区间的点连接,导致图形错误填充了从x=0到x=65的区域。
  • 加上xlim(30,80)时,x=0的部分被裁剪掉,所以看起来图形正常。

解决方法

正确的思路是提前对geom_area用到的数据进行子集筛选,而非依赖可视范围裁剪。注意原代码中dat$weight是笔误(dat仅包含x和y列),修正后的可行代码如下:

ggplot(data = dat, mapping = aes(x = x, y = y)) +
  geom_line()+
  geom_area(data = dat[dat$x > 30,] , # 提前筛选geom_area用到的数据
mapping = aes(x = ifelse(x>65 & x< 70 , x, 0)), fill = "red") +
  xlim(30, 80)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 05:52:38