Reputation: 1322
I have a nx2
dataframe where each row contains beginning and end of some time interval.
start end
3 2015-04-21 20:57:23 2015-04-21 23:55:23
5 2015-04-22 00:16:26 2015-04-22 00:28:23
8 2015-04-22 01:20:14 2015-04-22 02:34:51
12 2015-04-22 03:31:27 2015-04-22 04:31:03
14 2015-04-22 04:35:56 2015-04-22 05:54:10
16 2015-04-22 06:01:35 2015-04-22 07:14:35
I would like to plot these intervals in R with x-axis being 24 hours and y-axis being days. So it should look something like this:
What is the appropriate way to do this?
Here's dput from the first 20 rows:
nx2 <- structure(list(start = structure(c(1429642643.153, 1429654586.936,
1429658414.048, 1429666287.926, 1429670156.358, 1429675295.181,
1429680010.595, 1429691755.137, 1429700624.139, 1429708239.758,
1429712967.668, 1429716686.314, 1429725292.357, 1429735963.053,
1429741262.112, 1429751626.278, 1429755842.324, 1429774600.104,
1429787329.274, 1429791813.291), class = c("POSIXct", "POSIXt"
), tzone = ""), end = structure(c(1429653323.153, 1429655303.968,
1429662891.218, 1429669863.373, 1429674850.654, 1429679675.181,
1429686495.759, 1429695163.947, 1429707547.129, 1429711839.758,
1429715565.467, 1429722206.314, 1429734763.081, 1429740231.567,
1429749242.112, 1429752556.557, 1429767902.324, 1429783522.586,
1429790609.476, 1429795064.659), class = c("POSIXct", "POSIXt"
), tzone = "")), .Names = c("start", "end"), row.names = c(3L,
5L, 8L, 12L, 14L, 16L, 18L, 24L, 28L, 30L, 33L, 35L, 38L, 42L,
44L, 48L, 52L, 59L, 65L, 68L), class = "data.frame")
Upvotes: 4
Views: 2296
Reputation: 3635
Here is one way doing it using ggplot and dplyr. The graph is displayed for Moscow time.
library(ggplot2)
library(dplyr)
tz <- "Europe/Moscow"
df <- nx2 %>%
mutate( hour_start = floor(as.numeric(start)/3600),
hour_end_est = ceiling(as.numeric(end)/3600),
hour_end = ifelse(hour_end_est >= hour_start,
hour_end_est,
hour_start)
) %>%
rowwise() %>%
do( {
hourstamp <- 3600 * seq( .$hour_start, .$hour_end, by=1)
day_hour <- sapply(hourstamp, function(x)
as.POSIXlt(x, tz=tz, origin="1970-01-01")$hour)
day_id <- sapply(hourstamp, function(x)
as.POSIXlt(x, tz=tz, origin="1970-01-01")$mday)
data.frame(hour = day_hour, day = day_id)
} )
ggplot(df,aes(x=hour, y=day)) +
geom_tile(col="black",fill="blue",alpha=0.3) +
scale_x_continuous(breaks=0:24,limits=c(-1,24)) +
scale_y_continuous(breaks=0:31,limits=c(-1,31)) +
xlab("Hours") +
ylab("Days")
And I get this:
If minute resolution is needed then it is a simple modification to the code above:
library(ggplot2)
library(dplyr)
tz <- "Europe/Moscow"
df <- nx2 %>%
mutate( minute_start = floor(as.numeric(start)/60),
minute_end_est = ceiling(as.numeric(end)/60),
minute_end = ifelse(minute_end_est >= minute_start,
minute_end_est,
minute_start)
) %>%
rowwise() %>%
do( {
minutestamp <- 60 * seq( .$minute_start, .$minute_end, by=1)
day_minute <- sapply(minutestamp, function(x)
{
psx_time <- as.POSIXlt(x, tz=tz, origin="1970-01-01")
psx_time$hour*60 + psx_time$min
})
day_id <- sapply(minutestamp, function(x)
{
psx_time <- as.POSIXlt(x, tz=tz, origin="1970-01-01")
psx_time$mday
})
data.frame(minute = day_minute, day = day_id)
} )
ggplot(df,aes(x=minute, y=day)) +
geom_tile(fill="blue",alpha=0.3) +
scale_x_continuous(breaks=seq(0,24*60,by=60),
limits=c(-60,24*60)) +
scale_y_continuous(breaks=0:31,limits=c(-1,31)) +
xlab("Minutes") +
ylab("Days")
And I get this:
Upvotes: 2
Reputation: 56004
Try this:
library(lubridate)
library(ggplot2)
#data prep for plotting
nx2$DD <- day(nx2$start)
nx2$startHH <- hour(nx2$start)
nx2$endHH <- hour(nx2$end)
#plot
ggplot(nx2,aes(xmin = startHH, xmax = endHH + 1,
ymin = DD-0.5, ymax = DD + 0.5)) +
geom_rect(col="black",fill="blue",alpha=0.3) +
scale_x_continuous(breaks=0:24,limits=c(0,24)) +
scale_y_continuous(breaks=0:31,limits=c(0,31)) +
xlab("Hours") +
ylab("Days") +
theme_bw()
Upvotes: 2