rggplot2

geom_boxplot: reorder within a group


Assume some data and a corresponding box plot

random_data = data.frame("name" = rep(c("A", "B"), each = 500),
                         "nodes" = rep(c("X", "Y"), times = 500),
                         "type" = rep(c("I", "II", "III", "IV"), times = 10, each = 25),
                         "value" = rnorm(1000))


ggplot(random_data, aes(y = nodes, 
                        fill = type, 
                        x = value)) +
  geom_boxplot(alpha = 1) +
  facet_wrap(~name) +
  theme_bw() 

Can boxplots in each facet name and within each nodes group be reordered by descending median (e.g. facet A, group Y, from top to bottom: type II,III,I,IV)? enter image description here


Solution

  • One option would be to use a helper column created as the interaction of nodes, name and type and set the order according to the median values. This helper column could then be mapped on the group= aes:

    library(ggplot2)
    library(dplyr, warn = FALSE)
    library(forcats)
    
    # Seed
    set.seed(123)
    
    random_data |>
      mutate(
        value_order = median(value),
        .by = c(nodes, name, type)
      ) |>
      arrange(name, nodes, value_order) |>
      mutate(
        group = interaction(name, nodes, type),
        group = forcats::fct_inorder(group)
      ) |>
      ggplot(aes(
        y = nodes,
        fill = type,
        x = value,
        group = group
      )) +
      geom_boxplot(alpha = 1) +
      facet_wrap(~name, scales = "free_y") +
      theme_bw()