5

I am trying to get a geom_area to have twin colours dependant on value of Y axis.

So for example if we have a geom_area with a max X value of 50, I would like the fill colour to be blue when below 10 and red when above 10.

Sample Data;

df <- data.frame(
  y = sample(1:50),
  x = sample(1:50)
)

The closest that I have managed to get thus far is by using the following code;

ggplot(data = df, aes(x = x)) + 
  geom_area(aes(y = y),fill = "red") +
  geom_ribbon(aes(ymin = 0, ymax = ifelse(y >= 10,10,y)),fill = "blue")

This almost gets me what I require however the problem is that the horizontal split is not completely across the geom_area, as when the next value falls below the max value the edge of the ribbon goes straight to the next point, which upsets the split.

SamplePlot

This is plotting exactly what the code tells it, so I must be using the wrong method to create the split in colours, but cannot figure out how to do it correctly.

zx8754
  • 52,746
  • 12
  • 114
  • 209
redbaron1981
  • 407
  • 3
  • 9
  • [This question/answer](http://stackoverflow.com/questions/17959817/filling-area-under-curve-based-on-value-in-ggplot2) might be helpful – aosmith Mar 30 '17 at 21:33

1 Answers1

4

A quick fix would be to interpolate between the x-values using approx. Set the n argument (the number of interpolation points) to a high-enough value to get blue all the way across:

ggplot(data = as.data.frame(approx(df,n=1000)), aes(x = x)) + 
  geom_area(aes(y = y),fill = "red") +
  geom_ribbon(aes(ymin = 0, ymax = ifelse(y >= 10,10,y)),fill = "blue") +
  theme_classic()

enter image description here

eipi10
  • 91,525
  • 24
  • 209
  • 285
  • This is actually quite close to what I need however, I think I may have a better idea.I should be able to subset the observations to where the Y value crosses the horizontal level. Once I have two points I can then calculate the slope and the intercept. Then I can use the intercept values on geom_ribbon to have the correct fill. Not entirely sure of a good way to go about this or if it will work so any suggestions will be gladly appreciated. – redbaron1981 Apr 01 '17 at 21:53
  • 1
    The linked answer in @aosmith's comment has code for doing that. – eipi10 Apr 01 '17 at 22:08