12

I have a time series data with a gap of year (e.g. 2006). I attempted to create a continuous lineplot ignoring this gap with scale_x_date. However, the function only removes the date labels on the x-axis and leaves a gap in the plot. Is there a way to remove the x-axis text and the gap in datapoints?

Data:

set.seed(123)
n <- 100
y <- sample.int(n, replace=TRUE)
t <- seq(from=as.Date("2001-01-01"), by="month", length.out=n)
dat <- data.frame(t, y)[!format(t, "%Y") %in% 2006, ]

Tried:

library(ggplot2)
my_break_fun <- function(x){
  br <- seq(from = min(x), to=max(x), by="2 month")
  br[!format(br, "%Y") %in% 2006]
}

dat |> 
  ggplot(aes(x=t, y=y)) +
  geom_line() +
  scale_x_date(
    date_labels="%b-%Y",
    breaks=my_break_fun
  ) +
  theme(axis.text.x = element_text(angle=90, hjust=1, vjust=1))

enter image description here

4
  • 5
    Why would one do that? This is faking. Commented Sep 16 at 15:06
  • 8
    I think there are plenty of situations where there is dead space between relevant observations where it’s fine to skip the space between (Eg stock price movements where there’s no data when the market is closed, or sunlight measurements or store sales across the course of a week, etc.) Commented Sep 16 at 15:18
  • 4
    There are a bunch of honest gap axis functions floating around. Commented Sep 16 at 15:36
  • Also relevant: stackoverflow.com/questions/79581615/… Commented yesterday

4 Answers 4

21

Facets would be one common way:

dat |> 
  dplyr::mutate(grp = t >= as.Date("2006-01-01")) |>
  ggplot(aes(x=t, y=y)) +
  geom_line() +
  scale_x_date(
    date_labels="%b-%Y",
    breaks=my_break_fun
  ) +
  facet_grid(.~grp, scales = "free_x", space = "free_x") +
  theme(axis.text.x = element_text(angle=90, hjust=1, vjust=1)) +
  theme(strip.background = element_blank(),
        strip.text = element_blank())

enter image description here

1 Comment

13

We can use {ggbreak}:

dat |> 
  ggplot(aes(x=t, y=y)) +
  geom_line() +
  ggbreak::scale_x_break(c(as.Date("2005-12-02"), as.Date("2006-12-31")), 
                         expand = FALSE) +
  scale_x_date(date_labels="%b-%Y", breaks="2 months") +
  theme(axis.text.x = element_text(angle=90, hjust=1, vjust=1),
        axis.text.x.top = element_blank(),
        axis.ticks.x.top = element_blank())

Created on 2025-09-16 with reprex v2.1.1

Comments

8

Base R, addressing breaks by different line colours.

dat = data.frame(t, y)[
  !format(t, '%Y') %in% 2006, ] |> 
  transform(i=seq_along(t))

L = split(dat, cumsum(c(FALSE, diff(dat$t)>31)))
n = palette.colors(length(L))

par(mar=c(6, 4.1, 4.1, 2.1))
plot(y~i, data=dat, type='n', xaxt='n')
for (l in seq_along(L)) 
  lines(L[[l]]$i, L[[l]]$y, col=n[l], type='b')
axis(1, at=dat$i, labels=format(dat$t, '%b-%Y'), las=2)

enter image description here


Note

In my (publication) routine, when creating several figures in one script, I tend to wrap the figure-generating lines in local({ <code here> }), to prevent the global environment from getting cluttered.

Comments

7

I know this is tagged ggplot2, but a base R solution for others not using ggplot would be to create an index (here, seq_along(dat$t)) and then label the axis based on the index:

par(mar = c(6, 4.1, 4.1, 2.1)) # just to make room for long dates

plot(seq_along(dat$t), dat$y, type = "l", 
     xaxt = "n", xlab = "", ylab="Value")

axis(1, at = seq_along(dat$t), labels = labels = format(dat$t, "%b-%Y"), las = 2)

enter image description here

This is generally bad practice in the visual representation of data since it doesnt address the gap in data. Another way indicate the gap in data (other than changing line color) would be to add a vertical line with abline. This can also be done by simply creating an indicator using which and diff that "finds" the gap:

abline(v = which(as.numeric(diff(dat$t)) > median(diffs)) + 0.5,
       col = "red", lty = 3, lwd = 2)

enter image description here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.