Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
676 views
in Technique[技术] by (71.8m points)

How to create a list of ggplot objects that grid.arrange will accept and draw in r

Update The below code runs now after kernel restart. I'm leaving the question since I didn't see this exact method of converting the plot object into a list and appending.

I want to dynamically create a list of ggplot2::ggplot objects (gg) and pass that list to gridExtra::grid.arrange() to draw them.

However, I'm getting errors when I try (see bottom of code below).

How do I create a list of ggplots and use it in grid.arrange() (or anywhere I want one or more gg objects or grobs)?

I've looked at these posts, but the solutions didn't work.

Here's a simple example with outputs:

# RStudio Version 1.3.1093
# R version 4.0.3 (2020-10-10)
# ggplot2 version 3.3.2
# gridExtra version 2.3

library(ggplot2)
library(gridExtra)

test_fun = function (x) {
  plt_lst = list()
  
  for(col in colnames(x)){
    plt = ggplot(data = x, aes(x = x[ , col])) +
      geom_histogram()
    plt_lst = append(plt_lst, list(plt))
    grid.arrange(plt) # Draws each graph.
    print(is(plt))
    # [1] "gg"
    print(is(plt[[1]]))
    # [1] "data.frame" "list"       "oldClass"   "vector"
  }
  
  return(plt_lst)
}

df = data.frame(a = rnorm(n = 50),
                b = rnorm(n = 50))

test_plt_lst = test_fun(df)
print(is(test_plt_lst))
# [1] "gg"
print(is(test_plt_lst[[1]]))
# [1] "data.frame" "list"       "oldClass"   "vector"

# grid.arrange(test_plt_lst)
# # Error in gList(list(data = list(a = c(1.14459276559037, 2.33485713757935, : only 'grobs' allowed in "gList"


# Works
do.call(grid.arrange, test_plt_lst)
# The following error no longer appearing.
# Error in `$<-.data.frame`(`*tmp*`, "wrapvp", value = list(x = 0.5, y = 0.5, : replacement has 17 rows, data has 50

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can try to :

  1. Initialise the length of the list because growing objects in a loop is considerably slow.
  2. Use .data pronoun to subset the names so you get proper names on x-axis.
library(ggplot2)
library(gridExtra)

test_fun = function (x) {
  plt_lst = vector('list', length(x))
  nm <- names(x)

  for(i in seq_along(x)){
    plt_lst[[i]] = ggplot(data = x, aes(x = .data[[nm[i]]])) + geom_histogram()
  }
  
  return(plt_lst)
}


test_plt_lst = test_fun(df)
do.call(grid.arrange, test_plt_lst)

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...