I need to create raster plot which displays time based data. Here is an example of the data I have. For each participant, I have durations of time (onsets and offsets) they spent in different locations (crib, floor, etc) across 24 hour day. I would like a type of raster that shows participant locations continuously, rather than as ticks. How do I go about writing that script in ggplot2?
id onset offset location
1 06:00:00.0 06:35:00.0 hichair
1 06:35:00.0 08:00:00.0 carseat
1 08:00:00.0 09:00:00.0 chifurn
1 09:00:00.0 09:45:00.0 cribcradle
1 09:45:00.0 12:00:00.0 gndfl
1 12:00:00.0 12:45:00.0 chifurn
1 12:45:00.0 15:00:00.0 gndfl
1 15:00:00.0 16:00:00.0 chifurn
1 16:00:00.0 17:15:00.0 strowlkr
1 17:15:00.0 18:00:00.0 carseat
1 18:00:00.0 18:30:00.0 hichair
1 18:30:00.0 19:30:00.0 gndfl
1 19:30:00.0 20:00:00.0 adlfurn
1 20:00:00.0 06:00:00.0 cribcradle
2 06:00:00.0 06:30:00.0 cribcradle
2 06:30:00.0 06:45:00.0 adlfurn
2 06:45:00.0 06:55:00.0 adlfurn
2 06:55:00.0 07:45:00.0 gndfl
2 07:45:00.0 07:55:00.0 arms
2 07:55:00.0 08:30:00.0 gndfl
2 08:30:00.0 08:50:00.0 hichair
2 08:50:00.0 09:45:00.0 strowlkr
2 09:45:00.0 10:00:00.0 cribcradle
2 10:00:00.0 11:00:00.0 cribcradle
2 11:00:00.0 11:05:00.0 cribcradle
2 11:05:00.0 11:15:00.0 hichair
2 11:15:00.0 11:35:00.0 infcarry
2 11:35:00.0 12:30:00.0 gndfl
2 12:30:00.0 13:00:00.0 hichair
2 13:00:00.0 13:30:00.0 gndfl
2 13:30:00.0 15:15:00.0 cribcradle
2 15:15:00.0 16:20:00.0 carseat
2 16:20:00.0 18:30:00.0 arms
2 18:30:00.0 18:45:00.0 infcarry
2 18:45:00.0 19:45:00.0 carseat
2 19:45:00.0 20:05:00.0 arms
2 20:05:00.0 06:00:00.0 cribcradle
3 06:00:00.0 07:00:00.0 adlfurn
3 07:00:00.0 07:05:00.0 adlfurn
3 07:05:00.0 07:45:00.0 arms
3 07:45:00.0 08:00:00.0 gndfl
3 08:00:00.0 08:15:00.0 hichair
3 08:15:00.0 08:30:00.0 adlfurn
3 08:30:00.0 08:45:00.0 strowlkr
3 08:45:00.0 09:00:00.0 arms
3 09:00:00.0 11:30:00.0 gndfl
3 11:30:00.0 12:30:00.0 hichair
3 12:30:00.0 15:00:00.0 cribcradle
3 15:00:00.0 15:25:00.0 hichair
3 15:25:00.0 17:00:00.0 gndfl
3 17:00:00.0 17:15:00.0 carseat
3 17:15:00.0 17:30:00.0 hichair
3 17:30:00.0 17:45:00.0 gndfl
3 17:45:00.0 18:05:00.0 carseat
3 18:05:00.0 18:25:00.0 arms
3 18:25:00.0 18:40:00.0 carseat
3 18:40:00.0 19:10:00.0 gndfl
3 19:10:00.0 19:25:00.0 hichair
3 19:25:00.0 19:45:00.0 carseat
3 19:45:00.0 19:50:00.0 arms
3 19:50:00.0 19:55:00.0 adlfurn
3 19:55:00.0 20:05:00.0 arms
3 20:05:00.0 20:10:00.0 adlfurn
3 20:10:00.0 20:15:00.0 arms
3 20:15:00.0 20:20:00.0 adlfurn
3 20:20:00.0 20:25:00.0 arms
3 20:25:00.0 03:30:00.0 cribcradle
3 03:30:00.0 04:00:00.0 arms
3 04:00:00.0 06:00:00.0 adlfurn
Here is an example from a published article of what I want (but in my case I'd have multiple colors depicting different locations)
Here is the script I currently have that provides a disjointed time line using onsets of locations. I also need to sort the time in the figure to display data from 6:00am current until 6:00am the following day. I'd like the bars to be continuous.
Thank you for your help!!
ggplot(loc_us) +
geom_raster(aes(x=onset, y=id, fill = location)) +
coord_equal() + theme_classic() +
theme(legend.position="bottom") +
scale_x_discrete(breaks=c("00:00:00.0", "06:00:00.0", "12:00:00.0", "20:00:00.0"))
photo of output my script is giving me
By converting onset
and offset
to datetime this can be achieved via geom_rect
. The tricky part is the conversion to datetime and setting the correct dates. For the datetime conversion I first convert to periods using lubridate::hms
and then to datetime via lubridate::as_datetime
. Second, as the datetime conversion adds January 1, 1970 as the date we have to correct the dates in a second step, i.e. add one day to times between 00:00:00
and 06:00:00
or if offset
time > onset
time.
library(ggplot2)
library(dplyr)
loc_us %>%
mutate(
# convert to datetime
onset = lubridate::as_datetime(lubridate::hms(onset)),
offset = lubridate::as_datetime(lubridate::hms(offset)),
# set correct dates
onset = case_when(
onset < lubridate::as_datetime(lubridate::hms("06:00:00")) ~ onset + lubridate::days(1),
TRUE ~ onset),
offset = case_when(
offset < onset ~ offset + lubridate::days(1),
TRUE ~ offset)
) %>%
ggplot() +
geom_rect(aes(xmin=onset, xmax = offset, ymin=id-.4, ymax = id + .4, fill = location), color = "white") +
scale_x_datetime(date_labels = "%H:%M") +
theme_classic() +
theme(legend.position="bottom")
Created on 2020-05-25 by the reprex package (v0.3.0)