Can I set dynamic axis limits in facet wrapped ggplot?

Viewed 1055

I have a dataset of ETAs and actual arrivals that I want to plot, so that I can compare the estimated times to the actual times. The challenge is that the ETAs lie close to the ATAs, but the ATAs lie far apart from one another.

This is the plot I get when I plot the data straight away:

enter image description here

In this plot, the ETAs are the dots and the ATAs the vertical lines. You can see that all estimates were slightly before the actual time (i.e. there was a delay) but you can't say much else because of the horrible scale of the graph.

I've tried a facet wrap, but that creates a new issue.

enter image description here

This plot makes it easier to see the difference between the estimates, but because the actual time lies after all the estimates, it is lost from view. (Also the axis labels are ugly, but I can fix that).

There is a final complicating factor: I have many datasets like this, and I would like to plot them dynamically. I think I could hard-code the x limits into the plot, but then the plot would be completely useless when I introduce a new dataset. So a solution that hard-codes the x ranges into the graph is not going to help.

What I think would work is a way to expand the x limits for each facet of the graph by a set amount. A sort of 'padding', if you will. For example, I could say "add two days before and after in every facet". However, I can't find a way to achieve this. Any help on how to do that (or other ways to visualize this data) would be really appreciated.

Below follows the code to generate the data and the graphs.

library(ggplot2)

etas <- structure(list(eta = structure(c(1497391200, 1497391200, 1497391200, 
1497391200, 1497391200, 1497391200, 1497391200, 1497391200, 1497391200, 
1497391200, 1497391200, 1497391200, 1502229600, 1502298000, 1497391200, 
1497438000, 1502229600, 1502193600, 1502229600, 1497391200, 1497333600, 
1502229600, 1502229600, 1502229600, 1502229600, 1502229600, 1497391200, 
1497391200, 1502229600, 1502229600, 1502229600, 1497438000, 1502229600, 
1502229600, 1502229600, 1502276400, 1502229600, 1497391200, 1497391200, 
1502208000, 1502229600, 1502229600, 1497391200, 1502229600, 1502229600, 
1497391200, 1497391200, 1497391200, 1502283600, 1497391200, 1497438000, 
1502229600, 1497391200, 1497391200, 1502283600, 1502229600, 1502229600, 
1497391200, 1502283600, 1502229600, 1502229600, 1502229600, 1497391200, 
1497391200, 1497391200, 1497438000, 1497391200, 1497391200, 1502276400, 
1497438000, 1497391200, 1497438000, 1502229600, 1502229600, 1497391200, 
1497391200, 1497438000, 1502283600, 1502229600, 1502229600, 1502229600, 
1497391200, 1502229600, 1497391200, 1502229600, 1497438000, 1497348000, 
1502283600, 1497391200, 1497391200, 1502283600, 1497438000, 1497391200, 
1502229600, 1502229600, 1502229600, 1497391200, 1502229600, 1502229600, 
1502283600, 1497391200, 1497391200, 1502229600, 1502233200, 1497391200, 
1497376800, 1502229600, 1497391200, 1497391200, 1502229600, 1502229600, 
1497391200, 1502229600, 1497391200, 1497391200, 1502229600, 1502229600, 
1502229600, 1502229600, 1497391200, 1502229600, 1502229600, 1497391200, 
1502283600, 1497438000, 1502229600, 1497391200, 1502229600, 1502229600, 
1502229600, 1502229600, 1497391200, 1502229600, 1497391200, 1502229600, 
1502229600, 1502229600, 1502229600, 1502229600, 1502276400, 1502229600, 
1502298000, 1502283600, 1502276400, 1502229600, 1502229600, 1502229600, 
1502229600), class = c("POSIXct", "POSIXt"), tzone = ""), travel_time = c(32.4625, 
32.4625, 32.4625, 32.4625, 32.4625, 32.4625, 32.4625, 32.4625, 
32, 32, 32, 32, 34.5416666666667, 34.5416666666667, 23, 23, 23, 
23, 23, 23, 23, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
21, 21, 21, 21, 21, 21, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 27, 27, 27, 27, 
27, 27, 27), id = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 
1, 1, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 1, 2, 2, 2, 
2, 2, 1, 1, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, 2, 
2, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1, 1, 
2, 2, 2, 2, 1, 2, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 2, 2, 1, 2, 
2, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 1, 2, 2, 2, 2, 
1, 2, 2, 1, 2, 1, 2, 1, 2, 2, 2, 2, 1, 2, 1, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2)), row.names = 157697:157844, class = "data.frame", .Names = c("eta", 
"travel_time", "id"))

atas <- structure(c(1502310387, 1497461116), class = c("POSIXct", "POSIXt"
), tzone = "Europe/Amsterdam")

plot <- ggplot(etas, aes(eta, travel_time, color = factor(id))) +
    geom_point() +
    geom_vline(xintercept = as.integer(atas))

plot
plot + facet_wrap(~ id, nrow = 1, scales = "free_x")
1 Answers

Use the expand, A. Stam, use the A. Stam.

You are almost there. Good work on the nice MWE.

What you are looking for is the expand argument of the scale_x_*:

plot + facet_wrap(~ id, nrow = 1, scales = "free_x") + scale_x_datetime(expand=c(0.05,48*3600))

expand takes two values, a multiplier and an addition. The multiplier expands the axis by that amount in both directions, here 5%. The addition is then added on top. You wanted 2 days added to both sides, so I added 2 x 24 x 3600. For scale_x_datetime it seems it works on seconds.

Related