Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Missing Ribbon in ggplot2

Tags:

r

ggplot2

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))
like image 912
user1357015 Avatar asked Jan 01 '16 02:01

user1357015


2 Answers

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)

enter image description here 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))

enter image description here

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)
like image 69
alexforrence Avatar answered Oct 31 '22 22:10

alexforrence


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)

like image 34
tjebo Avatar answered Oct 31 '22 22:10

tjebo