QBoard » Advanced Visualizations » Viz - Others » Side-by-side plots with ggplot2

Side-by-side plots with ggplot2


  • I would like to place two plots side by side using the ggplot2 package, i.e. do the equivalent of par(mfrow=c(1,2)).
    For example, I would like to have the following two plots show side-by-side with the same scale.

    x <- rnorm(100) 
    eps <- rnorm(100,0,.2) 
    qplot(x,3*x+eps)
    qplot(x,2*x+eps)​
     
    Do I need to put them in the same data.frame?

    qplot(displ, hwy, data=mpg, facets = . ~ year) + geom_smooth()​​
    This post was edited by Shivakumar Kota at August 24, 2020 5:42 PM IST
      August 24, 2020 5:39 PM IST
    0
  • Using the reshape package you can do something like this.

    library(ggplot2)
    wide <- data.frame(x = rnorm(100), eps = rnorm(100, 0, .2))
    wide$first <- with(wide, 3 * x + eps)
    wide$second <- with(wide, 2 * x + eps)
    long <- melt(wide, id.vars = c("x", "eps"))
    ggplot(long, aes(x = x, y = value)) + geom_smooth() + geom_point() + facet_grid(.~ variable)​
      August 24, 2020 5:50 PM IST
    0
  • you need to arrange your data appropriately. One way would be this:

    X <- data.frame(x=rep(x,2),
                    y=c(3*x+eps, 2*x+eps),
                    case=rep(c("first","second"), each=100))
    
    qplot(x, y, data=X, facets = . ~ case) + geom_smooth()

    I am sure there are better tricks in plyr or reshape -- I am still not really up to speed on all these powerful packages by Hadley

      September 25, 2020 3:56 PM IST
    0
  • Using tidyverse:

    x <- rnorm(100)
    eps <- rnorm(100,0,.2)
    df <- data.frame(x, eps) %>% 
      mutate(p1 = 3*x+eps, p2 = 2*x+eps) %>% 
      tidyr::gather("plot", "value", 3:4) %>% 
      ggplot(aes(x = x , y = value)) + 
        geom_point() + 
        geom_smooth() + 
        facet_wrap(~plot, ncol =2)
    
    df


    This post was edited by Rishi Pandya at September 25, 2020 4:03 PM IST
      September 25, 2020 3:59 PM IST
    0
  • You can use the following multiplot function from Winston Chang's R cookbook

    multiplot(plot1, plot2, cols=2)

    multiplot <- function(..., plotlist=NULL, cols) {
        require(grid)
    
        # Make a list from the ... arguments and plotlist
        plots <- c(list(...), plotlist)
    
        numPlots = length(plots)
    
        # Make the panel
        plotCols = cols                          # Number of columns of plots
        plotRows = ceiling(numPlots/plotCols) # Number of rows needed, calculated from # of cols
    
        # Set up the page
        grid.newpage()
        pushViewport(viewport(layout = grid.layout(plotRows, plotCols)))
        vplayout <- function(x, y)
            viewport(layout.pos.row = x, layout.pos.col = y)
    
        # Make each plot, in the correct location
        for (i in 1:numPlots) {
            curRow = ceiling(i/plotCols)
            curCol = (i-1) %% plotCols + 1
            print(plots[], vp = vplayout(curRow, curCol ))
        }
    
    }
    
    
    ​
    This post was edited by Rakesh Racharla at September 25, 2020 4:03 PM IST
      September 25, 2020 4:02 PM IST
    0
  • Using the patchwork package, you can simply use + operator:

    library(ggplot2)
    library(patchwork)
    
    p1 <- ggplot(mtcars) + geom_point(aes(mpg, disp))
    p2 <- ggplot(mtcars) + geom_boxplot(aes(gear, disp, group = gear))
    
    
    p1 + p2
      September 25, 2020 4:11 PM IST
    0