Print several plots on one PDF page in R - r

I am trying to plot 4 graphs on one single PDF page. Untill now, the only output I got was 1 file per page. I would like to have all of them on one page. One plot is stocked in "c", the three others are produced using a loop. Here is the code I use :
pdf("path_to_file.pdf", onefile = TRUE)
plot(c)
for (exp in expL) {
plot(plot_list[[exp]])
}
dev.off
I tried without the "onefile" specification, or adding :
par(mfrow=c(2,2))
or even
layout(matrix(c(1,2,3,4), ncol = 2, byrow = TRUE))
but nothing helps...
I would be grateful for some help.
Thank you very much!

c should be same type of plot as expL.
If they are, do:
library(cowplot)
plot_grid( append( list(c), expL ), nrow=2 )

Related

Suppress graph output of a function [duplicate]

I am trying to turn off the display of plot in R.
I read Disable GUI, graphics devices in R but the only solution given is to write the plot to a file.
What if I don't want to pollute the workspace and what if I don't have write permission ?
I tried options(device=NULL) but it didn't work.
The context is the package NbClust : I want what NbClust() returns but I do not want to display the plot it does.
Thanks in advance !
edit : Here is a reproducible example using data from the rattle package :)
data(wine, package="rattle")
df <- scale (wine[-1])
library(NbClust)
# This produces a graph output which I don't want
nc <- NbClust(df, min.nc=2, max.nc=15, method="kmeans")
# This is the plot I want ;)
barplot(table(nc$Best.n[1,]),
xlab="Numer of Clusters", ylab="Number of Criteria",
main="Number of Clusters Chosen by 26 Criteria")
You can wrap the call in
pdf(file = NULL)
and
dev.off()
This sends all the output to a null file which effectively hides it.
Luckily it seems that NbClust is one giant messy function with some other functions in it and lots of icky looking code. The plotting is done in one of two places.
Create a copy of NbClust:
> MyNbClust = NbClust
and then edit this function. Change the header to:
MyNbClust <-
function (data, diss = "NULL", distance = "euclidean", min.nc = 2,
max.nc = 15, method = "ward", index = "all", alphaBeale = 0.1, plotetc=FALSE)
{
and then wrap the plotting code in if blocks. Around line 1588:
if(plotetc){
par(mfrow = c(1, 2))
[etc]
cat(paste(...
}
and similarly around line 1610. Save. Now use:
nc = MyNbClust(...etc....)
and you see no plots unless you add plotetc=TRUE.
Then ask the devs to include your patch.

Plot ggplots stored in list over several pages

I know similar questions have been already asked so sorry if this is a redundant question! However, I can't seem to find a solution that arranges several ggplots from a list onto 1 page over several pages.
I have a list of approximately 100 ggplots - I want to plot every 4 ggplots on 1 page, and iterate through the list until all the ggplots have been plotted. I then want to export the approximately 25 pages to a single pdf file.
So far, I've tried:
pdf("plots.pdf", onefile = TRUE, width = 11, height = 8.5)
for (i in 0:24) {
ggarrange(list[[4i+1]], list[[4i+2]], list[[4i+3]], list[[4i+4]],
nrow = 2, ncol = 2, common.legend = TRUE, legend = 'bottom'
}
dev.off()
However, I'm getting the error that the subscript is out of bounds. I've tried narrowing the range in the for loop to try to overcome this error but it's returning the same error. I also know we can use marrangeGrob(), but I can't seem to add a common legend to the file.
Really appreciate any help!
It would be helpful if you could provide some small list of plots to test on.
I have tried to recreate your scenario, and have found that it wasn't working unless I explicitly print the ggarrange object.
plot <- ggplot(mtcars, aes(x = cyl, y = mpg)) +
geom_point()
plot_list <- list(plot, plot, plot, plot, plot, plot, plot, plot)
pdf("test.pdf", 11, 8.5)
for(i in 0:3){
print(ggarrange(plot_list[[2*i + 1]], plot_list[[2*i + 1]], nrow = 2, ncol = 1))
}
dev.off()
This worked for me. Noting akrun's comment that you forgot your * symbol.

Saving ggplot graphs to pdf not formatting correctly in PDF

This is a follow on question to my original here
I am currently trying to save the outputs of a ggplot graph to .pdf but I am running into some problems.
I run the following on the dput data on the original question (I repaste everything below).
library(gridExtra)
pdf("Plots.pdf", onefile = TRUE)
for(j in 1:length(plotList)) {
grid.arrange(plotList[[j]], nrow = 2)
}
dev.off()
This saves the files as a pdf document but instead of getting two graphs per page I get one graph which takes up half a page. Is it possible to resize the graphs, when I select nrow = 3 I get the same problem, I get one graph in the top 3rd / half of the page and a blank space for the rest. I provide a screen shot of the output:
Here is a minimal example:
# Make empty list for plots
plotList <- list()
# Build plots
library(ggplot2)
for(i in 1:2){
plotList[[i]] <-
ggplot(mtcars, aes(mpg, cyl)) +
geom_point() +
labs(title = i)
}
# Save plots
library(gridExtra)
pdf("Plots.pdf", onefile = TRUE)
for(j in 1:length(plotList)) {
grid.arrange(plotList[[j]], nrow = 2)
}
dev.off()
Credit to #LachlanO
You problem comes from how you are calling grid.arrange. By including it in a loop, you are telling it to create multiple separate plots, like this:
grid.arrange(plotList[[1]], nrow = 2)
grid.arrange(plotList[[2]], nrow = 2)
grid.arrange(plotList[[3]], nrow = 2)
What you actually are trying to do is create one grid.arrange object which contains all the plots. To do this, you need call the function against the list:
do.call("grid.arrange", c(plotList, nrow=2))
Alternatively, you can use the cowplot package and use:
cowplot::plot_grid(plotlist = plotList, nrow = 2)
So to save the PDF you can use:
pdf("Plots.pdf", onefile = TRUE)
do.call("grid.arrange", c(plotList, nrow=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))

How can I export multiple plots as a pdf in R?

How can I export multiple plots as a pdf in R ?
Does anyone know What is the command for this ?
You may want to try this:
pdf(file='plot.pdf')
plot(1:10)
dev.off()
Since you didn't provide any reproducible example I just give you the example written above. See the documentation by doing ?pdf and ?dev.off()
Multiple plots would be (adding to Jilber)
pdf(file='plot.pdf')
par(mfrow=(c(1,3)))
plot(1:10)
plot(rnorm(10)
plot(rnorm(10)
dev.off()
or You can use the plyr package to create a pdf with multiple plots
library(ply)
pdf("plots.pdf", width = 7, height = 7)
d_ply(df, .(z), failwith(NA, function(x){plot(x$y,main=unique(z))}), .print=TRUE)
dev.off()
were df is a data frame containing a conditional factor (z) and a target variable (y). You will get as many plots as z levels, all included in a pdf report.
The above answers will help you to export the plots in table but if you want them to be in table like 2-3 graphs in 1 row, you can use following code:
pdf("Export_Plots.pdf", width = 16 , height = 10, title = "EDA Plots for data")
par(mfrow=c(2,2))
for(i in 1:10){
par(mar = c(5,4,4,5)+.1)
plot(i)
}
dev.off()
Please check below link for more detail:
https://topbullets.com/2017/04/19/exporting-multiple-graphs-in-same-plot-to-pdf-in-r-topbullets-com/

Resources