使用grid.arrange循环保存多个图

时间:2018-03-15 02:29:47

标签: r plot ggplot2

我正在尝试创建一个图,其中每个我都有一个密度图和一个直方图。对于这个例子,i = 1..3

我遇到的问题是创建要传递给grid.arrange的列表。但是,我这样做似乎以某种方式重复自己。

DF:

       x1    x2      x3
1  108.28 17.05 1484.10
2  152.36 16.59  750.33
3   95.04 10.91  766.42
4   65.45 14.14 1110.46
5   62.97  9.52 1031.29
6  263.99 25.33  195.26
7  265.19 18.54  193.83
8  285.06 15.73  191.11
9   92.01  8.10 1175.16
10 165.68 11.13  211.15

X <- df
mu.X <- colMeans(X)
cov.X <- cov(X)
eg <- eigen(cov.X)

myprinboot = function(
       X,
       iter = 10000,
       alpha = 0.05,
       prettyPlot = T
       ){

       # Find the dimensions of X
       nrX <- dim(X)[1]
       nx <- dim(X)[2]

       # Make matrices of suitable sizes to hold the booted parameter estimates
       # lambda
       # each cov matrix will have nx lambdas 
       lambda.mat <- matrix(NA, nr = nx, nc = iter)

       # e vectors nx components each and one vector per eigen value
       # Each cov matrix will therefore produce a nx X nx matrix of components
       Y.mat <- matrix(NA, nr = nx, nc = iter * nx)

       # For loop to fill the matrices created above
       for (i in 1:iter)
       {

              # ind will contain random integers used to make random samples of the X matrix
              # Must use number of rows nrX to index

              ind <- sample(1:nrX,nrX,replace=TRUE)

              # eigen will produce lambdas in decreasing order of size
              # make an object then remove extract the list entries using $
              eigvalvec <- eigen(cov(X[ind,]))
              lambda.mat[,i] <- eigvalvec$values
              colstart <- 1 + nx * (i - 1)
              colend <- colstart + nx - 1
              Y.mat[,colstart:colend] = eigvalvec$vectors
       }

       if(prettyPlot){
              p <- list()
              i <- 0
              for(j in 1:(2*nx))
              {
                     if (j %% 2 == 0){
                         p[[j]] <- ggplot(NULL, aes(lambda.mat[i,])) +
                            geom_histogram(color = 'black', fill = 'green', alpha = .5) +
                            xlab(substitute(lambda[i])) +
                            ggtitle(substitute(paste("Histogram of the pc variance ", lambda[i])))   
                     } else {
                            i <- i + 1
                            p[[j]] <- ggplot(NULL, aes(lambda.mat[i,])) + 
                            geom_density(fill = 'blue', alpha = .5) + 
                            xlab((substitute(lambda[i]))) + 
                            ggtitle(substitute(paste("Density plot of the pc variance ", lambda[i])))
                     }
                     do.call(grid.arrange, p)


              }

              do.call(grid.arrange, p)


       } else {

              layout(matrix(1:(2*nx),nr=nx,nc=2,byrow=TRUE))
              for(i in 1:nx)
              {
                     plot(density(lambda.mat[i,]),xlab=substitute(lambda[i]),
                          main=substitute(paste("Density plot of the pc variance ", lambda[i])
                          ))
                     hist(lambda.mat[i,],xlab=substitute(lambda[i]),
                          main=substitute(paste("Histogram of the pc variance ", lambda[i])))
              }

       }

       library(rgl)
       plot3d(t(lambda.mat))
       list(lambda.mat = lambda.mat, Y.mat = Y.mat)
}

pc <- myprinboot(X = Y, iter=1000, alpha=0.5)

Output

任何人都知道我做错了什么或这是不可能的?

2 个答案:

答案 0 :(得分:0)

我不明白你的代码Jay,因为它似乎做了很多事情并使用了base和ggplot绘图,但是如果你想要的是为每个j创建一个组合的直方图和密度图,为什么不循环在j和内部,对于j循环做这样的事情:

d&lt; - 创建密度图,使其仅依赖于j

h&lt; - 创建直方图,使其仅依赖于j

p [[j]]&lt; - grid.arrange(d,h,ncol = 2)

然后,当你离开循环时,你将有一个对象p,它包含一个绘图列表,每个绘图由密度图和直方图组合而成。

然后你可以使用cowplot包(在安装之后)做这样的事情:

cowplot :: plot_grid(plotlist = p,ncol = 2)

其中可能需要更改列数。有关绘制图表列表的其他方法,请参见此处:How do I arrange a variable list of plots using grid.arrange?

我对你的问题知之甚少,无法理解你为什么以不同的方式对待j even和j的情况。但潜在的想法应该与我在这里建议的相同。

答案 1 :(得分:0)

我最终得到了如下工作。

              getHist <- function(x, i){
                     lam <- paste('$\\lambda_', i, '$', sep='')
                     p <- qplot(x[i,], 
                                geom="histogram", 
                                fill = I('green'),
                                color = I('black'),
                                alpha = I(.5),  
                                main=TeX(paste("Histogram of the pc variance ", lam, sep='')),
                                xlab=TeX(lam), 
                                ylab="Count", 
                                show.legend=F)
                     return(p)
              }
              getDens <- function(x, i){
                     lam <- paste('$\\lambda_', i, '$', sep='')
                     p <- qplot(x[i,],
                                geom="density", 
                                fill = I('blue'), 
                                alpha = I(.5),  
                                main=TeX(paste("Density plot of the pc variance ", lam, sep='')),
                                xlab=TeX(lam), 
                                ylab="Density", 
                                show.legend=F)
                     return(p)
              }
              fp <- lapply(1:3, function(x) arrangeGrob(getHist(lambda.mat, x), getDens(lambda.mat, x), ncol=2))

              print(marrangeGrob(fp, nrow = 3, ncol=1, top = textGrob("Lambda.mat Histogram and Density Plot",gp=gpar(fontsize=18))))