Search code examples
ggplot2tidyversegt

Hierarchically structured Y-label for barbell ggplots


tibble(Class = c("A","A","B","B"),
       Country = c("UK","US","UK","US"),
       Label = str_c(Class,"-",Country),
       PRE = c(0,1,2,3),
       POST = c(4,5,6,7)) %>%
  ggplot() +
  geom_segment(aes(x=PRE, xend=POST,
                   y=Label, yend=Label), color="green") +
  geom_point(aes(x=POST, y=Label),
             color = "navy") +
  geom_point(aes(x=PRE, y=Label),
             color = "salmon") +
  xlab("shift")

I don't like in this code that it repeats the Class before each label. Ideally, I want 2 hierarchical labels for the plot: at higher level Class, which then splits for UK and US, so that it's easy to compare the barbells of the two countries for the same class.

Alternatively, is there a way to represent the same structure with a gt-table, where one column is the individual barbell of the combination Class and Country??


Solution

  • Hierarchically structuring plots with facet_grid

    Generate some toy data

    set.seed(123)
    df <- data.frame(
      Class = rep(LETTERS[1:19], each = 4),
      Country = rep(c("UK","US"), 19),
      Measure = rep(c("Measure_A", "Measure_B"), times = 19, each = 2),
      PRE = sample(0:10, 76, replace = TRUE)
    )
    

    Create a plot

    library(tidyverse)
    df %>%
      mutate(POST = PRE + sample(2:5)) %>%
      ggplot() +
      geom_segment(aes(x = PRE, xend = POST,
                       y = Country, yend = Country), color = 'green') +
      geom_point(aes(x=POST, y=Country),
                 color = "navy") +
      geom_point(aes(x=PRE, y=Country),
                 color = "salmon") +
      labs(x = "Shift") +
      facet_grid(Class ~ Measure,
                 switch = 'y') +
      theme(strip.background = element_blank(),
            strip.placement = 'outside',
            panel.spacing.y = unit(0.1, "lines"))
    

    Created on 2023-10-10 with reprex v2.0.2