【问题标题】:save grobs made in function of loop保存循环函数中的 grobs
【发布时间】:2014-10-16 07:49:24
【问题描述】:

我制作了这个以 grob 图形(3 个 ggplots)结尾的长函数。但是,当我在循环中使用此函数并尝试将所有生成的 grobs 放入一个超级图形中时,我遇到了问题。我得到了一个有很多 grobs 的人物,但它总是同一个 grob(第一个)!

为了演示我的问题,我做了这个简化的例子:

library(ggplot2)
library(gridExtra)

data(iris)

#the function
multi.plot=function(data,heading){
  p1=ggplot(data,aes(x=Sepal.Length,y=Sepal.Width))+geom_point()+ggtitle(heading)
  p2=ggplot(data,aes(x=Petal.Length,y=Sepal.Width))+geom_point()
  p3=ggplot(data,aes(x=Sepal.Length,y=Petal.Width))+geom_point()
  grob1=arrangeGrob(p1,ncol=2)
  grob2=arrangeGrob(p3,p2,ncol=2)
  grob3=arrangeGrob(grob1,grob2)
  # grob3  / return(grob3)  / print(grob3)   => all tried but non of them helps
}

# the loop
list.grob=list()
for(i in unique(iris$Species)){
  select=iris[iris$Species==i,]
  multi.plot(data=select,heading=i)
  list.grob[[which(unique(iris$Species)==i)]]=grob3  
}

# the final figure
png(file="superplot.png")
do.call("grid.arrange", list.grob)  
dev.off()

那么,如何使用函数和循环制作一个包含大量 grobs 的图形?此外,我的标题(“标题”)没有按应有的方式出现。

感谢您的建议!

【问题讨论】:

    标签: r function for-loop ggplot2 gridextra


    【解决方案1】:

    坚持你的技术,我会继续:

    library(ggplot2)
    library(gridExtra)
    data(iris)
    

    功能

    multi.plot=function(data=iris, heading="virginica"){
            p1=ggplot(data,aes(x=Sepal.Length,y=Sepal.Width))+geom_point()+ ggtitle(heading)
            p2=ggplot(data,aes(x=Petal.Length,y=Sepal.Width))+geom_point()+ ggtitle(heading)
            p3=ggplot(data,aes(x=Sepal.Length,y=Petal.Width))+geom_point()+ ggtitle(heading)
            grob_all=arrangeGrob(p1, p2, p3, ncol=3)
            return(grob_all)}`
    
    grob_test <- multi.plot()
    

    循环

    list.grob=list()
    names(list.grob) <- unique(iris$Species)`
    
    for(i in unique(iris$Species)){
      select <- iris[iris$Species==i,]
      grob_i <- multi.plot(data=select,heading=i)
      list.grob[[i]]=grob_i
    }
    

    最终图

    png(file="superplot.png")
    do.call("grid.arrange", list.grob)  
    dev.off()
    

    【讨论】:

      【解决方案2】:

      这里不需要使用for 循环。我的意思是最好通过使用by 的物种组来做到这一点,例如:

      by(iris,iris$Species,
         function(select)
           multi.plot(data=select,heading=unique(select$Species)))
      

      你还应该简化multi.plot函数:

      #the function
      multi.plot=function(data,heading){
        p1=ggplot(data,aes(x=Sepal.Length,y=Sepal.Width))+geom_point()+ggtitle(heading)
        p2=ggplot(data,aes(x=Petal.Length,y=Sepal.Width))+geom_point()
        p3=ggplot(data,aes(x=Sepal.Length,y=Petal.Width))+geom_point()
        arrangeGrob(p1,arrangeGrob(p1,p2,ncol=2))
      }
      

      【讨论】:

      • 感谢您的回答,它在示例中效果很好。但不幸的是,在我真正的问题中,我使用 for 循环遍历列而不是行的因子。有没有类似的事情我可以做?
      • 您可以重塑数据,使列是一个因子的值(即从宽到长)
      猜你喜欢
      • 2015-02-09
      • 1970-01-01
      • 2018-12-09
      • 2019-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多