'R ggplot date time major and minor axis breaks not aligning
I'm having a problem that I am surprised I haven't encountered before and that I can't see any answers about. I am plotting some date time data in ggplot and want to force daily major breaks and quarter daily minor breaks (0, 6, 12, 18). When I set date_breaks = "1 day", date_minor_breaks = "6 hours" the date breaks are at middnight but the minor breaks depend on the start time of the data so I have weird offset minor breaks.
I will be making similar plots for a whole range of data which will have variable start times and end times (read from csvs or filtered from datasets based on certain conditions) so I am looking for a generic solution which will work without a fixed start time.
I have made the minor gridlines blue and major gridlines black in the example just to be more clear
library(lubridate)
library(ggplot2)
testdat <- data.frame(DateTime = seq.POSIXt(from = ymd_hm("20210101 1200"), length.out = 130, by = "1 hour", tz = "UTC"),
y = rnorm(130))
ggplot(testdat, aes(x = DateTime, y = y))+geom_point()+
scale_x_datetime(date_breaks = "1 day", date_minor_breaks = "6 hours", timezone = "UTC",
date_labels = "%d %b %H:%M")+theme_bw()+
theme(panel.grid.major.x = element_line(colour = "black"),
panel.grid.minor.x = element_line(colour = "blue"))
Solution 1:[1]
One approach would be to remove the automatic scale padding with expand = c(0,0)
and to specify limits that are an integer # of minor breaks on either side:
ggplot(testdat, aes(x = DateTime, y = y))+geom_point()+
scale_x_datetime(date_breaks = "1 day", date_minor_breaks = "6 hours", timezone = "UTC",
date_labels = "%d %b %H:%M", expand = c(0,0),
limits = c(min(testdat$DateTime) - hours(6),
max(testdat$DateTime) + hours(6)))+
theme_bw()+
theme(panel.grid.major.x = element_line(colour = "black"),
panel.grid.minor.x = element_line(colour = "blue"))
Solution 2:[2]
Using the same units in the date_breaks
and date_minor_breaks
statements will align the axis breaks, but doesn't guarantee they start at a sensical date/time.
ggplot(testdat, aes(x = DateTime, y = y)) +
geom_point() +
scale_x_datetime(date_breaks = "1 day",
minor_breaks = function(x) {
seq.POSIXt(lubridate::floor_date(x[1], "day"),
lubridate::ceiling_date(x[2], "day"),
by = "6 hours")
},
date_labels = "%d %b %H:%M") +
theme_bw() +
theme(panel.grid.major.x = element_line(colour = "black"),
panel.grid.minor.x = element_line(colour = "blue"))
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Jon Spring |
Solution 2 |