Reputation: 1707
I have the following simple line graph with ribbons denoting thresholds of interest along the y-axis.
library(ggplot2)
main.df <- data.frame(time = c(1:20, 1:20),
level = runif(40),
type = c(rep('A', 20), rep('B', 20)))
gg <- ggplot(main.df, aes(x = time, y = level, colour = type))
gg + geom_ribbon(ymin = 0.1, ymax = 0.25, fill = 'green') +
geom_ribbon(ymin = 0.25, ymax = 0.5, fill = 'yellow') +
geom_ribbon(ymin = 0.5, ymax = 0.95, fill = 'red') +
geom_line()
I have made many attempts to set the data
property of geom_ribbon
to give me more flexibility and clean up my code. Here is one such example.
rib.df <- data.frame(low = c(0.1, 0.25, 0.5), high = c(0.25, 0.50, 0.95),
lab = c('green', 'yellow', 'red'))
gg + geom_ribbon(data = rib.df,
aes(ymin = low, ymax = high, fill = lab),
inherit.aes=FALSE) + geom_line()
This particular one has the error that the aesthetic x is missing. Which interestingly was not a problem in the prior example. I have tried setting the x and y in it seems every combination of inside the aes
and not. I am also unclear as to why sometimes the geom_ribbon
wants a y
when it is not a required aesthetic.
My question in summary: how to call geom_ribbon
setting the data
argument to achieve a result similar to the above manual calls?
I will also be glad to learn about efficient ways to achieve a similar visual result using other geom
s.
Upvotes: 1
Views: 3147
Reputation: 145775
I would do it like this:
rib2 = rbind(rib.df, rib.df)
rib2$x = rep(c(-Inf, Inf), each = nrow(rib.df))
gg + geom_ribbon(data = rib2,
aes(x = x, ymin = low, ymax = high, fill = lab),
inherit.aes=FALSE) +
geom_line()
Ribbons are made to have ymin and ymax values that change for various x values. In this case where you're just drawing rectangles, you could simplify by using geom_rect
, in which case you could set xmin = -Inf, xmax = Inf
outside of aes()
and use the rib.df
from your question. This way you don't have to double the data to show the ymin and ymax are the same at the min and max x values.
gg + geom_rect(data = rib.df,
aes(ymin = low, ymax = high, fill = lab),
xmin = -Inf, xmax = Inf,
inherit.aes=FALSE) +
geom_line()
Upvotes: 5