Search code examples
rggplot2

How to Stack a Scatter Plot and a Bar Chart with Discrete and Continuous Y-Axes?


I have created two plots: The first one is a scatter plot where the x-axis represents time and the y-axis contains discrete values like the names 'Tom' and 'Jerry'. The second one is a bar chart where the x-axis is also time and the y-axis shows continuous values like height. I'm now trying to stack these two plots onto the same graph, but I'm not sure how to do it.

Here is the code I have used for each plot:

For the scatter plot:

data.scatter <- data.frame(x = c(1, 2, 3, 4, 5), y = c("Tom", "Jerry", "Tom", "Jerry", "Tom"))
ggplot(data.scatter, aes(x = x, y = y)) + geom_point()

the scatter plot

For the bar chart:

data.bar <- data.frame(x = c(1, 2, 3, 4, 5), y = c(10, 20, 30, 40, 50))
ggplot(data.bar, aes(x = x, y = y)) + geom_bar(stat = "identity")

the bar chart

The following is my attempt, but this code is very cumbersome. Is there a simpler way to achieve this effect?

library(tidyverse)

data.scatter <- data.frame(x = c(1, 2, 3, 4, 5), y = c("Tom", "Jerry", "Tom", "Jerry", "Tom"))
p1 <- ggplot(data.scatter, aes(x = x, y = y)) + geom_point()
p1_data <- ggplot_build(p1)$data[[1]]

data.bar <- data.frame(x = c(1, 2, 3, 4, 5), y = c(10, 20, 30, 40, 50))
p2 <- ggplot(data.bar, aes(x = x, y = y)) + geom_bar(stat = "identity")


p2_data <- ggplot_build(p2)$data[[1]]

p3 <- p2_data %>% ggplot() +
  geom_rect(aes(ymin=ymin,ymax = ymax,xmin = xmin,xmax = xmax)) + 
  geom_text(aes(x=xmin+.45,y=ymax+1,label=ymax)) +
  geom_point(data = p1_data, aes(x = x, y = y*20),inherit.aes = F) + 
  scale_y_continuous(breaks = c(20,40),labels = c("Tom","Jerry")) + 
  labs(x=NULL,y=NULL)


p3

Stack Plot


Solution

  • You could set the limits for the y-axes in both plots to ensure that the axes align when combining them using align_plots from the cowplot package.

    library(ggplot2)
    library(cowplot)
    
    p1 <- ggplot(data.bar, aes(x = x, y = y)) + 
      geom_bar(stat = "identity") +
      scale_y_continuous(position = "right") +
      scale_x_continuous(limits=c(0.5,5.5))  +
      theme_minimal_hgrid()
    
    p2 <- ggplot(data.scatter, aes(x = x, y = y)) + 
      geom_point() + labs(x="x")  +
      scale_x_continuous(limits=c(0.5,5.5)) +
      theme_cowplot()
    
    aligned_plots <- align_plots(p1, p2, align="hv", axis="tblr")
    ggdraw(aligned_plots[[1]]) + draw_plot(aligned_plots[[2]])
    

    enter image description here