rggplot2treemap

Consistent layout of groups within subgroups in treemapifyr


I've got a three-level dataset, where the values of the intermediate categories are distinct to the largest categories, but where the (2) values of the smallest categories are consistent within each of the intermediate categories.

I'm using treemapifyr, and I'd like the layout to consistently have one of the smallest categories either on the left-hand side or on the top of the intermediate category. At the moment, these intermediate categories sometimes have horizontal splits, and at other times have vertical splits.

This reprex illustrates the issue:

library(tidyverse)
library(treemapifyr)

example_data <- 
  data.frame(Number = c(8.989663702,14.93294526,
                          5.727538109,11.47738226,5.962484342,5.528905863,
                          13.89280722,19.05866541,10.17157544,11.59719022,
                          17.93635842,2.034230053,13.38663681,8.729627328,
                          11.16785702,3.345153661,4.826922784,11.24138854),
                  Big = c("First","First","First",
                          "First","First","First","Second","Second",
                          "Second","Second","Third","Third","Third","Third",
                          "Third","Third","Third","Third"),
         Intermediate = c("A","A","B","B","C",
                          "C","D","D","E","E","F","F","G","G","H","H",
                          "I","I"),
                Small = c("Alpha","Beta","Alpha",
                          "Beta","Alpha","Beta","Alpha","Beta","Alpha",
                          "Beta","Alpha","Beta","Alpha","Beta","Alpha",
                          "Beta","Alpha","Beta")
   )
example_data %>% 
  group_by(Big, Intermediate) %>% 
  mutate(Fraction = 
           Number/sum(Number)) %>% 
  ggplot()+ 
  aes(area = Number,
      subgroup2 = Intermediate,
      subgroup = Big,
      group = Small) + 
  geom_treemap(aes(fill = Small)) +
  geom_treemap_subgroup2_border(colour = "gray50",
                                size = 2) +
  geom_treemap_subgroup_border(colour = "white") +
  geom_treemap_subgroup2_text(place = "centre") +
  geom_treemap_text(aes(label = round(Fraction, 2)))

treemap containing a three-level dataset, with polygons in pink and blue

If it's possible to have these configured so that the intermediate category (in this case, Intermediate) is always split side-by-side or top-to-bottom in the same order each time, that would be great. Thanks in advance!


Solution

  • You can apply a fixed layout instead of the default squarified one. All elements should have the same layout, to ensure borders and text line up with the rest of the plot. I also chose to change the starting position from the default in the bottomleft to the topleft. If that doesn't look good with your real data, you can experiment with starting from any corner.

    library(tidyverse)
    library(treemapify)
    
    layout = 'fixed'
    start = 'topleft'
    
    example_data %>% 
      group_by(Big, Intermediate) %>% 
      mutate(Fraction = 
               Number/sum(Number)) %>% 
      ggplot()+ 
      aes(area = Number,
          subgroup2 = Intermediate,
          subgroup = Big,
          group = Small) + 
      geom_treemap(aes(fill = Small),
                   layout = layout,
                   start = start) +
      geom_treemap_subgroup2_border(colour = "gray50",
                                    size = 2,
                                    layout = layout,
                                    start = start) +
      geom_treemap_subgroup_border(colour = "white",
                                   layout = layout,
                                   start = start) +
      geom_treemap_subgroup2_text(place = "centre",
                                  layout = layout,
                                  start = start) +
      geom_treemap_text(aes(label = round(Fraction, 2)),
                        layout = layout,
                        start = start)
    

    Created on 2023-09-29 with reprex v2.0.2