Shade alternate plot rows gray

Viewed 41

I have created two twin error-bar plots with ggplot2 and gridExtra and I'm now trying to shade the background of every other row on the y-axis in gray.

Intended output enter image description here

Data and code

library(ggplot2)
library(dplyr)
library(gridExtra)

# Reproducible example
dat <- data.frame(dataset=c("A", "B", "C", "A", "B", "A", "C"),
                  tis=c("T1", "T1", "T2", "T1", "T1", "T1", "T2"),
                  path=c("p1", "p1", "p2", "p2", "p2", "p3", "p1" ),
                  NS=c(1.1, 1.2, -0.5, -1.4, -1.6, 0.9, 0.8),
                  min=c(1, 0.4, -0.8, -2, -2, -0.1, 1.5),
                  max=c(2, 2, 0, -1, -0.3, 1.6, 2.1),
                  category=c("c1", "c1", "c1", "c1", "c1", "c2", "c1"))

# Data management
plots_dat <- dat %>%
  group_by(tis) %>%
  group_split() %>% lapply(function(plotDat){

# Plot
ggplot(plots_dat , aes(x=NS, y=path, group=dataset, col=dataset, fill=dataset)) +
      theme_minimal() + 
      geom_point(position = position_dodge(0.7)) +
      geom_vline(xintercept = c(-1,1), colour="#FA8072", linetype = "longdash") +
      geom_vline(xintercept = c(0), colour="grey", linetype = "solid") +
      geom_errorbarh(height=.3, aes(xmin = min, xmax = max), position = position_dodge(0.7)) + theme_bw() +
      theme(axis.title.y=element_blank(),
            axis.text.y=element_blank(),
            axis.ticks.y=element_blank(), 
            plot.margin = unit(c(5,5,5,5), "pt"),
            panel.grid.major = element_blank(), 
            panel.grid.minor = element_blank(),
            text = element_text(size = 14),
            legend.position = "top") + 
      labs(x = "NS", title = plotDat$tis) + 
      xlim(-2.5, 2.5) 
  })

# Join plots
grid.arrange(
    grobs = c(list(
        ggplot(plots_dat[[1]]$data, aes(y = path, x = "")) +
            labs(y = "Path", title = "", x = "") +
            theme_minimal() +
        theme(
            panel.grid.major.x = element_blank(),
            plot.margin = unit(c(5, 0, 5, 5), "pt"),
            text = element_text(size = 14)
            )
    ), plots_dat),
    nrow = 1,
    widths = c(1.1, rep(1, length(plots_dat)))
)

Current output enter image description here

How can I shade the p2 row in gray?

I would appreciate any help.

1 Answers

I would simply draw the strips before drawing the plots.

First, ensure the plots are transparent:

# Data management
plots_dat <- dat %>%
  group_by(tis) %>%
  group_split() %>% lapply(function(plotDat){
    
    # Plot
    ggplot(plotDat, aes(x=NS, y=path, group=dataset, col=dataset, fill=dataset)) +
      theme_minimal() + 
      geom_point(position = position_dodge(0.7)) +
      geom_vline(xintercept = c(-1,1), colour="#FA8072", linetype = "longdash") +
      geom_vline(xintercept = c(0), colour="grey", linetype = "solid") +
      geom_errorbarh(height=.3, aes(xmin = min, xmax = max), 
                     position = position_dodge(0.7)) + 
      theme_bw() +
      theme(axis.title.y=element_blank(),
            axis.text.y=element_blank(),
            axis.ticks.y=element_blank(), 
            plot.margin = unit(c(5,5,5,5), "pt"),
            panel.grid.major = element_blank(), 
            panel.grid.minor = element_blank(),
            text = element_text(size = 14),
            legend.position = "top",
            plot.background = element_blank(),
            panel.background = element_blank()) + 
      labs(x = "NS", title = plotDat$tis) + 
      xlim(-2.5, 2.5) 
  })

Next, store the output of grid.arrange:

pg <- grid.arrange(
  grobs = c(list(
    ggplot(plots_dat[[1]]$data, aes(y = path, x = "")) +
      labs(y = "Path", title = "", x = "") +
      theme_minimal() +
      theme(
        panel.grid.major.x = element_blank(),
        plot.margin = unit(c(5, 0, 5, 5), "pt"),
        text = element_text(size = 14)
      )
  ), plots_dat),
  nrow = 1,
  widths = c(1.1, rep(1, length(plots_dat)))
)

Now draw a gray rectangle on a blank canvas, and draw your result over it:

grid::grid.newpage()
grid::grid.draw(grid::rectGrob(y = 0.48, height = 0.2, 
                               gp = grid::gpar(fill = "gray92", col = NA)))
grid::grid.draw(pg)

enter image description here

Related