17

I have a time series with multiple days of data. In between each day there's one period with no data points. How can I omit these periods when plotting the time series using ggplot2?

An artificial example shown as below, how can I get rid of the two periods where there's no data?

code:

Time = Sys.time()+(seq(1,100)*60+c(rep(1,100)*3600*24, rep(2, 100)*3600*24, rep(3, 100)*3600*24))
Value = rnorm(length(Time))
g <- ggplot() 
g <- g + geom_line (aes(x=Time, y=Value))
g

enter image description here

Sven Hohenstein
  • 80,497
  • 17
  • 145
  • 168
billlee1231
  • 395
  • 5
  • 11

3 Answers3

21

First, create a grouping variable. Here, two groups are different if the time difference is larger than 1 minute:

Group <- c(0, cumsum(diff(Time) > 1))

Now three distinct panels could be created using facet_grid and the argument scales = "free_x":

library(ggplot2)
g <- ggplot(data.frame(Time, Value, Group)) + 
  geom_line (aes(x=Time, y=Value)) +
  facet_grid(~ Group, scales = "free_x")

enter image description here

Sven Hohenstein
  • 80,497
  • 17
  • 145
  • 168
  • 1
    Definitely the best solution when you only have a few blocks. – csgillespie Jan 03 '13 at 10:30
  • Thx. I was trying to do this within one single plot but it seems that your method is still acceptable. Other packages like quantmod could do this perfectly right, but I guess this is not what ggplot2 is supposed to do. – billlee1231 Jan 03 '13 at 10:31
9

The problem is that how does ggplot2 know you have missing values? I see two options:

  1. Pad out your time series with NA values
  2. Add an additional variable representing a "group". For example,

    dd = data.frame(Time, Value)
    ##type contains three distinct values
    dd$type = factor(cumsum(c(0, as.numeric(diff(dd$Time) - 1))))
    
    ##Plot, but use the group aesthetic
    ggplot(dd, aes(x=Time, y=Value)) +
          geom_line (aes(group=type))
    

    gives

    enter image description here

csgillespie
  • 59,189
  • 14
  • 150
  • 185
  • Thanks. But I would rather completely get rid of the blank periods in between (meaning even not shown in the x axis). – billlee1231 Jan 03 '13 at 10:31
  • 3
    You didn't put that in your question ;) But the answer you accepted is much nicer for only a few blocks and that's the one I would go for. – csgillespie Jan 03 '13 at 10:32
3

csgillespie mentioned padding by NA, but a simpler method is to add one NA after each block:

Value[seq(1,length(Value)-1,by=100)]=NA

where the -1 avoids a warning.

Dieter Menne
  • 10,076
  • 44
  • 67