将持续时间绘制为ggplot2

时间:2016-03-16 15:18:50

标签: r date datetime ggplot2

最后几天,我正在考虑以下问题:我想将活动的持续时间绘制为一条线, y轴表示活动发生的日期,x轴表示时间(小时)。 当我处理在同一天开始和结束的活动时,这很容易。

例如:

df1<-structure(list(Date = structure(c(16802, 16803, 16805, 16806, 
16809, 16810, 16812, 16813, 16816, 16820, 16821, 16822, 16829
), class = "Date"), hms1 = structure(c(1457623680, 1457620860, 
1457621160, 1457622540, 1457625600, 1457621280, 1457620380, 1457619720, 
1457623620, 1457621460, 1457620440, 1457617980, 1457621880), class =      c("POSIXct", "POSIXt"), tzone = ""), hms2 = structure(c(1457632500, 1457627640, 
1457628360, 1457629500, 1457631000, 1457625120, 1457625420, 1457624520, 
1457627640, 1457626800, 1457626800, 1457622060, 1457625540), class = c("POSIXct", 
"POSIXt"), tzone = "")), .Names = c("Date", "hms1", "hms2"), class =     "data.frame", row.names = c(103L, 105L, 108L, 110L, 114L, 117L, 120L, 122L, 127L, 135L, 136L, 138L, 145L))

p1<-ggplot(df1, aes(x=Date,y= hms1))+ scale_x_date(breaks = date_breaks("1 day"))+
geom_linerange(aes(ymin = hms1, ymax = hms2),color = "red",size = 2)+ coord_flip()
p1+ylab("Time")+ggtitle("Activity During Day")

给出了所需的情节:    ggplot1

请注意,实际日期位于列日期,而hms1m hms2中的日期错误,因为我用H + M:S格式获取时间的过程。

df1$hms1 <- format(df1$time, format = "%H:%M:%S")
df1$hms1 <- as.POSIXct(df1$hms1, format = "%H:%M:%S")

事情就是大多数&#34;活动&#34;,我试图在两天内绘制跨度。我到目前为止唯一提出的解决方案, 正在将日期时间值移动一段适当的时间段,以便人工制造&#34;按照2的建议,将它们放在同一天。 然而,这个过程自然会导致x轴显示&#34; artificial&#34;时间戳。

如何控制ggplot中的刻度线,这样我才能让它们显示正确的时间戳? 或者甚至更好的人可以提出更优雅的解决方案? 要明确:我希望y轴只是事件开始的日期,但是x轴的跨度超过24小时。

1 个答案:

答案 0 :(得分:8)

我不确定您的真实数据结构是什么样的,所以我创建了一些时间段用于说明,如下所示:我使用Date的值,然后使用runif选择一些随机启动和每个活动的结束时间。某些时间段出现在一个日期内,有些时间段出现在两个日期之内

然后我按如下方式绘制数据:绘制在活动开始日期垂直定位的水平线。该行从活动开始时的时间(以小时为单位)开始(相对于活动开始日期的午夜),然后向右延伸,持续活动持续数小时。

水平刻度延长至48小时,因此可以显示涵盖多个日期的活动。垂直线标记日期边界,因此您可以查看哪些活动持续到第二天。如果您的活动持续三天或更长时间,只需根据需要扩展水平刻度以适应它们。

# Convert Date to POSIXct and set HMS to beginning of day (i.e., Midnight).
# To do this, I added 8-hours to account for my locale being the U.S. Pacific time zone.
df1$Date = as.POSIXct(df1$Date) + 3600*8

## Create some times for start and end of each activity
set.seed(20)
df1$hms1a = df1$Date  + runif(nrow(df1), 3600*5, 3600*10)
df1$hms2a = df1$Date + runif(nrow(df1), 3600*15, 3600*40)

library(ggplot2)
library(scales)
library(stringr)

ggplot(df1, aes(x=Date)) + 
  scale_x_datetime(breaks = date_breaks("1 day")) +
  scale_y_continuous(limits = c(0,48), breaks=seq(0,48,2), 
                     labels=str_pad(seq(0,48,2) %% 24, 2, pad="0")) +
  geom_hline(yintercept=seq(0,48,24)) +
  geom_linerange(aes(ymin = hms1a - Date, ymax = hms2a - Date), color = "red",size = 2) + 
  coord_flip() + ylab("Time (hours)") + 
  ggtitle("Activity During Day")

enter image description here