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
相关产品推荐
相关产品推荐

