Saving S3 aggr object in a way mice_plots can be visualized by ggplot in a grid arrangement - r

I am using a for loop to loop through a dataset and produce a mice_plot per category. In the for loop, I would like to save the produced mice_plot so that I can later plot them all in a grid.
my code looks like this atm:
for center in unique(df$center){
dispatch_centers <- list()
mice_plot <- aggr(center, ...)
# save mice_plot some how in a way I can later open it with ggplot
as.grob()?
#add to list
center_plots[[center]] <- mice_plot
}
grid.arrange(grobs = center_plots, ncol = 2)
However, I do not understand the aggr() object nor how to save it so I can later handle it with ggplot2. Does anyone have any ideas?

Related

Set common y axis limits from a list of ggplots

I am running a function that returns a custom ggplot from an input data (it is in fact a plot with several layers on it). I run the function over several different input data and obtain a list of ggplots.
I want to create a grid with these plots to compare them but they all have different y axes.
I guess what I have to do is extract the maximum and minimum y axes limits from the ggplot list and apply those to each plot in the list.
How can I do that? I guess its through the use of ggbuild. Something like this:
test = ggplot_build(plot_list[[1]])
> test$layout$panel_scales_x
[[1]]
<ScaleContinuousPosition>
Range:
Limits: 0 -- 1
I am not familiar with the structure of a ggplot_build and maybe this one in particular is not a standard one as it comes from a "custom" ggplot.
For reference, these plots are created whit the gseaplot2 function from the enrichplot package.
I dont know how to "upload" an R object but if that would help, let me know how to do it.
Thanks!
edit after comments (thanks for your suggestions!)
Here is an example of the a gseaplot2 plot. GSEA stands for Gene Set Enrichment Analysis, it is a technique used in genomic studies. The gseaplot2 function calculates a running average and then plots it and another bar plot on the bottom.
and here is the grid I create to compare the plots generated from different data:
I would like to have a common scale for the "Running Enrichment Score" part.
I guess I could try to recreate the gseaplot2 function and input all of the datasets and then create the grid by facet_wrap, but I was wondering if there was an easy way of extracting parameters from a plot list.
As a reproducible example (from the enrichplot package):
library(clusterProfiler)
data(geneList, package="DOSE")
gene <- names(geneList)[abs(geneList) > 2]
wpgmtfile <- system.file("extdata/wikipathways-20180810-gmt-Homo_sapiens.gmt", package="clusterProfiler")
wp2gene <- read.gmt(wpgmtfile)
wp2gene <- wp2gene %>% tidyr::separate(term, c("name","version","wpid","org"), "%")
wpid2gene <- wp2gene %>% dplyr::select(wpid, gene) #TERM2GENE
wpid2name <- wp2gene %>% dplyr::select(wpid, name) #TERM2NAME
ewp2 <- GSEA(geneList, TERM2GENE = wpid2gene, TERM2NAME = wpid2name, verbose=FALSE)
gseaplot2(ewp2, geneSetID=1, subplots=1:2)
And this is how I generate the plot list (probably there is a much more elegant way):
plot_list = list()
for(i in 1:3) {
fig_i = gseaplot2(ewp2,
geneSetID=i,
subplots=1:2)
plot_list[[i]] = fig_i
}
ggarrange(plotlist=plot_list)

Make multiple histograms at once and save them

I would like to make histogram of columns 5-34 of my data set and save them for reference. This is what I have and the error 'x must be numeric' is what keeps coming up. All of these columns have numeric data.
[data screenshot][1]
dput(longbroca)
histograms = c()
GBhistograms = c()
RThistograms = c()
for (i in 5:34){
hist(longbroca)
hist(GBlongbroca)
hist(RTlongbroca)
histograms = c(histograms, hist(longbroca[,5:34]))
GBhistograms = c(GBhistograms, hist(GBlongbroca[,5:34]))
RThistograms = c(RThistograms, hist(RTlongbroca[,5:34]))
}
#reproducible
fakerow1 <- c(100,80,60,40,20)
fakerow2 <- c(100,80,60,40,20)
fakedata = rbind(fakerow1,fakerow2)
colnames(fakedata) = c('ant1','ant2','ant3','ant4','ant5')
You cannot plot all of the columns with a single hist() function. That is why you are getting the error message. You are plotting histograms and saving the output list from the histogram. Your code does not save any histograms, only the data for producing them. If you actually want to save the plotted histograms, you need to plot them to a device (e.g. pdf).
We can use the iris dataset which comes with R (data(iris)) as some example data. The first 4 columns are numeric. If you just want the data for the histograms from the iris data set (columns 1 through 4):
# R will plot all four but you will only see the last one.
histograms <- lapply(iris[, 1:4], hist)
The variable histograms is a list that contains 6 elements. These are documented on the manual page for the function (?hist).
# To plot one of the histograms with a title and x-axis label:
lbl <- names(histograms)
plot(histograms[[1]], main=lbl[1], xlab=lbl[1])
# To plot them all
pdf("histograms.pdf")
lapply(1:4, function(x) plot(histograms[[x]], main=lbl[x], xlab=lbl[x]))
dev.off()
The file "histograms.pdf" will have all four histograms, one per page.

Generate list of R plotly plots and pass it to subplot

I usually generate subplots in a for loop when using base R graphics (using par(mfrow=c(nr,nc))). I'm trying to do something similar with plotly, by generating a series of plots and saving them to a list to be later passed to the subplot function. However, for reasons that I don't understand, at the end of the loop all the elements of the list seem to contain the same plot (the last one). If I print each plot in the list within the loop (uncommenting the line starting with print in the example below), then the plots seem fine). I don't really understand what's going on. Could someone explain this unexpected behavior or point out issues with my example code below?
library(plotly)
plotList = list()
plotListNames = c("p1", "p2", "p3")
for (i in 1:3){
x = rnorm(10)
y = rnorm(10)
thisName = plotListNames[i]
plotList[[thisName]] = plot_ly(x=x,y=y, name=thisName)
##print(plotList[[thisName]]
}
sbp = subplot(plotList[["p1"]], plotList[["p2"]], plotList[["p3"]])
print(sbp)
try this:
plotList[[thisName]] = plotly_build(plot_ly(x=x,y=y, name=thisName))

Plot multiple ggplot2 on same page

I have a working loop which generates and can save individual plots from each file saved in a directory.
I want to plot all of the returned plots in a single file as a 2x2 grid over multiple pages but cannot do this.
I have tried to save the plot objects in a list
pltList <- list()
pltList[]
for (f in 1:length(files)){
plot_object <- ggplot2(...) #make ggplot2 plot
print(plot_object)
pltList[[f]] <- plot_object #save ggplot2 plot in list
}
jpeg(filename.jpg)
par(mfrow=c(2,2)) #to generate 2x2 plot per page
print(pltList[[1]])
print(pltList[[2]])
...
print(pltList[[f]])
dev.off()
The problem is that the resulting saved .jpg file only contains the last plot and not a 2x2 grid of all plots over many pages which is what I want.
EDIT
My first problem is how to save each plot from the loop in the list - how can I view the saved objects from the list to make sure they have been saved correctly?
When I do print(pltList[1]), the resulting output is:
function (x, y, ...)
UseMethod("plot")
<bytecode: 0x0000000010f43b78>
<environment: namespace:graphics>
rather than the actual plot. It seems that the plots are not being saved in the list as expected. How can I correct for this?
Hopefully, once this is fixed, your plotting suggestions will work.
I did recently the same. I used grid.arrange().
library(ggplot2)
library(gridExtra)
library(grid)
p1<-ggplot()+geom_line(aes(x=1:10,y=1:10))
p2<-ggplot()+geom_line(aes(x=1:10,y=1:10))
p3<-ggplot()+geom_line(aes(x=1:10,y=1:10))
p4<-ggplot()+geom_line(aes(x=1:10,y=1:10))
grid.arrange(p1,p2,p3,p4, ncol=1, top=textGrob("Multiple Plots", gp=gpar(fontsize=12, font = 2)))
Assuming you need a PDF output where every page has multiple plots plotted as one, e.g.: if there are 12 plots then 4 plots per page.
Try this example:
library(ggplot2)
library(cowplot)
# list of 12 dummy plots, only title is changing.
pltList <- lapply(1:12, function(i){
ggplot(mtcars,aes(mpg,cyl)) +
geom_point() +
ggtitle(paste("Title",i))})
# outputs 3 jpeg files with 4 plots each.
for(i in seq(1,12,4))
ggsave(paste0("Temp",i,".jpeg"),
plot_grid(pltList[[i]],
pltList[[i+1]],
pltList[[i+2]],
pltList[[i+3]],nrow = 2))
# or we can output into 1 PDF with 3 pages using print
pdf("TempPDF.pdf")
for(i in seq(1,12,4))
print(plot_grid(pltList[[i]],
pltList[[i+1]],
pltList[[i+2]],
pltList[[i+3]],nrow = 2))
dev.off()
EDIT:
Another way using gridExtra, as suggested by #user20650:
library(gridExtra)
#output as PDF
pdf("multipage.pdf")
#use gridExtra to put plots together
marrangeGrob(pltList, nrow=2, ncol=2)
dev.off()

ggplot2 : printing multiple plots in one page with a loop

I have several subjects for which I need to generate a plot, as I have many subjects I'd like to have several plots in one page rather than one figure for subject.
Here it is what I have done so far:
Read txt file with subjects name
subjs <- scan ("ListSubjs.txt", what = "")
Create a list to hold plot objects
pltList <- list()
for(s in 1:length(subjs))
{
setwd(file.path("C:/Users/", subjs[[s]])) #load subj directory
ifile=paste("Co","data.txt",sep="",collapse=NULL) #Read subj file
dat = read.table(ifile)
dat <- unlist(dat, use.names = FALSE) #make dat usable for ggplot2
df <- data.frame(dat)
pltList[[s]]<- print(ggplot( df, aes(x=dat)) + #save each plot with unique name
geom_histogram(binwidth=.01, colour="cyan", fill="cyan") +
geom_vline(aes(xintercept=0), # Ignore NA values for mean
color="red", linetype="dashed", size=1)+
xlab(paste("Co_data", subjs[[s]] , sep=" ",collapse=NULL)))
}
At this point I can display the single plots for example by
print (pltList[1]) #will print first plot
print(pltList[2]) # will print second plot
I d like to have a solution by which several plots are displayed in the same page, I 've tried something along the lines of previous posts but I don't manage to make it work
for example:
for (p in seq(length(pltList))) {
do.call("grid.arrange", pltList[[p]])
}
gives me the following error
Error in arrangeGrob(..., as.table = as.table, clip = clip, main = main, :
input must be grobs!
I can use more basic graphing features, but I d like to achieve this by using ggplot. Many thanks for consideration
Matilde
Your error comes from indexing a list with [[:
consider
pl = list(qplot(1,1), qplot(2,2))
pl[[1]] returns the first plot, but do.call expects a list of arguments. You could do it with, do.call(grid.arrange, pl[1]) (no error), but that's probably not what you want (it arranges one plot on the page, there's little point in doing that). Presumably you wanted all plots,
grid.arrange(grobs = pl)
or, equivalently,
do.call(grid.arrange, pl)
If you want a selection of this list, use [,
grid.arrange(grobs = pl[1:2])
do.call(grid.arrange, pl[1:2])
Further parameters can be passed trivially with the first syntax; with do.call care must be taken to make sure the list is in the correct form,
grid.arrange(grobs = pl[1:2], ncol=3, top=textGrob("title"))
do.call(grid.arrange, c(pl[1:2], list(ncol=3, top=textGrob("title"))))
library(gridExtra) # for grid.arrange
library(grid)
grid.arrange(pltList[[1]], pltList[[2]], pltList[[3]], pltList[[4]], ncol = 2, main = "Whatever") # say you have 4 plots
OR,
do.call(grid.arrange,pltList)
I wish I had enough reputation to comment instead of answer, but anyway you can use the following solution to get it work.
I would do exactly what you did to get the pltList, then use the multiplot function from this recipe. Note that you will need to specify the number of columns. For example, if you want to plot all plots in the list into two columns, you can do this:
print(multiplot(plotlist=pltList, cols=2))

Resources