Search code examples
rggvis

Adding labels to stacked bar charts - ggvis


Is there a way to append labels to stacked bar charts in ggvis?

Sample Code:

plotData = data.frame(v1    = c("ABC", "ABC", "ABC", "XYX","XYX","XYX"), 
                      v2    = c("A"  , "B"  , "C"  , "X"  ,"Y"  ,"Z"  ),
                      value = c(30   ,  60  , 10   ,  20  , 40  , 40  ))

plotData %>%
  ggvis(y = ~v1, fill = ~v2) %>%
  compute_stack(stack_var = ~value, group_var = ~ v1) %>% 
  layer_rects(x = ~stack_lwr_, x2 = ~stack_upr_, height = band()) %>%
  add_axis("y", title = "Variable") %>%
  add_axis("x", title = "Percentage") 

Plot output:

enter image description here

Preferred output - How would I modify the above chart to add labels to individual stacks? :

enter image description here


Solution

  • This is not an ideal solution but I'll post it anyway as it may give you a way forward.

    Basically, I create a new column to specify the position of the label, and use that to place the text onto the graph.

    I haven't figured out how to put a % onto the labels yet though.

    library(ggvis)
    
    plotData = data.frame(v1    = c("ABC", "ABC", "ABC", "XYX","XYX","XYX"), 
                          v2    = c("A"  , "B"  , "C"  , "X"  ,"Y"  ,"Z"  ),
                          value = c(30   ,  60  , 10   ,  20  , 40  , 40  ))
    
    library(dplyr)
    
    ## This can be shortened, but I'm leaving it as is to show the steps
    plotData <- plotData %>%
      group_by(v1) %>%
      mutate(cs = cumsum(value)) %>%
      mutate(pos = ifelse(is.na(cs - lag(cs)), cs, (cs - lag(cs)))) %>%
      mutate(pos = cs - (pos/2)) %>%
      ungroup
    
    plotData %>%
      ggvis(y = ~v1, fill = ~v2) %>%
      compute_stack(stack_var = ~value, group_var = ~ v1) %>% 
      layer_rects(x = ~stack_lwr_, x2 = ~stack_upr_, height = band()) %>%
      add_axis("y", title = "Variable") %>%
      add_axis("x", title = "Percentage") %>%
      layer_text(x = prop("x", ~pos),
                 y = prop("y", ~v1, scale = "ycenter"),
                 text:=~value, fill := "white", fontSize:=20) 
    

    enter image description here