BiXiC
BiXiC

Reputation: 973

change part of time x axis labels in ggplot

I have data frame like this one:

d <- data.frame(time = seq(as.POSIXct("01.01.2014 05:00:01",
                                  format = "%d.%m.%Y %H:%M:%S"),
                       as.POSIXct("02.01.2014 05:00:00",
                                  format = "%d.%m.%Y %H:%M:%S"),
                       length.out = 1440))
d$variable <- rnorm(1440)

I made ggplot of d

library(ggplot2)
library(scales)
ggplot(data = d, aes(time,variable)) + 
  geom_point() +
  scale_x_datetime(labels = date_format("%H:%M"),breaks = "1 hour")

enter image description here

I want change part of x axis labels from 00:00 to 05:00 Instead of this x axis labels I want 24:00 to 29:00.

Is it possible to do this with scale_x_datetime function or may be smth similar to it?

Upvotes: 2

Views: 2577

Answers (1)

MrFlick
MrFlick

Reputation: 206308

What if you created a new formatter which calculated hours/minutes since a certain day/time like

hmsince_format <- function(since) {
    function(x) {
        dt<-as.numeric(difftime(x, since, units="mins"))
        sprintf("%02d:%02d", as.integer(dt %/% 60), as.integer(dt %% 60))
    }
}

Basically hmsince() is a factory style function that will return a label formatting function. ggplot will pass the dates used as axis marks to this inner function via x. We then subtract these dates from the since date that remains in scope because our function is nested in the factory. We then subtract the two dates from each other and format them as hour:minute.

Then you could do

sinceDate <- as.POSIXct("01.01.2014 00:00:00", format = "%d.%m.%Y %H:%M:%S")
ggplot(data = d, aes(time,variable)) + 
  geom_point() +
  scale_x_datetime(labels = hmsince_format(sinceDate ), breaks = "1 hour")

that should give you the labels you are after.

Now that i've read why you are doing this, I created an alternate function that you may wish to use should your data span multiple dates

tvtime_format<-function() {
    function(x) {
        v<-character(length(x))
        notNA<-!is.na(x)
        lt <- as.POSIXlt(x[notNA])
        hour <- lt$hour
        hour[hour<5] <- hour[hour<5]+24
        min <- lt$min
        v[notNA]<-sprintf("%02d:%02d", hour, min)
        v
    }
}

Here is it not required to pass any particular date to use as an anchor. It will just add 24 to hours less than 5. (I don't really need a nested function in this case but I kept it this way so the methods are similar.) This is used like

ggplot(data = d, aes(time,variable)) + 
  geom_point() +
  scale_x_datetime(labels = tvtime_format(), breaks = "1 hour")

Upvotes: 5

Related Questions