geom_facet with scales = 'free_y' generates y-axis texts in empty plots

66 views Asked by At

I have a following ggplot2 R code that creates state-specific plot using geofacet package:

ggplot(plotdf, aes(x = year, y = value)) + 
    geom_line(aes(color = group1), linewidth = 0.6) +
    geom_hline(yintercept = 0, lty = 2) +
    facet_geo(~ state, grid = 'us_state_without_DC_grid1', scales = 'free_y', move_axes = TRUE) +
    scale_color_manual(name = "", values = c('black', 'darkgreen', 'darkviolet','blue')) +
    theme_bw() + 
    theme(plot.title = element_text(hjust = 0.5),
          panel.grid = element_blank(),
          axis.text.x = element_text(angle = 90),
          legend.position = 'bottom')

which produces the following plot that includes y-axis text even in empty plot areas: enter image description here

How can I remove the axis labels in the empty plots while asserting scales = 'free_y'?

Below is a fake data set to reproduce a plot similar to what's shown above:

plotdf <- expand.grid(state = state.abb, year = 1990:2020, group1 = c('White', 'Black', 'Asian', 'Hispanic'))
plotdf$value <- rnorm(nrow(plotdf))
2

There are 2 answers

0
nrennie On BEST ANSWER

The problem here is with geom_hline() - it's being added to every facet plot (even empty ones) since there's no facet variable associated with the intercept value. One option is to add it to your data and specify the intercept in the aes() function instead:

plotdf <- expand.grid(state = state.abb, year = 1990:2020, group1 = c('White', 'Black', 'Asian', 'Hispanic'))
plotdf$value <- rnorm(nrow(plotdf))
plotdf$intercept <- 0

ggplot(plotdf, aes(x = year, y = value)) + 
  geom_line(aes(color = group1), linewidth = 0.6) +
  geom_hline(aes(yintercept = intercept),
             lwd = 2) +
  facet_geo(~ state, grid = 'us_state_without_DC_grid1', scales = 'free_y', move_axes = TRUE) +
  scale_color_manual(name = "", values = c('black', 'darkgreen', 'darkviolet','blue')) +
  theme_bw() + 
  theme(plot.title = element_text(hjust = 0.5),
        panel.grid = element_blank(),
        axis.text.x = element_text(angle = 90),
        legend.position = 'bottom')

facet plot

0
stefan On

One option would be to use ggh4x::facet_manual to plot the geofacet which works well with free scales. However, this requires to first create a design matrix from the geofacet grid to specify the layout to place the facets:

library(geofacet)
library(ggplot2)
library(ggh4x)

set.seed(1)
plotdf <- expand.grid(
  state = state.abb,
  year = 1990:2020,
  group1 = c("White", "Black", "Asian", "Hispanic")
)
plotdf$value <- rnorm(nrow(plotdf))

# Get the grid and create a design matrix
grid <- geofacet::us_state_grid1
design <- matrix(nrow = 7, ncol = 11)
for (i in seq_len(nrow(grid))) {
  design[grid$row[i], grid$col[i]] <- i
}

ggplot(plotdf, aes(x = year, y = value)) +
  geom_line(aes(color = group1), linewidth = 0.6) +
  geom_hline(yintercept = 0, lty = 2) +
  ggh4x::facet_manual(~state,
    design = design,
    scales = "free_y"
  ) +
  scale_color_manual(
    name = NULL,
    values = c("black", "darkgreen", "darkviolet", "blue")
  ) +
  theme_bw() +
  theme(
    plot.title = element_text(hjust = 0.5),
    panel.grid = element_blank(),
    axis.text.x = element_text(angle = 90),
    legend.position = "bottom"
  )

enter image description here