2

I want to plot a time series, excluding in the plot a stretch of time in the middle. If I plot the series alone, with only an index on the x-axis, that is what I get. The interior set of excluded points do not appear.

x <- rnorm(50)
Dates <- seq(as.Date("2008-1-1"), by = "day", length.out = length(x))
dummy <- c(rep(1, 25), rep(0, 10), rep(1, length(x) - 35))
plot(x[dummy == 1])

Once the dates are on the x-axis, however, R dutifully presents an accurate true time scale, including the excluded dates. This produces a blank region on the plot.

plot(Dates[dummy == 1], x[dummy == 1])

How can I get dates on the x-axis, but not show the blank region of the excluded dates?

rafa.pereira
  • 13,251
  • 6
  • 71
  • 109
RGecon
  • 115
  • 2
  • 10
  • Doing so would break your x-axis, which is not a good idea. You could put the remaining parts into ggplot facets, perhaps. – alistaire May 27 '16 at 16:45
  • Why not @alistaire? Is it bad form/misleading, or bad for a more technical reason? – RGecon May 28 '16 at 03:17
  • I had in mind something like `plot(x[dummy == 1], xaxt = "n")` and then using `axis` to put the dates in (or an equivalent construct in `ggplot`) but couldn't figure out how to add the dates using the `dummy == 1` subset. – RGecon May 28 '16 at 03:25
  • The meaning of the positioning in the x-direction would vary based on where you are on the graph, instead of having a single consistent relationship. That's misleading; it will make data points look closer than they in fact are. – alistaire May 28 '16 at 03:41

2 Answers2

1

Three alternatives:

1. ggplot2 Apparently, ggplot2 would not allow for a discontinuous axis but you could use facet_wrap to get a similar effect.

# get the data
  x = rnorm(50)
  df <- data.frame( x = x,
                  Dates = seq(as.Date("2008-1-1"), by = "day", length.out = length(x)) ,
                  dummy = c(rep(1, 25), rep(0, 10), rep(1, length(x) - 35)))

  df$f <- ifelse(df$Dates <= "2008-01-25",  c("A"), c("B")) 

# plot
  ggplot( subset(df, dummy==1)) +
    geom_point(aes(x= Dates, y=x)) +
    facet_wrap(~f , scales = "free_x")

enter image description here

2. base R

plot(df$x ~ df$Dates, col= ifelse( df$f=="A", "blue", "red"), data=subset(df, dummy==1))

enter image description here

3. plotrix Another alternative would be to use gap.plot{plotrix}. The code would be something like this one below. However, I couldn't figure out how to make a break in an axis with date values. Perhaps this would and additional question.

library(plotrix)

gap.plot(Dates[dummy == 1], x[dummy == 1], gap=c(24,35), gap.axis="x")
Community
  • 1
  • 1
rafa.pereira
  • 13,251
  • 6
  • 71
  • 109
  • Thanks, but that appears to impose a gap in the plot. I want the opposite: the standard plot has a gap that I don't want. – RGecon May 28 '16 at 03:28
  • I've corrected the code. Does it answer your question ? – rafa.pereira May 31 '16 at 11:06
  • 1
    Thanks. One note for total newbies like me: the data.table command in the ggplot solution (1) can be replaced by data.frame and then doesn't need another package. – RGecon Jun 02 '16 at 01:07
0

I think I figured it out. Along the lines I proposed above, I had to fiddle with the axis command for a long time to get it to put the date labels in the right place. Here's what I used:

plot(x[dummy == 1], xaxt = "n", xlab = "")  # plot with no x-axis title or tick labels
Dates1_index <- seq(1,length(Dates1), by = 5)  # set the tick positions
axis(1, at = Dates1_index, labels = format(Dates1[Dates1_index], "%b %d"), las = 2)

Having succeeded, I now agree with @alistaire that it looks pretty misleading. Maybe if I put a vertical dashed line at the break...

RGecon
  • 115
  • 2
  • 10