Search code examples
rggplot2axis-labels

Only show one part of interacting x variable in x-axis labels in ggplot


I am plotting interacting variables on the x-axis of a ggplot, for example as below. Since I am using a fill color to indicate one of the values (here, variable), I would only like my x-axis labels to display the other variable (here, study_day). I can't specify a manual scale (scale_x_discrete(labels = c('1', '1', '1', '2', '2', '2')) because my study_day values may vary in each facet, as in this example. How do I indicate to only label the x-axis with study_day?

set.seed(1)
df <- data.frame(variable = rep(c('A', 'B', 'C'), 8),
                 study_day = rep(c('1', '2'), 12),
                 ID = rep(c('W', 'X', 'Y', 'Z'), 6),
                 value = rnorm(24))

ggplot(df, aes(interaction(variable, study_day), value))+
  geom_point(shape = 21, aes(fill = variable))+
  facet_wrap(~ID, scales = 'free')

enter image description here


Solution

  • You can write a make_labels() function that extracts the study day from the labels ggplot2 generates:

    library(stringr)
    
    make_labels <- function(labels) {
      result <- str_split(labels, "\\.")
      unlist(lapply(result, function(x) x[2]))
    }
    
    set.seed(1)
    df <- data.frame(variable = rep(c('A', 'B', 'C'), 8),
                     study_day = rep(c('1', '2'), 12),
                     ID = rep(c('W', 'X', 'Y', 'Z'), 6),
                     value = rnorm(24))
    
    ggplot(df, aes(interaction(variable, study_day), value))+
      geom_point(shape = 21, aes(fill = variable))+
      facet_wrap(~ID, scales = 'free') +
      scale_x_discrete(labels = make_labels, name = "study day")
    

    enter image description here