Reputation: 11686
I seem to be having trouble setting up a ribbon in ggplot2 to display.
Here's a made up data set:
Estimate <- c(100,125,150,175)
GlobalDFData <- data.frame(Estimate, Upper = Estimate + 25, Lower = Estimate - 25, Date = paste0('Q', 1:4,'_16'), Area = 'Global', stringsAsFactors = FALSE)
Here's the code that I'm trying with no success. I get the line chart but not the upper and lower bounds
ggplot(GlobalDFData, aes(x = Date)) +
geom_line(aes(y = Estimate, group = Area, color = Area))+
geom_point(aes(y = Estimate, x = Date))+
geom_ribbon(aes(ymin = Lower, ymax = Upper))
Upvotes: 8
Views: 6893
Reputation: 23747
geom_ribbon
needs a grouping variable.
We all know that you need to tell geom_line
which observation the lines need to connect. If there is only one observation per group, then you specify group = 1
. This seems also the case for geom_ribbon
. That's the reason, why in @alexforrence example, providing a grouping aesthetic (color = Area
) results in the weird output, similar to the output of geom_linerange
.
Specifying group = 1
(interestingly either inside or outside aes()
) is a solution. No need for changing x to a continuous variable, nor any zoo magic.
library(tidyverse)
Estimate <- c(100,125,150,175)
GlobalDFData <- data.frame(Estimate, Upper = Estimate + 25, Lower = Estimate - 25, Date = paste0('Q', 1:4,'_16'), Area = 'Global', stringsAsFactors = FALSE)
plt <- ggplot(GlobalDFData, aes(x = Date)) +
geom_line(aes(y = Estimate, group = Area, color = Area)) +
geom_point(aes(y = Estimate, x = Date))
plt + geom_ribbon(aes(ymin = Lower,
ymax = Upper,
group = 1),
alpha = 0.5)
Created on 2019-04-24 by the reprex package (v0.2.1)
Upvotes: 4
Reputation: 2744
geom_ribbon
prefers a continuous x value, but you can trick it a bit by providing one during the call.
plt <- ggplot(dat, aes(x = Date)) +
geom_line(aes(y = Estimate, group = Area, color = Area)) +
geom_point(aes(y = Estimate, x = Date))
plt + geom_ribbon(aes(x = 1:length(Date), ymin = Lower, ymax = Upper), alpha = .2)
Additionally, you could use
geom_linerange
, but that probably doesn't achieve the look you're going for:
plt + geom_linerange(aes(ymin = Lower, ymax = Upper, color = Area))
And curiously enough, assigning a color with geom_ribbon
achieves the same (effective) result (plot not shown):
plt + geom_ribbon(aes(ymin = Lower, ymax = Upper, color = Area))
Additionally, you could use the zoo
package to convert your quarterly times to something that can be understood as continuous, in conjunction with scale_x_yearqtr
:
library(zoo)
dat$Date <- as.yearqtr(dat$Date, format = 'Q%q_%y')
ggplot(dat, aes(x = Date)) +
scale_x_yearqtr(format = 'Q%q_%y') +
geom_line(aes(y = Estimate, group = Area, color = Area))+
geom_point(aes(y = Estimate, x = Date))+
geom_ribbon(aes(ymin = Lower, ymax = Upper), alpha = 0.2)
Upvotes: 10