Search code examples
rggplot2facet-wrap

Strip label customization in facet_wrap


I want to shift the strip label of the facet graph in Col-2 to the right side. As i marked in the graph, enter image description here

I am using this code

library(reshape2)
library(tidyverse)
library(ggh4x)
library(scales)
library(ggplot2)
#step 1: mutate the data
df <- melt(df, id=c("Specie","Treatment"))
head(df)
#plotting
left  <- scale_y_continuous(labels = number_format(accuracy = 0.01))
right <- scale_y_continuous(labels = number_format(accuracy = 0.01),position = "right")

ggplot(df1, aes(x = Specie, y = mean, fill = Treatment, colour=Treatment)) +
  geom_col(position = position_dodge(), width = 0.8)+
  facet_wrap(~ variable, scales = "free_y", ncol = 2, 
             labeller = label_parsed, strip.position = "left")+
  geom_errorbar(aes(ymin = mean, ymax = mean + sd), width = 0.2,
                position = position_dodge(0.9)) +theme_bw()+
  geom_text(aes(y = mean+sd,label = label),position = position_dodge(0.9),
            size = 3.5, vjust=-0.2, family="serif", colour="black")+
  geom_text(aes(y = Q1/2,label = letter),size = 3.5, family="serif", colour="#000000")+
  scale_fill_manual(values=c('#DEB887','#CD853F'))+
  scale_color_manual(values=c('#DEB887','#CD853F'))+
  facetted_pos_scales(y = list(left, right, left, right, left, right))+
  #coord_flip()+
  theme(axis.text.x = element_text(face = "italic"),
        strip.placement = "outside",
        strip.background = element_blank())

Here is the example dataset

Treatment Specie Pn Gs E WUE
CT S. commersonii 4.8100 0.0736 1.1100 4.3333
CT S. commersonii 11.5000 0.4660 5.4400 2.1140
CT S. tuberosum 2x 16.4000 0.4930 5.5200 2.9710
CT S. tuberosum 2x 4.2400 0.0862 1.8100 2.3425
CT S. chacoense 3.9200 0.0426 0.7160 5.4749
CT S. chacoense 7.9000 0.1500 1.9400 4.0722
HS S. commersonii 10.1000 0.3520 6.0300 1.6750
HS S. commersonii 6.8500 0.3700 5.4600 1.2546
HS S. tuberosum 2x 4.7100 0.0205 0.8400 5.6071
HS S. tuberosum 2x 4.3400 0.0314 1.2450 3.4859
HS S. chacoense 13.8000 0.2450 6.4800 2.1296
HS S. chacoense 14.4000 0.1700 5.5100 2.6134

Solution

  • You could use the patchwork package and piece together two plots, making the labels be individual then patched together with a shared axis/legend. This doesn't include all the specifications in your plot (e.g., error bars, colors, text), but the general idea is:

    library(patchwork)
    
    
    #Creating dataset and adding grouping variable
    mod_iris <- iris %>% 
        group_by(Species) %>% 
        mutate(average_petal_length = mean(Petal.Length)) %>% 
        mutate(species_length_group = case_when(Petal.Length <= average_petal_length ~ "Short",
                                                TRUE ~ "Long")) %>% 
        select(-average_petal_length) %>% 
        ungroup() %>% 
        pivot_longer(cols = "Sepal.Length":"Petal.Width")  
    
    #Create two datasets
    
    #One for length
    
    iris_lengths_data <- mod_iris %>% 
        filter(!str_detect(name,"Width"))
    
    #This will be plot that has information on the left
    length_plot <- iris_lengths_data %>% 
        ggplot(aes(x = Species, y = value, fill = species_length_group, color = species_length_group)) +
        geom_bar(stat = "identity", position = "dodge") +
        facet_wrap(.~name, scales = "free_y", ncol = 1, strip.position = "left") +
        theme(strip.placement = "outside")
    
    
    
    #One for width
    
    iris_widths_data <- mod_iris %>% 
        filter(str_detect(name,"Width"))
        
    #This will be plot that has information on the right
    width_plot <- iris_widths_data %>% 
        ggplot(aes(x = Species, y = value, fill = species_length_group, color = species_length_group)) +
        geom_bar(stat = "identity", position = "dodge") +
        facet_wrap(.~name, scales = "free_y", ncol = 1, strip.position = "right") +
        scale_y_continuous(position = "right") +
        labs(y = NULL)+ #Removed to have just one y axis
        theme(strip.placement = "outside",
              strip.text.y.right = element_text(angle = 90))  #adjusted to have text in same direction as length plot
    
        
    
    #Patch together 
    iris_patch <- length_plot + width_plot + plot_layout(guides = "collect") & xlab(NULL) & theme(legend.position = "right")
    
    
    #Add common x-axis and position
    wrap_elements(panel = iris_patch) +
        labs(tag = "Species") +
        theme(plot.tag = element_text(size = rel(1)),
              plot.tag.position = c(.415, 0))
    

    enter image description here