Haroon Lone
Haroon Lone

Reputation: 2949

Plot hourly data using ggplot2

I am using ggplot2 to plot my hourly time series data. Data organization is as

> head(df)
            timestamp    power
1 2015-08-01 00:00:00 584.4069
2 2015-08-01 01:00:00 577.2829
3 2015-08-01 02:00:00 569.0937
4 2015-08-01 03:00:00 561.6945
5 2015-08-01 04:00:00 557.9449
6 2015-08-01 05:00:00 562.4152

I use following ggplot2 command to plot the data:

    ggplot(df,aes(timestamp,power,group=1))+ theme_bw() + geom_line()+
     scale_x_datetime(labels = date_format("%d:%m; %H"), breaks=pretty_breaks(n=30)) +
       theme(axis.text.x = element_text(angle=90,hjust=1)) 

With this the plotted graph is: enter image description here

My questions are:

Upvotes: 2

Views: 5261

Answers (2)

Rorschach
Rorschach

Reputation: 32416

Here is a rather long example of scaling dates in ggplot and also a possible interactive way to zoom in on ranges. First, some sample data,

## Make some sample data
library(zoo)  # rollmean
set.seed(0)
n <- 745
x <- rgamma(n,.15)*abs(sin(1:n*pi*24/n))*sin(1:n*pi/n/5)
x <- rollmean(x, 3, 0)

start.date <- as.POSIXct('2015-08-01 00:00:00')  # the min from your df
dat <- data.frame(
    timestamp=as.POSIXct(seq.POSIXt(start.date, start.date + 60*60*24*31, by="hour")),
    power=x * 3000)

For interactive zooming, you could try plotly. You need to set it up (get an api-key and username) then just do

library(plotly)
plot_ly(dat, x=timestamp, y=power, text=power, type='line')

and you can select regions of the graph and zoom in on them. You can see it here.

For changing the breaks in the ggplot graphs, here is a function to make date breaks by various intervals at certain hours.

## Make breaks from a starting date at a given hour, occuring by interval,
## length.out is days
make_breaks <- function(strt, hour, interval="day", length.out=31) {
    strt <- as.POSIXlt(strt - 60*60*24)  # start back one day
    strt <- ISOdatetime(strt$year+1900L, strt$mon+1L, strt$mday, hour=hour, min=0, sec=0, tz="UTC")
    seq.POSIXt(strt, strt+(1+length.out)*60*60*24, by=interval)
}

One way to zoom in, non-interactively, is to simply subset the data,

library(scales)
library(ggplot2)
library(gridExtra)

## The whole interval, breaks on hour 18 each day
breaks <- make_breaks(min(dat$timestamp), hour=18, interval="day", length.out=31)
p1 <- ggplot(dat,aes(timestamp,power,group=1))+ theme_bw() + geom_line()+
  scale_x_datetime(labels = date_format("%d:%m; %H"), breaks=breaks) +
  theme(axis.text.x = element_text(angle=90,hjust=1)) +
  ggtitle("Full Range")

## Look at a specific day, breaks by hour
days <- 20
samp <- dat[format(dat$timestamp, "%d") %in% as.character(days),]
breaks <- make_breaks(min(samp$timestamp), hour=0, interval='hour', length.out=length(days))
p2 <- ggplot(samp,aes(timestamp,power,group=1))+ theme_bw() + geom_line()+
  scale_x_datetime(labels = date_format("%d:%m; %H"), breaks=breaks) +
  theme(axis.text.x = element_text(angle=90,hjust=1)) +
  ggtitle(paste("Day:", paste(days, collapse = ", ")))

grid.arrange(p1, p2)

enter image description here

Upvotes: 2

drmariod
drmariod

Reputation: 11762

I didn't worked with data time data a lot so my code might look a bit messy... But the solution to 1 is to not use pretty_breaks() but better use concrete breaks and also limit the within the scale_x_datetime() function.

A bad written example might be the following:

ggplot(df,aes(timestamp,power,group=1))+ theme_bw() + geom_line()+
  scale_x_datetime(labels = date_format("%d:%m; %H"), 
                   breaks=as.POSIXct(sapply(seq(18000, 3600000, 86400), function(x) 0 + x), 
                                     origin="2015-10-19 7:00:00"),
                   limits=c(as.POSIXct(3000, origin="2015-10-19 7:00:00"),
                          as.POSIXct(30000, origin="2015-10-19 7:00:00"))) +
  theme(axis.text.x = element_text(angle=90,hjust=1)) 

I am not sure how to write the as.POSIXct() more readable... But Basically create the 12 hour point manually and add always a complete day within the range of your data frame...

Upvotes: 1

Related Questions