Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fill region between two loess-smoothed lines in R with ggplot

Tags:

I'd like to know how to fill the area between to loess-smoothed lines in ggplot.

The following data frame is used for the pictures:

    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 

Following source produces a figure with normal lines (not smoothed):

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)) 

where x and y are continuous numeric values. ymin and ymax each contain the y-values from the green and red line at position x.

Two normal geom_line lines with geom_ribbon filled area

Now I'd like to smoothen the lines. I simply do this with following code:

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) 

which gives following plot:

Two smoothed lines without filled region

But I did not manage to fill the area between these two lines. I tried to fit a loess-model and use the predicted values, but I guess I completely used the wrong predictors.

Who could tell me how to fill the region between the smoothed lines?

Thanks in advance Daniel

like image 250
Daniel Avatar asked Oct 28 '13 19:10

Daniel


People also ask

How do you add a smooth line to a scatter plot in R?

We can better visualize the relationship by adding a straight regression line (linear) or a smoothed curve to the scatter plot. In R, the smoothed curve can be estimated using the loess. smooth() function or we can generate the plot using the scatter. smooth() function directly.

What does Geom_smooth do in Ggplot?

The geom smooth function is a function for the ggplot2 visualization package in R. Essentially, geom_smooth() adds a trend line over an existing plot.

How do I smooth a Geom line?

Method 1: Using “loess” method of geom_smooth() function We can plot a smooth line using the “loess” method of the geom_smooth() function. The only difference, in this case, is that we have passed method=loess, unlike lm in the previous case.

What does the SE argument to Geom_smooth () do?

se Display confidence interval around smooth (TRUE by default, see level to control.)


1 Answers

A possible solution where the loess smoothed data is grabbed from the plot object and used for the 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) 

enter image description here

like image 200
Henrik Avatar answered Sep 28 '22 09:09

Henrik