Search code examples
ggplot2gridfacetgtable

ggplot, drawing lines across multiple facets (x axis is date)


My question is almost identical to this question EXCEPT that I am using dates for my x axis. I have tried the code from the answer in the linked question. The example provided works for me, but I cannot get it to work for my dataset. I am guessing it is because of the dates?

(Sorry I could not comment on the previous question chain - I'm new and don't have enough points to comment)

Here is the sample code:

library(ggplot2)
library(gtable)
library(grid)

data<-data.frame(Date=rep(seq(as.Date("2018-09-22","%Y-%m-%d"),
                              as.Date("2019-06-19","%Y-%m-%d"),
                              by=30),9),
                 Station=c(rep("A",30),rep("B",30),rep("C",30)),
                 Description=rep(c(rep("Var1",10),rep("Var2",10),
                                   rep("Var3",10)),3),
Data=c(seq(1,10,by=1),seq(500,800,length.out=10),seq(30,90,length.out=10),                   seq(5,19,length.out=10),seq(450,1080,length.out=10),seq(20,60,length.out=10),                  seq(2,15,length.out=10),seq(600,750,length.out=10),seq(80,25,length.out=10)))

plot<-ggplot(data,aes(x=Date,y=Data,color=as.factor(Station)))+
  geom_line(size=1)+
  facet_grid(Description~.,scales="free_y",switch="y")+
  xlab("")+
  ylab("")+
  theme(panel.background=element_blank(),
        panel.grid.major.y=element_line(color="grey80",
                                        size=0.25),
        panel.grid.major.x=element_blank(),
        axis.line=element_line(color="black"),
        strip.placement="outside",
        strip.background=element_blank(),
        legend.position="top",
        legend.key=element_blank(),
        legend.title=element_blank())
plot
plot.b<-ggplot_build(plot)
plot.g<-ggplot_gtable(plot.b)
data2npc <- function(x, panel = 1L, axis = "x") {
  range <- plot.b$layout$panel_params[[panel]][[paste0(axis,".range")]]
  scales::rescale(c(range, x), c(0,1))[-c(1,2)]
}
start <- sapply(as.Date("2018-10-10"),"%Y-%m-%d"), data2npc, panel=1, axis="x")
plot.g <- gtable_add_grob(plot.g, segmentsGrob(x0=start, x1=start, y0=0, y1=1, gp=gpar(lty=2)), t=7, b=9,l=5)

grid.newpage()
grid.draw(plot.g)

resulting plot


Solution

  • I have figured out my own answer!

    The key is in changing t, b, and l in gtable_add_grob:

    plot.g <- gtable_add_grob(plot.g, segmentsGrob(x0=start, x1=start, y0=0, y1=1, gp=gpar(lty=2)), t=7, b=13,l=7)
    

    Although, it seems to me to be trial and error to identify the correct values of t,b, and l.

    New code:

    library(ggplot2)
    library(gtable)
    library(grid)
    
    data<-data.frame(Date=rep(seq(as.Date("2018-09-22","%Y-%m-%d"),
                                  as.Date("2019-06-19","%Y-%m-%d"),
                                  by=30),9),
                     Station=c(rep("A",30),rep("B",30),rep("C",30)),
                     Description=rep(c(rep("Var1",10),rep("Var2",10),
                                       rep("Var3",10)),3),
    Data=c(seq(1,10,by=1),seq(500,800,length.out=10),seq(30,90,length.out=10),                seq(5,19,length.out=10),seq(450,1080,length.out=10),seq(20,60,length.out=10),                     seq(2,15,length.out=10),seq(600,750,length.out=10),seq(80,25,length.out=10)))
    
    plot<-ggplot(data,aes(x=Date,y=Data,color=as.factor(Station)))+
      geom_line(size=1)+
      facet_grid(Description~.,scales="free_y",switch="y")+
      xlab("")+
      ylab("")+
      theme(panel.background=element_blank(),
            panel.grid.major.y=element_line(color="grey80",
                                            size=0.25),
            panel.grid.major.x=element_blank(),
            axis.line=element_line(color="black"),
            strip.placement="outside",
            strip.background=element_blank(),
            legend.position="top",
            legend.key=element_blank(),
            legend.title=element_blank())
    plot
    plot.b<-ggplot_build(plot)
    plot.g<-ggplot_gtable(plot.b)
    data2npc <- function(x, panel = 1L, axis = "x") {
      range <- plot.b$layout$panel_params[[panel]][[paste0(axis,".range")]]
      scales::rescale(c(range, x), c(0,1))[-c(1,2)]
    }
    start <- sapply(as.Date("2018-10-10","%Y-%m-%d"), data2npc, panel=1, axis="x")
    plot.g <- gtable_add_grob(plot.g, segmentsGrob(x0=start, x1=start, y0=0, y1=1, gp=gpar(lty=2)), t=7, b=13,l=7)
    
    grid.newpage()
    grid.draw(plot.g)
    

    And new resulting plot