使用ggplot2绘制每小时数据

时间:2015-10-19 03:51:17

标签: r ggplot2

我正在使用ggplot2绘制我的每小时时间序列数据。数据组织如

> 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

我使用以下ggplot2命令绘制数据:

    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)) 

有了这个绘制的图表是: enter image description here

我的问题是:

  • 在绘制的图表中,为什么仅显示与hour 18对应的标签。现在,如果我想显示与每天hour 12对应的标签,该怎么办?
  • 我正在绘制每小时的数据,希望能够看到精细的细节。但是,我无法看到整个一个月的所有时间。我可以在同一个地块中以某种方式看到任何选定日期的缩放视图吗?

2 个答案:

答案 0 :(得分:2)

这是一个在ggplot中缩放日期的相当长的例子,也是一种放大范围的可能的交互方式。首先,一些样本数据,

## 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)

对于交互式缩放,您可以尝试plotly。您需要进行设置(获取api-key和用户名),然后执行

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

您可以选择图表的区域并放大它们。你可以看到它enter image description here

为了更改ggplot图中的中断,这里有一个函数可以在特定时间以不同的间隔进行日期分隔。

## 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)
}

非交互式放大的一种方法是简单地对数据进行子集化,

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)

diawi

答案 1 :(得分:1)

我没有大量使用数据时间数据,所以我的代码可能看起来有点乱......但是1的解决方案是使用pretty_breaks()但是更好地使用具体中断并限制scale_x_datetime()函数。

一个糟糕的书面例子如下:

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)) 

我不确定如何编写as.POSIXct()更具可读性......但基本上手动创建12小时点并在数据框范围内添加一整天......