Control Individual Breaks/Labels Facet Grid / ggplot2

I have the ggplot2 code below that produces the plot attached. I would like to know if it would be possible to control the individual y-axis breaks/labels. For instance, I would like to have them for the Mean Depth as "1X", "2X" "3X" and "4X" & for Percentage of Retained Reads I would like to have "10%", "20%", "30%" and "40%". I guess I would need to use something like scale_y_continuous for each individual facet, but I have not been able to find a way of doing so.

Many thanks in advance, George.

ggplot() +
  geom_violin(data = fulldfUp, aes(x = Species, y = Value),
              fill = "#ffffff", colour = "#000000", show.legend = FALSE, alpha = .9, size = .3, width = .7) +
  stat_summary(data = fulldfUp, aes(x = Species, y = Value),  
               fun = mean, geom = "point", shape = 21, size = 3.5, alpha = .9, colour = "#000000", fill = "#fc3232") +
  facet_grid(Estimate ~. , scales = "free", labeller = labeller(Estimate = ylabels)) +
  scale_fill_manual(values = c("#fbb4ae", "#b3cde3", "#ccebc5", "#decbe4", "#fed9a6")) +
  scale_colour_manual(values = c("#fbb4ae", "#b3cde3", "#ccebc5", "#decbe4", "#fed9a6")) +
  theme(panel.background = element_rect(fill = "#ffffff"),
        panel.grid.major.x = element_line(color = "#ededed", linetype = "dashed", size = .00005),
        panel.grid.major.y = element_blank(),
        panel.grid.minor = element_blank(), 
        panel.border = element_blank(),
        axis.line = element_line(colour = "#000000", size = .3),
        axis.title = element_blank(),
        axis.text.x = element_text(colour = "#000000", size = 20, face = "bold", angle = 45, vjust = 1, hjust = 1),
        axis.text.y = element_text(color = "#000000", size = 20),
        axis.ticks.x = element_line(color = "#000000", size = .3),
        axis.ticks.y = element_line(color = "#000000", size = .3),
        strip.background.y = element_rect(colour = "#000000", fill = "#d6d6d6", size = 0.3),
        strip.text = element_text(colour = "#000000", size = 20, face = "bold"),
        legend.position = "top",
        legend.margin = margin(t = 0, b = 0, r = 0, l = 0),
        legend.box.margin = margin(t = 10, b = 20, r = 0, l = 0),
        legend.key = element_rect(fill = NA),
        legend.background = element_blank())

The labels argument of scale_y_continuous can be a function that takes breaks as input and returns labels as output. To specify a different function for each facet in a plot, you can use a global variable to keep track of the plot index.

library(tidyverse)
library(palmerpenguins)
dummy_data <- penguins %>% pivot_longer(cols = where(~ !is.factor(.x)), names_to = "Estimate", values_to = "Value")

plot_index <- 0 # Based on: https://coolbutuseless.github.io/2019/03/07/custom-axis-breaks-on-facetted-ggplot/
label_fun <- function(x) {
    plot_index <<- plot_index + 1L
    switch(plot_index,
           scales::label_number(accuracy = 1, suffix = "X", big.mark = "")(x),
           scales::label_percent(scale = 1)(x),
           scales::label_percent(scale = 0.01)(x),
           scales::label_number_auto()(x),
           scales::label_number(accuracy = 1, big.mark = "")(x))
}

ggplot() +
    geom_violin(data = dummy_data, aes(x = species, y = Value)) +
    facet_grid(Estimate ~ . , scales = "free") +
    scale_y_continuous(labels = label_fun) 
#> Warning: Removed 8 rows containing non-finite values (stat_ydensity).


Created on 2021-11-12 by the reprex package (v2.0.1.9000)

1 Like

Hej,

I have managed to improve the plot with the function below, but it does not solve all the issues as you can see, and I cannot see why :frowning:

# Custom y-axis breaks ~
breaks_fun <- function(x){
  if (max(x) < 5){
    c(0.5, 1.5, 2.5, 3.5)}
  else if (max(x) > 90 || max(x) < 100){
    c(96, 97, 98, 99)}
  else if (max(x) > 6 || max(x) < 50){
    c(10, 20, 30, 40)}
  else{
    c(5000000, 15000000, 25000000, 35000000)}}

Hello,

I have managed to solve the issue with the function below:

# Custom y-axis breaks ~
breaks_fun <- function(x){
  if (max(x) < 5){
    c(0.5, 1.5, 2.5, 3.5)}
  else if (max(x) > 90 && max(x) < 100){
    c(96, 97, 98, 99)}
  else if (max(x) > 6 && max(x) < 50){
    c(10, 20, 30, 40)}
  else{
    c(5000000, 15000000, 25000000, 35000000)}}

Thanks again for your help.

Best regards, George.