Search code examples
rggplot2axis-labelsgeom-hline

Customization of plots created with the ale package


I started using the ale package that automatically generates ggplot objects from models. I would like to remove the labels "75%", "median" and "25%" that are automatically created with the hlines : here is my graph. I find it makes the graph too crowded (as I combine 6 plots with wrap_plots) and they could easily be explained textually in a legend under the graph. Is there a way to do this? I'm not a ggplot expert and spent way too much time on this please help :')

I stored my 6 plots in a list named "list", to then use wrap_plots. I was able to custommize the x axis labels with this code :

list[["plot1"]][["labels"]][["x"]] <- "Degree Days"

and it works, but I can't seem to find where the "75%","median" and "25%" labels are stored in the ggplot object, probably because they are not labels?

Here is my reproducible example frome the ale package documentation:

diamonds_sample <- ggplot2::diamonds[sample(nrow(ggplot2::diamonds), 1000), ]

# Create a GAM model 
gam_diamonds <- mgcv::gam(
  price ~ s(carat) + s(depth) + s(table) + s(x) + s(y) + s(z) +
    cut + color + clarity,
  data = diamonds_sample
)
summary(gam_diamonds)

# Simple ALE 
ale_gam_diamonds <- ale(
  diamonds_sample, gam_diamonds,
  parallel = 2  # CRAN limit (delete this line on your own computer)
)

# Plot the ALE data
ale_gam_diamonds$plots |>
  patchwork::wrap_plots()

Solution

  • The labels for the horizontal lines are added via a secondary axis. Hence, one option would to get rid of these labels would be to overwrite the y scale.

    As you want to apply your modifications to all plots there is in general no need to fiddle around with the list of ggplot objects. Instead, you could apply your modifications to the final patchwork object.

    Actually, getting a legend requires some more effort (see below). As a first approach you might consider declutterring your plot by getting rid of the axes for the inner plots, which using patchwork >=1.2.0 could be a achieved by using axes="collect".

    library(ale)
    library(patchwork)
    library(ggplot2)
    
    # Get rid of the axes for the inner plots
    ale_gam_diamonds$plots |>
      wrap_plots() +
      plot_layout(axes = "collect") &
      labs(x = "Degree Days")
    

    But if you prefer having a legend instead you could fake one by adding a blank (e.g. geom_hline) layer where I decided to map on the linetype aes. Afterwards you could style the legend using the `override.aes´ argument:

    # Use a legend
    ale_gam_diamonds$plots |>
      wrap_plots() +
      plot_layout(guides = "collect") &
      labs(x = "Degree Days", linetype = NULL) &
      # Get rid of the secondary axis aka the labels on the right
      scale_y_continuous() &
      # Fake a legend
      geom_hline(
        data = data.frame(
          yintercept = NA_real_,
          linetype = factor(c("25%", "median", "75%"), c("25%", "median", "75%"))
        ),
        aes(yintercept = yintercept, linetype = linetype),
        na.rm = TRUE
      ) &
      guides(
        linetype = guide_legend(
          override.aes = list(
            color = c("black", "grey85", "black"),
            linetype = c("dashed", "solid", "dashed")
          )
        )
      ) &
      theme(legend.position = "bottom")
    #> Scale for y is already present.
    #> Adding another scale for y, which will replace the existing scale.
    #> Scale for y is already present.
    #> Adding another scale for y, which will replace the existing scale.
    #> Scale for y is already present.
    #> Adding another scale for y, which will replace the existing scale.
    #> Scale for y is already present.
    #> Adding another scale for y, which will replace the existing scale.
    #> Scale for y is already present.
    #> Adding another scale for y, which will replace the existing scale.
    #> Scale for y is already present.
    #> Adding another scale for y, which will replace the existing scale.
    #> Scale for y is already present.
    #> Adding another scale for y, which will replace the existing scale.
    #> Scale for y is already present.
    #> Adding another scale for y, which will replace the existing scale.
    #> Scale for y is already present.
    #> Adding another scale for y, which will replace the existing scale.