Search code examples
rggplot2sjplot

Including a jump from 0 to 1500 in my y-axis


I want to include a jump in my plot. Thy y-axis should start from 0 but the there should be a break which goes to 1500 and from there in 100 unit increments up to 2000. This works in my code, but the space between 0 and 1500 is still expanded, and i cannot figure out how to remove that:enter image description here

I tried using that code with the package ggplot2 and sjPlot: kcalPlot+ylab("Energy Intake (kcal)")+ scale_y_continuous(limits = c(0,2000),expand=c(0,0),breaks = c(0,1500,seq(1600,2000, by=100)), labels = c("0", "1500", "1600", "1700", "1800", "1900","2000")) which produces me the plot above, but it is still expanded. kcalPlot is produced by this kcalPlot <- plot_model(kcal3, type="slope"), where kcal3 is a model from lmer(). Is it possible to get rid of that space, or is there another way to it? Data Here would be a snippet of my data, it is a dropbox link, i hope this is okay. To produce the lme-model i used: kcal3 <- lmer(EnergyIntake~Group+Timepoint+BMI+(1+Group|ID), data=kcalL, REML=F) and then the code above to produce the plot with sjplot. Thanks for your help!


Solution

  • Here's an alternative hack, assuming OP already has the model (created using lmer() from the lme4 package) and plot (created using plot_model() from the sjPlot package), and doesn't want to undo the work done there.

    Simulate the model / plot creation process, based off the example used in lmer's help file:

    library(lme4)
    library(sjPlot)
    
    data(Orthodont,package="nlme")
    
    kcal3 <- lmer(distance ~ age + Sex + (age|Subject), data=Orthodont)
    kcalPlot <- plot_model(kcal3, type = "slope")
    

    Hack:

    library(ggplot2)
    library(dplyr)
    
    # replace the facet_wrap in the original with facet_grid for ease of alignment 
    # layer; impact should be minimal since the desire is to have a common y-axis.
    p <- kcalPlot + 
      facet_grid(cols = vars(group), scales = "free_x")
    
    # duplicate plot but remove x-axis elements
    # if you want to specify y-axis breaks for your actual plot, can add them
    # here as well (other than the y = 0 break, which is addressed below)
    p.top <- p + 
      # scale_y_continuous(breaks = seq(1500, 2000, by = 100)) +
      theme(axis.ticks.length.x.bottom = unit(0, "pt"), 
            axis.text.x = element_blank(), 
            axis.title.x = element_blank(), 
            axis.ticks.x = element_blank(), 
            plot.margin = unit(c(5.5, 5.5, 0, 5.5), "points"))
    
    # duplicate plot again for its basic structure, for y = 0 range, with a new 
    # text layer added to provide the plot break symbol for the leftmost facet
    p.bottom <- p +
      geom_text(data = get_model_data(kcal3, type = "slope") %>%
                  group_by(group) %>%
                  summarise(x = -Inf, y = 0.5, .groups = "drop") %>%
                  arrange(group) %>%
                  mutate(alpha = c(1, rep(0, n()-1))),
                aes(label = "\\\\", alpha = alpha), angle = 90, size = 5) +
      scale_y_continuous(breaks = 0) +
      scale_alpha_identity() +
      coord_cartesian(ylim = c(0, 1), clip = "off") +
      theme(axis.title.y = element_blank(),
            plot.margin = unit(c(0, 5.5, 5.5, 5.5), "points"),
            panel.grid.minor.y = element_blank(), 
            plot.background = element_blank(),
            strip.background = element_blank(), 
            strip.text = element_blank())
    
    # stitch the two plots together & adjust the relative amount of space for the
    # y=0 portion (I set it as 20% of the top plot's height)
    cowplot::plot_grid(p.top, p.bottom, align = "v", axis = "lr", ncol = 1,
                       rel_heights = c(1, 0.2))
    

    Result:

    result