oibaFox
oibaFox

Reputation: 141

How to add area between two lines in ggplot

I am working on R, using ggplot2. I would like to color the area between two lines: the OLS fit line and a line passing through the intercept.

Obviously, I could create many points on the two curves and fill the space between them with geom_ribbon, but I would like to know if it is possible to have a solution relying on a parametrical definition of the two curves, for simplicity.

MWE:

test <- data.frame(x=c(1,2,3),y=c(1.2,1.4,1.1)) 

ggplot(test, aes(x,y))+
  geom_smooth(method = "lm", fill = NA, fullrange = T, color="green") +
  geom_point()+
  geom_abline(intercept=0, slope=1.5, col = "red") +
  coord_cartesian(xlim = c(0,4),ylim = c(0,4))

Can I color the area between the green and the red lines?

Upvotes: 0

Views: 797

Answers (1)

teunbrand
teunbrand

Reputation: 37933

I'm not quite sure what exactly is meant with the analytical definition of the curves and what would and would not satisfy that criterion, but I found a not so cumbersome solution using geom_ribbon anyway.

The following works when your second line goes through the origin and has a 45 degree angle and hence y = x. Should be quite agnostic to what method argument is supplied to the geom/stat_smooth though. The trick is to combine the geom_ribbon with the same stat function as used in the geom_smooth.

ggplot(test, aes(x,y))+
  geom_smooth(method = "lm", fill = NA, fullrange = T, color="green") +
  geom_line(data=data.frame(x=c(0,7),y=c(0,7)), col = "red") +
  geom_ribbon(aes(ymin = stat(y), ymax = stat(x)), 
              stat = "smooth", method = "lm", fullrange = T,
              fill = "dodgerblue") +
  geom_point()+
  coord_cartesian(xlim = c(0,4),ylim = c(0,4))

enter image description here

Edit:

For any line that passes through the origin and can be described by 'y = a + bx' you could substitute ymax = stat(x) by ymax = a + b * stat(x), e.g:

a <- -1
b <- 2

ggplot(test, aes(x,y))+
  geom_smooth(method = "lm", fill = NA, fullrange = T, color="green") +
  geom_line(data=data.frame(x=c(0,7),y=c(0,7)), col = "red") +
  geom_ribbon(aes(ymin = stat(y), ymax = a + b * stat(x)), 
              stat = "smooth", method = "lm", fullrange = T,
              fill = "dodgerblue") +
  geom_point()+
  coord_cartesian(xlim = c(0,4),ylim = c(0,4))

Upvotes: 1

Related Questions