6

I have a number of times and want to plot the frequency of each time in a barplot

library(ggplot2)
library(chron)
test <- data.frame(times = c(rep("7:00:00",4), rep("8:00:00",3), 
                         rep("12:00:00",1), rep("13:00:00",5)))
test$times <- times(test$times)
test
      times
1  07:00:00
2  07:00:00
3  07:00:00
4  07:00:00
5  08:00:00
6  08:00:00
7  08:00:00
8  12:00:00
9  13:00:00
10 13:00:00
11 13:00:00
12 13:00:00
13 13:00:00

The value of binwidth is chosen to represent minutes

p <- ggplot(test, aes(x = times)) + geom_bar(binwidth=1/24/60)
p + scale_x_chron(format="%H:%M")

As you see the scales are plus one hour in the x-axis:

enter image description here

I have the feeling that is has something to do with the timezone, but I cant really place it:

Sys.timezone()
[1] "CET"

Edit: Thanks @shadow for comment

UPDATE:

If I run Sys.setenv(TZ='GMT') first it works perfectly. The problem is in the times() function. I automatically sets the timezone to GMT and if I'm plotting the x-axis, ggplot notices that my system-timezone is CET and adds one hour on the plot. Now if i'm setting my system-timezone to GMT, ggplot doesn't add an hour.

PatrickT
  • 10,037
  • 9
  • 76
  • 111
schlusie
  • 1,907
  • 2
  • 20
  • 26
  • Take a look at some of the challenges of working with timezones here: http://stackoverflow.com/questions/18156015/posixct-to-numeric-using-different-timezones – Andy Clifton Mar 13 '14 at 14:12

2 Answers2

6

The problem is that times(...) assumes the timezone is GMT, and then ggplot compensates for your actual timezone. This is fair enough: times are meaningless unless you specify timezone. The bigger problem is that it does not seem possible to tell times(...) what the actual timezone is (if someone else knows how to do this I'd love to know).

A workaround is to use POSIXct and identify your timezone (mine is EST).

test <- data.frame(times = c(rep("7:00:00",4), rep("8:00:00",3), 
                             rep("12:00:00",1), rep("13:00:00",5)))
test$times <- as.POSIXct(test$times,format="%H:%M:%S",tz="EST")
p <- ggplot(test, aes(x = times)) + geom_bar(binwidth=60,width=.01)

binwidth=60 is 60 seconds.

jlhoward
  • 58,004
  • 7
  • 97
  • 140
  • Is it possible to use a `scale_x_...` for `POSIXTct`, say for setting limits? Because everytime I was using `scale_x_datetime`, the date appeared and I just wanted to limit my x-axis without the appearance of dates. This was one of the reasons I switched to the `chron`-package. – schlusie Mar 13 '14 at 19:18
  • 1
    You could add `scale_x_datetime(labels=date_format("%H:%M"))`, but there's no need in this case. – jlhoward Mar 13 '14 at 20:09
2

It has nothing to do with timeszone, the only problem is that in format, %m represents the month and %M represents the minute. So the following will work

p + scale_x_chron(format="%H:%M") 
shadow
  • 21,823
  • 4
  • 63
  • 77
  • Thanks for noticing the mistake but still doesn't work: http://imgur.com/yHvxQxr. The hours are still +1.8:00 instead of 7:00, for example. – schlusie Mar 13 '14 at 14:02
  • 4
    Try setting your R system timezone to be the same as the data were originally. For example, for UTC data, use `Sys.setenv(TZ='GMT')`. – Andy Clifton Mar 13 '14 at 14:13