1

I am trying to create a plot where for each i there is a density graph and a histogram side by side. For this instance i = 1..3

The problem I have is creating the list to pass to grid.arrange. However I do it it seems to repeat itself somehow.

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

Anyone have any clue what I am doing wrong or is this just not possible?

Jay
  • 36
  • 4
  • I would put a lot of `print` or `write.table` or `pdf` commands to debug every single step of `i` & `j` and find out what went wrong – Tung Mar 15 '18 at 03:57
  • I have done this and at least during the loop the graphs are forming properly. There seems to be a problem in either how the list is being stored, which is exactly how a much simpler example was done and worked, or in how grid.arrange is handling the list. – Jay Mar 15 '18 at 10:30

2 Answers2

0

I don't understand your code, Jay, as it seems to do lots of things and use both base and ggplot plotting, but if all you want is to create a combined histogram and density plot for each j, why not loop over j and inside that for j loop do something like this:

d <- your density plot created so that it depends on j only

h <- your histogram plot created so that it depends on j only

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

Then, when you come out of the loop, you'll have an object p which consists of a list of plots, with each plot consisting of a combination of density plot and histogram.

Then you could use the cowplot package (after installing it) to do something like this:

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

where the number of columns may need to be changed. See here for other ways to plot a list of plots: How do I arrange a variable list of plots using grid.arrange?

I don't know enough about your problem to understand why you treat the case of j even and j odd differently. But the underlying idea should be the same as what I suggested here.

Isabella Ghement
  • 715
  • 6
  • 14
0

I eventually got this working as follows.

              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))))
Jay
  • 36
  • 4