Search code examples
rggplot2data.tableggvis

Create a plot which highlight the weeks for which records exists by group for any of the day in table


Let's say that the data.table dt looks like this:

library(data.table)
dt <- data.table(grp = c("01", "01","01", "01", "01", "01", "01", "01", "02", "02", "02",
                     "03", "03", "03",
                     "04", "04", "04", "04"),
             date = c("2012-04-18", "2012-04-19","2012-04-30", "2012-05-10", "2012-06-23", "2012-06-25", 
                      "2012-07-05", "2012-07-06", 
                      "2012-04-07", "2012-04-19", "2012-04-05",
                      "2012-04-04", "2012-04-22", "2012-04-25", 
                      "2012-05-19", "2012-06-05", "2012-06-26", "2012-06-27"))



> dt
    grp       date
 1:  01 2012-04-18
 2:  01 2012-04-19
 3:  01 2012-04-30
 4:  01 2012-05-10
 5:  01 2012-06-23
 6:  01 2012-06-25
 7:  01 2012-07-05
 8:  01 2012-07-06
 9:  02 2012-04-07
10:  02 2012-04-19
11:  02 2012-04-05
12:  03 2012-04-04
13:  03 2012-04-22
14:  03 2012-04-25
15:  04 2012-05-19
16:  04 2012-06-05
17:  04 2012-06-26
18:  04 2012-06-27

I want to create a plot for each of the groups grp highlighting the weeks for which I have records. I wanted a chart something like this:

Bad paint skills

So I tried the following but it is only putting a | on the days i have records

ggplot(dt) +
   aes(y = grp, x = as.Date(date)) +
   geom_segment(aes(yend = grp, 
                    xend = as.Date(date), 
                    color = grp), 
                size = 6,
                show.legend = FALSE) +
   geom_text(aes(label = grp), 
             nudge_x = 3,
             size = 5) +
   scale_x_date('Date', date_breaks = '7 days', expand = c(0, 2)) +
   scale_color_brewer(palette = 'Set3') +
   theme_bw() +
   theme(axis.line.y = element_blank(),
         axis.text.y = element_blank(),
         axis.ticks.y = element_blank())

Right now my plot is looking like this:enter image description here How can I improve my plot to the desired one?


Solution

  • Would this work for you? For each date in dt it grabs the start of the week and the end of the week that it falls in. Then it plots a line segment for each start/end week combination. Per Henrik's comment, used floor_date/ceiling_date. I need to as.Date the ceiling_date because, it rounds the week up to the 20th hour so it returns a class of POSIXct.

    library(lubridate)
    
    dt$start_week <- floor_date(as.Date(dt$date), unit = "week")
    dt$end_week <- as.Date(ceiling_date(as.Date(dt$date), unit = "week"))
    
     ggplot(dt, aes(y = grp)) + geom_segment(aes(x = start_week, xend = end_week, yend = grp)) + 
      geom_text(aes(x = as.Date(date), label = grp), nudge_x = 3, size = 5) + 
      theme_bw()+
      theme(axis.text.x=element_text(angle=45,hjust=1,vjust=1))+ 
      scale_x_date('Date', date_breaks = '7 days', expand = c(0, 2)) + 
      scale_color_brewer(palette = 'Set3') + 
      theme(axis.line.y = element_blank(), axis.text.y = element_blank(), axis.ticks.y = element_blank())
    

    enter image description here