Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ggplot2 - add horizontal line to faceted plot with dates on x-axis

Tags:

r

ggplot2

I'm trying to add a zero line to a faceted plot in ggplot2 with dates on the x-axis. The problem is that I'm also adding polygons to represent certain time spans, so I have to pass separate data.frames to separate geoms, which yields some difficulties.

Here is an example with a continuous x-axis:

ggplot()+
  geom_rect(data=data.frame(from=c(1,3),to=c(2,4)),aes(xmin=from,xmax=to,ymin=-Inf,ymax=Inf),fill="red",alpha=0.1)+
  geom_point(data=data.frame(x=c(1,2,3,4,5,6),y=c(6,7,8,9,10,11),type=rep(letters[1:2],each=3)),aes(x=x,y=y))+
  facet_grid(type~.)

If I try to add a horizontal line with geom_hline I get an error: Error in if (empty(data)) { : missing value where TRUE/FALSE needed, which I take is because geom_vline needs to inherit info provided in the base ggplot line. As noted above, however, I must provide separate data.frames to create both points and shaded polygons.

This can be worked around if the x-axis is continuous by using geom_line and setting the values to Inf:

ggplot()+
  geom_line(data=data.frame(x=c(-Inf,Inf),y=0),aes(x=x,y=y),col="grey50",lwd=1)+
  geom_rect(data=data.frame(from=c(1,3),to=c(2,4)),aes(xmin=from,xmax=to,ymin=-Inf,ymax=Inf),fill="red",alpha=0.1)+
  geom_point(data=data.frame(x=c(1,2,3,4,5,6),y=c(6,7,8,9,10,11),type=rep(letters[1:2],each=3)),aes(x=x,y=y))+
  facet_grid(type~.)

But if I switch the x-axis to dates, then I can't add a horizontal line using geom_hline (for the same reasons as above):

dates=c("2001-01-1","2002-01-01","2003-01-01","2004-01-01","2005-01-01","2006-01-01")

ggplot()+
  geom_hline(aes(yintercept=0))+
  geom_rect(data=data.frame(from=c(as.Date("2001-01-1"),as.Date("2003-01-01")),
                            to=c(as.Date("2002-01-1"),as.Date("2004-01-01"))),
            aes(xmin=from,xmax=to,ymin=-Inf,ymax=Inf),fill="red",alpha=0.1)+
  geom_point(data=data.frame(x=as.Date(dates),y=c(6,7,8,9,10,11),type=rep(letters[1:2],each=3)),aes(x=x,y=y))+
  facet_grid(type~.)

Similarly, using geom_line as above produces an error: Error: Discrete value supplied to continuous scale because the x-axis is no longer continuous.

I can specify the endpoints of geom_line as dates:

ggplot()+
  geom_line(data=data.frame(x=c(as.Date("2001-01-01"),as.Date("2006-01-01")),y=0),aes(x=x,y=y),col="grey50",lwd=1)+
  geom_rect(data=data.frame(from=c(as.Date("2001-01-1"),as.Date("2003-01-01")),
                            to=c(as.Date("2002-01-1"),as.Date("2004-01-01"))),
            aes(xmin=from,xmax=to,ymin=-Inf,ymax=Inf),fill="red",alpha=0.1)+
  geom_point(data=data.frame(x=as.Date(dates),y=c(6,7,8,9,10,11),type=rep(letters[1:2],each=3)),aes(x=x,y=y))+
  facet_grid(type~.)

But now the line does not extend the length of the plot!

How can I reproduce a geom_vline-like output using something that will work with dates on the x-axis and facets?

like image 802
jslefche Avatar asked Dec 14 '14 21:12

jslefche


Video Answer


1 Answers

Your problem is in fact quite different, and also very easy to fix.

Since the value of yintercept in your hline is not related to your data, but a user-specified value, this should not form part of the aes().

Instead, the specification is simply:

geom_hline(yintercept=0) +

Try this:

dates=c("2001-01-1","2002-01-01","2003-01-01","2004-01-01","2005-01-01","2006-01-01")

ggplot()+
  geom_rect(data=data.frame(from=c(as.Date("2001-01-1"),as.Date("2003-01-01")),
                            to=c(as.Date("2002-01-1"),as.Date("2004-01-01"))),
            aes(xmin=from,xmax=to,ymin=-Inf,ymax=Inf),fill="red",alpha=0.1) +
  geom_point(data=data.frame(x=as.Date(dates),y=c(6,7,8,9,10,11),type=rep(letters[1:2],each=3)),
             aes(x=x,y=y)) +
  geom_hline(yintercept=0) +
  facet_grid(type~.)

enter image description here

like image 134
Andrie Avatar answered Oct 19 '22 09:10

Andrie