Search code examples
rggplot2waffle-chart

How to make a faceted waffle chart, filling each bin from top left


I'm trying to create a 3x4 grid of bins with a count of observations from my data in each bin. I'm halfway there:

library(ggplot2)
type <- c('daily', 'daily', 'habit', 'habit', 'habit', 'seasonal', 'seasonal', 'year-long', 'year-long', 'year-long', 'year-long', 'year-long')
status <- c('complete', 'incomplete', 'push', 'push', 'incomplete', 'complete', 'complete', 'complete', 'complete', 'push', 'push', 'incomplete')
results <- data.frame(type, status)

ggplot(results) +
  geom_dotplot(aes(x=status, y=type), binwidth=.2) +
  facet_grid(vars(type))

result

Clearly the y-axis is meaningless right now - I'm not sure if geom_dotplot is the right thing to use. I can get similar results with geom_histogram or geom_bar as well.

I'd like dots to start in the upper left corner of each bin. Is this possible? I've tried to use the waffle package but can't figure it out. Ideally each dot will be a square, which isn't possible using geom_dotplot, so I'd prefer to use waffle if I can.


Solution

  • There is currently an open issue with that waffle package which prevented me from producing the chart the way I wanted to (getting an error "invalid 'times' argument"), using facet_grid along both status and type.

    Alternatively, we can do some data prep to create something similar.

    rows <- 4
    cols <- 4
    
    results %>%
      arrange(status, type) %>%
      group_by(status, type) %>%
      mutate(num = row_number(),
             x_pos = (num - 1) %/% rows,
             y_pos = rows - (num - 1) %% rows - 1) %>%
    
      ggplot(aes(x = x_pos, y = y_pos)) +
      geom_tile(fill = "black", color = "white") +
      coord_equal(xlim = c(0, cols) - 0.5,
                  ylim = c(0, rows) - 0.5) +
      facet_grid(vars(type), vars(status)) +
      theme_light() +
      theme(panel.grid = element_blank(),
            axis.text = element_blank())
    

    enter image description here