Search code examples
rggplot2pie-chart

Scaling multiple pie charts in a grid according to their sample size in R


I want to create a grid containing 3 pie charts (my real data is big and here is an example) with each chart being scaled according to its sample size. For example, the plot for row 2, location b, should have the minimum size and row 3, location c should have the maximum size. Here is a similar question: Scaling multiple pie charts in a grid according to their size in R using ggplot2

Could you please help me with that?thank you.

here is my df:

x <- data.frame(
  location = c("a", "b", "c"),
  samplesize = c(26, 3, 96),
  a1 = c(12, 2, 77),
  a2 = c(24, 1, 31),
  a3 = c(15, 2, 56)
)

Solution

  • I would probably just roll my own pie chart function and draw this with geom_polygon:

    library(tidyverse)
    
    make_pie <- function(x, y, size, groups, n, rownum) {
      angles <- c(0, 2*pi * cumsum(n)/sum(n))
      do.call("rbind", Map(function(a1, a2, g) {
        xvals <- c(0, sin(seq(a1, a2, len = 30)) * size, 0) + x
        yvals <- c(0, cos(seq(a1, a2, len = 30)) * size, 0) + y
        data.frame(x = xvals, y = yvals, group = g, rownum = rownum)
      }, head(angles, -1), tail(angles, -1), groups))
    }
    
    x %>%
      mutate(r = row_number()) %>%
      mutate(x = 1:3, y = 1) %>%
      rowwise() %>%
      group_map(~ with(.x, make_pie(x, y, sqrt(samplesize)/20, 
                                    c("a1", "a2", "a3"),
                                    c(a1, a2, a3), r))) %>%
      bind_rows() %>%
      ggplot(aes(x, y, fill = group, group = interaction(group, rownum))) +
      geom_polygon() +
      annotate("text", x = 1:3, y = 1.6, label = c("a", "b", "c"), size = 7) +
      coord_equal() +
      theme_void(base_size = 20)
    

    enter image description here