Search code examples
rggplot2limit

in ggplot2 can i set the upper limit to automaticly pick the major gridline above my maximum datapoint (faceted)


In ggplot2, I want to create a grid faceted graph with a free x scale like in the first image. But I want my limits to be at the edge of the plot and for my upper limit to automatically be 1 tick higher than my maximum data point for each faceted graph

Is there any simple way to do this? its just a formating prefernce I know it should involve the limet and expand functions.

p.s My real data does need faceting unlike the gapminder example

library(gapminder)
gap_filterd<-gapminder%>%
  mutate(country=as.character(country))%>%
  filter(startsWith(country,"D"))%>%
  mutate(country=as.factor(country))

gap_filterd%>%
  ggplot(aes(pop,lifeExp))+
  geom_point()+
  facet_grid(rows = vars(country),
             cols = vars(continent),
             scales = "free_x"
  )+
  scale_x_continuous(
    labels = label_number(scale_cut = cut_short_scale()),
    limits = c(0,NA),
    expand = c(0,NA))

enter image description here

enter image description here


Solution

  • One possible option would be to set the limits= using scales::breaks_extended and argument only.loose=TRUE which will set the limits such that

    the extreme labels will be outside the data range. (See ?labeling::extended)

    However, this is perhaps still not perfect as you can see in the middle left panel.

    Note: I added clip=off to prevent clipping and increased the panel spacing to avoid overlapping axis text at the panel borders.

    library(gapminder)
    library(ggh4x)
    library(tidyverse)
    library(scales)
    
    gap_filterd %>%
      ggplot(aes(pop, lifeExp)) +
      geom_point() +
      facet_grid(
        rows = vars(country),
        cols = vars(continent),
        scales = "free_x"
      ) +
      scale_x_continuous(
        labels = label_number(scale_cut = cut_short_scale()),
        limits = \(x) range(
          scales::breaks_extended(only.loose = TRUE)(c(0, x))
        ),
        expand = c(0, NA)
      ) +
      coord_cartesian(clip = "off") +
      theme(
        panel.spacing.x = unit(20, "pt")
      )