ggplot: Best way to split x-axis in intervals?

If we create a separate plot for each group, then we can add a spacer next to the last plot to keep it from stretching to the full width of the previous plots. In the code below, we calculate the relative widths needed for the last plot and the spacer based on how many data rows go into the last plot relative to the 100 rows that go into each of the other plot panels.

library(tidyverse)
library(patchwork)

# Reproducible example
set.seed(352053)

# Set example data
d <- tibble(x = seq(from = 1, to = 922),
            y = rnorm(n = length(x)))

# Create groups with 100 rows each
d = d %>% 
  mutate(group = (x-1) %/% 100) 

# Create a list of plots, one for each group of 100 rows
pl = d %>% 
  # Split into one data frame for each group
  split(d$group) %>% 
  map(
    ~ggplot(.x, aes(x = x, y = y)) +
      geom_col() +
      scale_x_continuous(expand = c(0, 0), breaks=seq(0,nrow(d), 10)) +
      theme_bw() +
      theme(axis.title=element_blank()) 
  )
# Get number of data rows in last plot
n = nrow(d[d$group==max(d$group),])

# Add (to the last plot in the list) an empty plot with width equal to 
#  the amount of empty space we need on the right
# Removing the right plot margin is to ensure (or at least make it more likely) 
#  that the last plot will line up vertically with the previous plots.
pl[[length(pl)]] = pl[[length(pl)]] + theme(plot.margin=margin(r=0)) + plot_spacer() + plot_layout(widths=c(n, 100-n))

# Lay out the plots
wrap_plots(pl, ncol=1)

3 Likes