用ggplot填充R中两条黄土平滑线之间的区域

Posted

技术标签:

【中文标题】用ggplot填充R中两条黄土平滑线之间的区域【英文标题】:Fill region between two loess-smoothed lines in R with ggplot 【发布时间】:2013-11-07 17:21:41 【问题描述】:

我想知道如何填充 ggplot 中黄土平滑线之间的区域。

图片使用以下数据框:

    x         y      ymin     ymax grp     ydiff
1   1  3.285614  3.285614 10.14177 min 6.8561586
2   1 10.141773  3.285614 10.14177 max 6.8561586
3   2  5.061879  5.061879 11.24462 min 6.1827368
4   2 11.244615  5.061879 11.24462 max 6.1827368
5   3  8.614408  8.614408 13.45030 min 4.8358931
6   3 13.450301  8.614408 13.45030 max 4.8358931
7   4  6.838143  6.838143 12.34746 min 5.5093150
8   4 12.347458  6.838143 12.34746 max 5.5093150
9   5 10.390673 10.390673 14.55314 min 4.1624713
10  5 14.553144 10.390673 14.55314 max 4.1624713
11  6 12.166937 12.166937 15.65599 min 3.4890495
12  6 15.655987 12.166937 15.65599 max 3.4890495
13  7 13.943202 13.943202 16.75883 min 2.8156277
14  7 16.758830 13.943202 16.75883 max 2.8156277
15  8  5.950011  5.950011 11.79604 min 5.8460259
16  8 11.796037  5.950011 11.79604 max 5.8460259
17  9 17.495731 17.495731 18.96452 min 1.4687841
18  9 18.964515 17.495731 18.96452 max 1.4687841
19 10 15.719466 15.719466 17.86167 min 2.1422059
20 10 17.861672 15.719466 17.86167 max 2.1422059
21 11 19.271996 19.271996 20.06736 min 0.7953623
22 11 20.067358 19.271996 20.06736 max 0.7953623

以下来源生成带有法线的图形(未平滑):

ggplot(intdf) + 
    geom_point(aes(x=x, y=y, colour=grp)) +
    geom_ribbon(aes(x=x, ymin=ymin, ymax=ymax), fill="grey", alpha=.4) +
    geom_line(aes(x=x, y=y, colour=grp))

其中 x 和 y 是连续数值。 ymin 和 ymax 分别包含位置 x 的绿线和红线的 y 值。

现在我想平滑线条。我只需使用以下代码即可:

ggplot(intdf) + 
    stat_smooth(aes(x=x, y=ymin, colour="min"), method="loess", se=FALSE) +
    stat_smooth(aes(x=x, y=ymax, colour="max"), method="loess", se=FALSE)

给出以下情节:

但我没有设法填充这两行之间的区域。我试图拟合一个黄土模型并使用预测值,但我想我完全使用了错误的预测器。

谁能告诉我如何填充平滑线之间的区域?

提前致谢 丹尼尔

【问题讨论】:

【参考方案1】:

从绘图对象中获取黄土平滑数据并用于geom_ribbon 的可能解决方案:

# create plot object with loess regression lines
g1 <- ggplot(df) + 
  stat_smooth(aes(x = x, y = ymin, colour = "min"), method = "loess", se = FALSE) +
  stat_smooth(aes(x = x, y = ymax, colour = "max"), method = "loess", se = FALSE)
g1

# build plot object for rendering 
gg1 <- ggplot_build(g1)

# extract data for the loess lines from the 'data' slot
df2 <- data.frame(x = gg1$data[[1]]$x,
                  ymin = gg1$data[[1]]$y,
                  ymax = gg1$data[[2]]$y) 

# use the loess data to add the 'ribbon' to plot 
g1 +
  geom_ribbon(data = df2, aes(x = x, ymin = ymin, ymax = ymax),
              fill = "grey", alpha = 0.4)

【讨论】:

这是一个非常好的解决方案,但在我的情况下,我有日期格式的 x 轴并且没有按预期工作。有没有其他选择? @Joy 感谢您的反馈。您可以考虑提出一个新问题。如果是这样,请注意How to ask:“即使您在网站的其他地方没有找到有用的答案,包括指向没有帮助的相关问题的链接也可以帮助其他人理解您的问题与其他人不同。”。祝你好运! 如果第一个情节是+ facet_wrap(~ some_group)怎么办?【参考方案2】:

本身不是答案,但如果您想运行 Henrik 的答案,可以先借用一些代码并运行。

library(tidyverse)

df <- tribble(
~row, ~x, ~y,    ~ymin,   ~ymax,  ~grp, ~ydiff,
1,   1,  3.285614,  3.285614, 10.14177, min, 6.8561586,
2,   1, 10.141773,  3.285614, 10.14177, max, 6.8561586,
3,   2,  5.061879,  5.061879, 11.24462, min, 6.1827368,
4,   2, 11.244615,  5.061879, 11.24462, max, 6.1827368,
5,   3,  8.614408,  8.614408, 13.45030, min, 4.8358931,
6,   3, 13.450301,  8.614408, 13.45030, max, 4.8358931,
7,   4,  6.838143,  6.838143, 12.34746, min, 5.5093150,
8,   4, 12.347458,  6.838143, 12.34746, max, 5.5093150,
9,   5, 10.390673, 10.390673, 14.55314, min, 4.1624713,
10,  5, 14.553144, 10.390673, 14.55314, max, 4.1624713,
11,  6, 12.166937, 12.166937, 15.65599, min, 3.4890495,
12,  6, 15.655987, 12.166937, 15.65599, max, 3.4890495,
13,  7, 13.943202, 13.943202, 16.75883, min, 2.8156277,
14,  7, 16.758830, 13.943202, 16.75883, max, 2.8156277,
15,  8,  5.950011,  5.950011, 11.79604, min, 5.8460259,
16,  8, 11.796037,  5.950011, 11.79604, max, 5.8460259,
17,  9, 17.495731, 17.495731, 18.96452, min, 1.4687841,
18,  9, 18.964515, 17.495731, 18.96452, max, 1.4687841,
19, 10, 15.719466, 15.719466, 17.86167, min, 2.1422059,
20, 10, 17.861672, 15.719466, 17.86167, max, 2.1422059,
21, 11, 19.271996, 19.271996, 20.06736, min, 0.7953623,
22, 11, 20.067358, 19.271996, 20.06736, max, 0.7953623
)

【讨论】:

以上是关于用ggplot填充R中两条黄土平滑线之间的区域的主要内容,如果未能解决你的问题,请参考以下文章

将平滑线添加到绘图图表

向 ggplot 添加自定义范围 ab/平滑线

ggplot2:面内几个线图的单个平滑线

r ggplot时间序列,方面,黄土和日期

在 R 中使用负值在 3d 黄土平滑上设置上限为 0

将acspline与数据填充曲线相结合