Alex
Alex

Reputation: 198

R ggplot2 - plot alternating Y axes

Hello StackOverflow community, Is there a way in R ggplot2, using the facet_grid() function to get alternate Y axes like in this example :

(Example of multiple time series plot with alternating Y axes. Source : https://www.sciencedirect.com/science/article/pii/S0277379121004522)

Here are fake data from the economics dataset and ggplot code to reproduce :

library(ggplot2)
library(tidyverse)

data <- economics %>%
  select(date, unemploy, pop, psavert) %>%
  pivot_longer(cols = c(unemploy, pop, psavert), names_to = "variable", values_to = "value")

p <- ggplot(data, aes(x = date, y = value, color = variable)) +
  geom_line() +
  facet_grid(rows = vars(variable), scales = "free_y") +  # Create facets with free Y scales
  scale_y_continuous(
    sec.axis = sec_axis(~.) # Add a secondary axis
  )+
  theme(strip.text = element_blank(), 
        strip.background = element_blank(),
        axis.line = element_line(), 
        legend.position = "top")
 
print(p)

Upvotes: 4

Views: 57

Answers (2)

jpsmith
jpsmith

Reputation: 17145

A brute-force approach is to not rely on faceting and create three plots, stacking plots with a / b / c from patchwork:

library(ggplot2) 
library(patchwork)

data_list <- split(data, data$variable) # split into list for loop

# define colors, position, and names
ccols <- c("steelblue", "firebrick", "darkgreen")
positn <- rep(c("left", "right"), length.out = length(data_list))
nnames <- c("Unemployment", "Population", "Personal Savings Rate")

# plot
for(x in seq_along(data_list)){
  assign(paste0("px", x), ggplot(data_list[[x]], aes(x = date, y = value)) +
    geom_line(color = ccols[x]) +
    scale_y_continuous(position = positn[x]) +
  ggtitle(nnames[x]) +
  theme_minimal() +
  theme(
    axis.title.x = element_blank(), 
    axis.text.x  = element_blank()  # Hide x-axis ticks
  ))
}
px1 / px2 / px3

enter image description here

Upvotes: 1

Jon Spring
Jon Spring

Reputation: 66415

  ... +
  ggh4x::facetted_pos_scales(y = list(
    scale_y_continuous(),
    scale_y_continuous(position = "right"),
    scale_y_continuous()
  )) + 
  theme(panel.spacing.y=unit(0, "lines")) + ...

enter image description here

Upvotes: 5

Related Questions