0

I'm working with bedtime and waketime, so I would like to create a graph with a 24h x axis, starting at 12pm on day 1 and ending at 12pm on day 2. Meaning that after 11:59pm, it should start at 0 again.

Same question with number only, I'd like to create a scale from 10 to 20 and after 20 start at 1 again until 10.

This is the code that I have for now:

ggplot(SLEEP2, aes(x=as.POSIXct(bedT, format="%H:%M"), y=Jour))+ 
geom_rect(aes(xmin=as.POSIXct(sleepT, format="%H:%M"), xmax=as.POSIXct(wakeT, 
format="%H:%M"),ymin=(Jour-0.4), ymax=(Jour+0.4)),fill="orange", 
color="black")+ scale_x_datetime()

Voici un bout de mes données:

dat <- data.frame(Jour=1:5,
              date=seq.Date(as.Date("2020-10-01"), as.Date("2020-10-05"), "day"),
              sleeptime=c("22:30","21:10","23:00","23:00", "23:20"),
              waketime= c("6:30", "7:00", "7:30", "6:25","7:10"))

I'd like to represent their sleep time with bars...

How can I do that? I tried several option but nothing is working. Thank you.

Virginie
  • 67
  • 5
  • 2
    Hello, to make your question [reproducible](https://stackoverflow.com/a/5963610/5619526) could you please share some of your data? You can use the `dput` function. Providing the data makes it more likely for people on SO to help you. – bouncyball Jan 14 '21 at 14:13
  • @bouncyball like that? – Virginie Jan 14 '21 at 15:39
  • 1
    Hi Virginie. Providing data and code is an improvement. However, it would be nice if your code would work with the data provided. Additionally could you clarify how your desired plot should like? Would you like an axis from 12pm on day1 to 12pm on day2 and the bars for each day "stacked" on top of each other or ...? – stefan Jan 14 '21 at 17:52

1 Answers1

0

Edit at bottom to include given data.

If there's a way to get the graph's axis transformed like maybe is more intuitive I don't know. I couldn't figure that out.

As other's mentioned having some sample data in your code would be helpful so that solutions could use it instead of having to guess and/or make up our own. Including a picture of what you have and/or want is also good.

Something like:

R> head(SLEEP2)
...

Anyways, here's one way of doing it. It's not at all elegant but it works.

First, make some "untransformed" data that peaks at midnight and plot it. I'm guessing this looks something like what you have already.

library(tidyverse)
library(lubridate)

start <- ymd_hm("20210101-0000")
# Make some pretend data. It's value is zero during the "day"
# and peaks around midnight.
secsday <- 60*60*12
df <- tibble(date_time = seq(start, start %m+% weeks(2), by=200)) %>%
    mutate(time = hms::as_hms(date_time),
           date = factor(date(date_time)),
           values = jitter(cos(day(date_time)/30+pi*as.numeric(time)/secsday), amount=1/40),
           values = ifelse(values>0, values, 0)
    )

# Plot original data.
ggplot(df, aes(time, values, colour=date)) +
    geom_line() +
    scale_x_time(breaks=hours(seq(0,24,6)), labels=c("midnight","6AM","noon","6pm","midnight")) +
    ggtitle('pre-transform')

pre-transform ggplot

Next, translate AM to PM and PM to AM.

# Transform times so AM is PM and PM is AM (swap around noon).
dt <- df %>% mutate(time=
            ifelse(time>hm("12:00"), hms::as_hms(time)-secsday, hms::as_hms(time)+secsday)
        )
ggplot(dt, aes(time, values, colour=date)) +
    geom_line() +
    scale_x_time(breaks=hours(seq(0,24,6)), labels=c("noon", "6PM", "midnight", "6AM", "noon")) +
    ggtitle('post-transform')

post-transform ggplot

I'd like to know if there's a way of doing this by only adjusting the axis instead of the data.

With the data you provided and using bars:

library(lubridate)
dat <- data.frame(Jour=1:5,
                  date=seq.Date(as.Date("2020-10-01"), as.Date("2020-10-05"), "day"),
                  sleeptime=c("22:30","21:10","23:00","23:00", "23:20"),
                  waketime= c("6:30", "7:00", "7:30", "6:25","7:10"))

# make fake dates for sleep and wake
dat <- dat %>% mutate(
            sleep = ymd_hm(paste(dat[1,]$date, sleeptime)),
            wake = ymd_hm(paste(dat[1,]$date, waketime)),
            wake = wake + ddays(ifelse(lubridate::hm(waketime)<lubridate::hm(sleeptime), 1, 0))
        )

ggplot(dat, aes(xmin=sleep, xmax=wake)) +
    scale_x_datetime(breaks=ymd(dat[1,]$date) + hours(seq(12,36,length.out=5)),
                     labels=c("noon", "6PM", "midnight", "6AM", "noon"),
                     limits=ymd(dat[1,]$date) + hours(seq(12,36,length.out=2))
                     ) +
    geom_rect(ymin=0.25, ymax=0.75, fill='darkgreen') +
    ylim(0,1) +
    facet_grid(rows = vars(date)) +
    theme(axis.title = element_blank()) +
    theme(axis.text.y = element_blank(),
          axis.ticks = element_blank()
    )

ggplot with bars and user supplied data

keithpjolley
  • 2,089
  • 1
  • 17
  • 20