Search code examples
rggplot2time-seriesgraphing

Change number of x ticks on time series using ggplot2


I'm trying to plot a time series x_output that looks like this:

              timestamp   city wait_time weekday     time
    2015-07-14 09:00:00 Boston       1.6 Tuesday 09:00:00
    2015-07-14 09:01:00 Boston       1.8 Tuesday 09:00:00
    2015-07-14 09:02:00 Boston       2.4 Tuesday 09:00:00
    2015-07-14 09:03:00 Boston       2.9 Tuesday 09:00:00
    2015-07-14 09:04:00 Boston       4.5 Tuesday 09:00:00
    2015-07-14 09:05:00 Boston       5.6 Tuesday 09:00:00

Here's how I'm plotting it:

brks <- seq(1, length(x_output$timestamp), 10)
brks_labels <- x_output[brks, ]

p <- ggplot(x_output, aes(x=as.character(timestamp), y=wait_time, group=city)) + geom_line(aes(color=city), size=1.5) + theme(axis.text.x = element_text(angle = 90, hjust=1), legend.position = "bottom") + labs(x=NULL, y="Waiting time (minutes)") + scale_x_discrete(breaks = brks, labels = brks_labels)
print(p)

I have to use x_output$timestamp as a character (ie. categorical variable) because otherwise, ggplot2 thinks it's continuous and includes white blank areas that have no values.

For some reason however, scale_x_discrete does not seem to be working. I believe I got the input for breaks right, however, the labels now aren't showing. Does anyone know why? Here's what plots:

enter image description here

I'm trying to simply have the labels appear every 10 timestamps on the x-axis (which is why I put the breaks into an array as brks).


Solution

  • Your breaks have to be the same type as your aes(x=, i.e. scale_x_discrete(breaks=x_output$timestamp[brks]) works.

    However be aware that converting your timestamp to categorical like this can be inaccurate on the timescale then - if a timestamp skipped by 2 minutes and the rest skipped by 1 this wouldn't be reflected on your graph.

    I think you're better off keeping X as a datetime, and using + scale_x_datetime(breaks=date_breaks("10 mins")). If you have multiple windows of time separated by expanses of no data, you could use a variable to indicate which 'window' each row belongs to, and facet_wrap to plot the windows side-by-side, which would let you skip the gaps while preserving x-axis scale. E.g. you could facet_wrap by weekday if your data was only for a particular window each day.