rggplot2facet-grid

Add label on right y axis of two combined facet plots in R


I have combined two facet plots unsing ggplot2 and patchwork. Because my original data is rather complex, I can not handel it with just one facet_grid. So I combine the two plots after creating them seperately. However, I dont know how I can add a secon y-axis lab on the right of the combined plot.

Any ideas on how to do this? I have tried using e.g. scale_y_continuous(sec.axis = dup_axis(name = "second axis")) but nothing worked.

Here I created some example data and plots:


library(ggplot2)
library(patchwork)

# Create a sample dataset
data_sample <- data.frame(
  group = rep(c("A", "B"), each = 20),
  n_classes = rep(c("xyz", "zyx"), each = 10),
  indicator = rep(c("Indicator 1", "Indicator 2"), each = 20),
  ICC = runif(40, 0, 1), # Random values for x-axis
  extrapolation_rate = runif(40, 0, 1) # Random values for y-axis
)

basic_facet_plot1 <- ggplot(data_sample, aes(x = ICC, y = extrapolation_rate, color = group)) +
  geom_point() + # Adding points
  facet_grid(indicator ~ n_classes) + # Facetting on n_classes on the x-axis
  theme_minimal() + # Using a minimal theme
  labs(
    title = "Sample Facet Plot",
    y = "Something",
    color = "Group"
  ) +
  theme(
    axis.title.x = element_blank() # Remove x-axis title
    
  )

data_sample <- data.frame(
  group = rep(c("A", "B"), each = 20),
  n_classes = rep(c("abc", "cba"), each = 10),
  indicator = rep(c("Indicator 3", "Indicator 4"), each = 20),
  ICC = runif(40, 0, 1), # Random values for x-axis
  extrapolation_rate = runif(40, 0, 1) # Random values for y-axis
)


# double the plot
basic_facet_plot2 <- ggplot(data_sample, aes(x = ICC, y = extrapolation_rate, color = group)) +
  geom_point() + # Adding points
  facet_grid(indicator ~ n_classes) + # Facetting on n_classes on the x-axis
  theme_minimal() + # Using a minimal theme
  labs(
    y = "Something else",
    color = "Group",
    x = "ICC",
  ) 

# Print the plot
basic_facet_plot2


# Adjust plot margins (you may need to tweak the margin sizes for your specific plots)
basic_facet_plot1 <- basic_facet_plot1 + theme(plot.margin = margin(t = 1, r = 1, b = -2, l = 1, unit = "cm"))
basic_facet_plot2 <- basic_facet_plot2 + theme(plot.margin = margin(t = 0, r = 1, b = 0, l = 1, unit = "cm"))

# Combine plots vertically with reduced space
combined_plot <- (basic_facet_plot1  / basic_facet_plot2) 
# comes from patchwork

print(combined_plot)

# Add legend below the plots
final_plot <- combined_plot + plot_layout(guides = 'collect') & theme(legend.position = 'bottom') 


# Print the final plot with legend below
print(final_plot)


red where I want to add a text


Solution

  • As suggested by @JonSpring in the comments you can use dup_axis to add a secondary axis title where I also used breaks = NULL to drop the ticks and labels. Finally use axes="collect_y" in plot_layout to have only one title for both plots:

    library(ggplot2)
    library(patchwork)
    
    # Create a sample dataset
    data_sample <- data.frame(
      group = rep(c("A", "B"), each = 20),
      n_classes = rep(c("xyz", "zyx"), each = 10),
      indicator = rep(c("Indicator 1", "Indicator 2"), each = 20),
      ICC = runif(40, 0, 1), # Random values for x-axis
      extrapolation_rate = runif(40, 0, 1) # Random values for y-axis
    )
    
    basic_facet_plot1 <- ggplot(
      data_sample,
      aes(x = ICC, y = extrapolation_rate, color = group)
    ) +
      geom_point() + # Adding points
      facet_grid(indicator ~ n_classes) + # Facetting on n_classes on the x-axis
      scale_y_continuous(
        sec.axis = dup_axis(breaks = NULL, name = "Foo")
      ) +
      theme_minimal() + # Using a minimal theme
      labs(
        title = "Sample Facet Plot",
        y = "Something",
        color = "Group"
      ) +
      theme(
        axis.title.x = element_blank() # Remove x-axis title
      )
    
    data_sample <- data.frame(
      group = rep(c("A", "B"), each = 20),
      n_classes = rep(c("abc", "cba"), each = 10),
      indicator = rep(c("Indicator 3", "Indicator 4"), each = 20),
      ICC = runif(40, 0, 1), # Random values for x-axis
      extrapolation_rate = runif(40, 0, 1) # Random values for y-axis
    )
    
    
    # double the plot
    basic_facet_plot2 <- ggplot(data_sample, aes(x = ICC, y = extrapolation_rate, color = group)) +
      geom_point() + # Adding points
      facet_grid(indicator ~ n_classes) + # Facetting on n_classes on the x-axis
      scale_y_continuous(
        sec.axis = dup_axis(breaks = NULL, name = "Foo")
      ) +
      theme_minimal() + # Using a minimal theme
      labs(
        y = "Something else",
        color = "Group",
        x = "ICC",
      )
    
    # Adjust plot margins (you may need to tweak the margin sizes for your specific plots)
    basic_facet_plot1 <- basic_facet_plot1 + theme(plot.margin = margin(t = 1, r = 1, b = -2, l = 1, unit = "cm"))
    basic_facet_plot2 <- basic_facet_plot2 + theme(plot.margin = margin(t = 0, r = 1, b = 0, l = 1, unit = "cm"))
    
    # Combine plots vertically with reduced space
    combined_plot <- (basic_facet_plot1 / basic_facet_plot2)
    # comes from patchwork
    # Add legend below the plots
    final_plot <- combined_plot +
      plot_layout(guides = "collect", axes = "collect_y") &
      theme(legend.position = "bottom")
    
    # Print the final plot with legend below
    print(final_plot)