rggplot2axis

Adding a split/broken axis to a ggplot2 code


I am trying to add a broken/split axis to my R code on the x-axis (actually the y-axis because it is flipped). However after many attempts (hours), the codes I apply doesn't work.

Edit- Adding sample data provided by LTyrone:

library(dplyr)
library(ggplot2) 
library(ggbreak)


Sample data df <- data.frame(Name = c("Ellesworth",
>                        "Elmer Thomas",
>                        "Frederick",
>                        "Lawtonka",
>                        "Walters (Dave Boyer)",
>                        "Waurika"),
>                  Result = c(47, 248, 30, 45, 48, 43))
> 
> df$Name <- factor(df$Name)

Codes I have tried:

scale_y_break(c(60,240), scales="free")

scale_y_break(c(60,240), scales='free',expand = expansion(mult = c(0,.5)))

scale_y_cut(breaks=c(60,240), which=c(1, 3), scales=c(3, 5))

My data is large but simple—lake names on the y-axis and chlorophyll levels on the x-axis. The attached picture is the closest I have come to applying a split axis, but this looks odd and does not accomplish what I want.

Broken axis attempt.

my code:

PB1_R_Data %>%
ggplot(., aes(x=Name, y = Result)) +

geom_col(aes(x=forcats::fct_rev(reorder(Name,Name)), y=MeanGrowSeason))+ 

(aes(x = Name, y = Result, fill = "Mean Chlorophyll a")) +

scale_fill_manual(name = NULL, values = c("Mean Chlorophyll a" = "#1ca6df")) +

geom_point(mapping=aes(y = `MaxGrowSeason`, pch = 16, color = "black"),  
size = 3, fill = "black", stat = "summary", fun=max)+

geom_hline(yintercept = 0, linetype = 'solid', color = 'black') +

geom_hline(aes(yintercept = 10, linetype = 'Middle'), color = "#d15420", 
size = 1) +

geom_hline(aes(yintercept = 20, linetype = 'Upper'), color = "#d15420", 
size = 1)+

labs(title = "PB1 (2002-2023)
Chlorophyll a for the Growing Season (May-Sep)",
x = "",
y=expression(plain("Chlorophyll ")~italic("a")~~plain("(mg/l)")), family="mono")+

labs(linetype='')+ 

theme_minimal() +
theme(axis.text=element_text(size=11,family = "Calibri", face="plain"),
legend.text = element_text(size=11,family = "Segoe UI", face="plain"),
axis.title.x = element_text(size=11, family = "Segoe UI", face="plain")) +

theme(text=element_text(size=12,family="Segoe UI"))+

theme(axis.text.x = element_text(angle=0))+
coord_flip() + 
 
scale_color_manual(values = c("#004e9a"),
labels = c("Maximum Chlorophyll a")) +
scale_shape_identity()+
labs(colour = "")+
theme(legend.position = "bottom")+
theme(plot.title = element_text(hjust = 0.5))

Solution

  • You haven't provided a minimal, reproducible example, but here's a reprex that will help. I haven't looked at the source code for ggbreak but it appears the default behaviour for scale_y_break() is to align axis titles to one of the 'splits' or to the far left.

    However, using hjust = and vjust =, you can customise title placement. You may need to rely on your 'eyechromometer' (e.g. trial and error) to get it how you want it. In this example, I have attempted to align your titles to the panel.grid. If you want your titles aligned to the entire plot, use hjust = 0.5. Also note the inclusion of expand = c(0, 0), this makes for a nicer looking plot IMO. This setting causes the axis labels either side of the break to overlap so I've adjusted the break space to 0.4 to avoid overlaps. You can remove these additions if they do not suit:

    library(dplyr)
    library(ggplot2)
    library(ggbreak)
    
    # Sample data
    df <- data.frame(Name = c("Ellesworth",
                           "Elmer Thomas",
                           "Frederick",
                           "Lawtonka",
                           "Walters (Dave Boyer)",
                           "Waurika"),
                     Result = c(47, 248, 30, 45, 48, 43))
    
    df$Name <- factor(df$Name)
    
    df %>%
      ggplot(., aes(x = factor(Name, level = rev(Name)), y = Result)) +
      coord_flip() +
      geom_point() +
      scale_y_continuous(breaks = seq(0,250,20), limits = c(0,250)) +
      scale_y_break(c(60,240), space = 0.4, ticklabels = c(seq(0,250,20), 250),
                    expand = c(0, 0)) +
      labs(title = "PB1 (2002-2023)
                    Chlorophyll a for the Growing Season (May-Sep)",
           x = "",
           y = expression(plain("Chlorophyll ")~italic("a")~~plain("(mg/l)")),
           family = "mono") +
      labs(linetyp = "") + 
      theme(axis.title.y = element_blank(),
            # Adjust to suit
            plot.title = element_text(size = 15,
                                      hjust = 0.6, 
                                      vjust = 0.2),
            axis.title.x = element_text(size = 15,
                                       hjust = 0.6, 
                                       vjust = 0.2))
    

    result