Search code examples
rggplot2r-sfcowplot

apply a function for creating cowplots on a list of ggplots with 4 plots each time


Sorry, I think it's a dumb question.

I've just created a function that return a map (with geom_sf) of points for each grouping variable of a whole sf dataframe (points).

At the end I get a list of ggplot objects.

Now I want to plot the results 4 by 4, in a grid.

Here a simpler reproducible example

## I have a df

library(ggplot2)
library(cowplot)
df <- data.frame(V1 = runif(100, 0.0, 1.0), 
                 V2 = runif(100, 0.0, 1.0),
                 V3 = runif(100, 0.0, 1.0),
                 V4 = runif(100, 0.0, 1.0),
                 V5 = runif(100, 0.0, 1.0),
                 V6 = runif(100, 0.0, 1.0),
                 V7 = runif(100, 0.0, 1.0),
                 V8 = runif(100, 0.0, 1.0))

## I've created a function to produce several ggplot from this df
# for this example, let's say it is a list of histograms

plot_data_column <- function (data, column) {
  ggplot(data, aes_string(x = column)) +
    geom_histogram(fill = "lightgreen") +
    xlab(column)
}

myplots <- lapply(colnames(df), plot_data_column, data = df)

## Now i want to create a function that make grids of 4 plots each times
# Something like that (below) but working on the 4 first element of the list, 
# then the 4 next and so on until the last items on the list, automaticaly

Gridplot <- function(myplots){
  Grid <- cowplot::plot_grid(plotlist = myplots)
  return(Grid)
}

Grid1 <- Gridplot(myplots[1:4])

How can I do that ? I'm sure it's quite simple


Solution

  • You need to split your myplots list in chunks of size 4. You can do that with split(myplots, ceiling(seq_along(myplots)/n)) where n is the size of the chunks (as per the answer here).

    So you can do something like this:

    ## I have a df
    
    library(ggplot2)
    library(cowplot)
    #> 
    #> ********************************************************
    #> Note: As of version 1.0.0, cowplot does not change the
    #>   default ggplot2 theme anymore. To recover the previous
    #>   behavior, execute:
    #>   theme_set(theme_cowplot())
    #> ********************************************************
    df <- data.frame(V1 = runif(100, 0.0, 1.0), 
                     V2 = runif(100, 0.0, 1.0),
                     V3 = runif(100, 0.0, 1.0),
                     V4 = runif(100, 0.0, 1.0),
                     V5 = runif(100, 0.0, 1.0),
                     V6 = runif(100, 0.0, 1.0),
                     V7 = runif(100, 0.0, 1.0),
                     V8 = runif(100, 0.0, 1.0))
    
    ## I've created a function to produce several ggplot from this df
    # for this example, let's say it is a list of histograms
    
    plot_data_column <- function (data, column) {
      ggplot(data, aes_string(x = column)) +
        geom_histogram(fill = "lightgreen") +
        xlab(column)
    }
    
    myplots <- lapply(colnames(df), plot_data_column, data = df)
    
    ## Now i want to create a function that make grids of 4 plots each times
    # Something like that (below) but working on the 4 first element of the list, 
    # then the 4 next and so on until the last items on the list, automaticaly
    
    Gridplot <- function(myplots, n){
    
      splitted_plots <- split(myplots, ceiling(seq_along(myplots)/n))
    
      lapply(splitted_plots, function(x) plot_grid(plotlist = x))
    
      # Grid <- cowplot::plot_grid(plotlist = myplots)
      # return(Grid)
    }
    
    Grid_list <- Gridplot(myplots, 4)
    #> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
    #> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
    #> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
    #> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
    #> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
    #> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
    #> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
    #> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
    
    Grid_list[[1]]
    

    Grid_list[[2]]
    

    Created on 2019-11-24 by the reprex package (v0.3.0)

    Note that with this solution, if you want more plots per grid, you only need to change n value in the Gridplot function