ggplot time series interval stacked bars

Viewed 93

I have a massive data file that I am breaking down into day blocks by person and then plotting events that occurred during the day and the duration of those events (either A, B or C)

Data is structured like below: t_z is the interval between rows, period is the event variable, this example is for one individual for one day ( actual data is xdays xpersons)

intervals <- c(0,5.1166667,6.2166667,3.5166667,0.06666667,3.0666667,6.3,
               2.3833333,0.06666667,4.7,18.666667,17.383333,21.533333,
               0.1,0.08333333,0.85)
period <- c("C",    "B",    "A",    "B",    "C",    "B",    "C",    "B",
            "C",    "B",    "C",    "B",    "C",    "B",    "C",    "B")
i <- as.data.frame(intervals)
p <- as.data.frame(period)
d <- cbind(i,p)

Getting a bar plot is easy enough but it stacks all "periods" into blocks by day:

d$id<-1
e <- ggplot(d,aes(id))
e + geom_bar(aes(fill=period))

Simple aggregated stacked bar of time data: Simple aggregated stacked bar of time data

However, I would like each "period" to be represented discretely and by its magnitude:

Periods as discrete stacked blocks example: Periods as discrete stacked blocks example

Thanks YBS but your method comes close but the size of the periods is not correct any ideas? The first C=5 is not the same size as the first A=5?

intervals <- c(5, 15, 5, 3,7,3,6, 2)
period <- c("C","B","A","B","C","B","C","B") 

d <- data.frame(intervals,period)
colors=c("red","blue","green")
dc <- data.frame(period=unique(d$period),colors)
d2 <- d %>% mutate(nid = paste0(d$period,'_',row_number()))
d3 <- left_join(d2,dc, by="period")
d3$id<-1

e <- ggplot(d3,aes(x=id, y=intervals)) +
  geom_col(aes(fill=nid)) 
e + scale_fill_manual(name='period', labels=d3$period, values=d3$colors )

Block sizes not in proportion to their interval values

1 Answers

The trick is to create a newid with all the discrete values, and then reverting back to initial period values via scale_fill_manual. You can use coord_flip() to make it horizontal and change the legend position as necessary. Perhaps this is the desired output.

intervals <- c(0, 5.1166667, 6.2166667, 3.5166667,0.6666667,3.0666667,6.3, 2.3833333)
               #,0.06666667 , 4.7,18.666667,17.383333,21.533333, 0.1,0.08333333,0.85)
period <- c("C",    "B",    "A",    "B",    "C",    "B",    "C",    "B") 
            # ,"C",    "B",    "C",    "B",    "C",    "B",    "C",    "B")

d <- data.frame(intervals,period)

colors=c("red", "blue","green")

dc <- data.frame(period=unique(d$period),colors)

d2 <- d %>% mutate(nid = paste0(d$period,'_',row_number()))

d3 <- left_join(d2,dc, by="period")

d3$id<-1

e <- ggplot(d3,aes(x=id, y=intervals)) +
       geom_col(aes(fill=nid)) 
e + scale_fill_manual(name='period', labels=d3$period, values=d3$colors )

output

Related