append pdf file in R - dev.off() [duplicate] - r

This question already has answers here:
Plotting over multiple pages
(2 answers)
Closed 9 years ago.
How can I keep saving figures to a pdf with R. Consider the following example:
require(ggplot2)
require(gridExtra)
TopFolder <- "...directory on my drive"
setwd(TopFolder)
pdf(file = paste(TopFolder,"figures","example.pdf",sep = "\\"))
g <- list()
for(i in 1:4){
dat <- data.frame(d1 = c(1:10),
d2 = runif(10))
g[[i]] <- qplot(x = d1, y = d2,
data = dat)
}
grid.arrange(g[[1]],g[[2]],g[[3]],g[[4]])
for(i in 1:6){
dat <- data.frame(d1 = c(1:20),
d2 = runif(20))
qplot(x = d1, y = d2,
data = dat)
}
dev.off()
My question is: Why doesn't the sesond set of plots i.e. the 6 generated by the second for loop show up in the pdf file? The only obvious difference I can spot is that I store the plots in the first loop and do't in the second. Why doesn't R generate these plots in the second loop and save them in the pdf after completion?
The result I would expect from this example would be to have the first page of the pdf with the four subplots and then have 6 pages following with one figure in each page. Why isn't this being generated? I would have thought that R would keep generating the figures in the file until dev.off() was called?

... and all putting all commands from above together
require(ggplot2)
require(gridExtra)
TopFolder <-"...directory on my drive"
setwd(TopFolder)
pdf(file = file.path(TopFolder,"figures","example.pdf"), onefile=TRUE)
g <- list()
for(i in 1:4){
dat <- data.frame(d1 = c(1:10),
d2 = runif(10))
g[[i]] <- qplot(x = d1, y = d2,
data = dat)
}
grid.arrange(g[[1]],g[[2]],g[[3]],g[[4]])
gg <- list()
# each of this plots will be on a separate page
for(i in 1:6){
dat <- data.frame(d1 = c(1:20),
d2 = runif(20))
# here a print is necessary
print(qplot(x = d1, y = d2,
data = dat))
}
dev.off()

Related

number of items to replace is not a multiple of replacement length + several plots in same graph error

I'm trying to draw several plots in the same graph in Rstudio, but to no avail. This is the code I'm using:
for (i in 1:10){
require(ggplot2)
N <- 100
T <- 3
Delta <- T/N
B <- numeric(N+1)
t <- seq(0,T,length=N+1)
for(i in 2:(N+1)){
B[i] <- B[i-1]+rnorm(1) * sqrt(Delta)
}
x <- 0
y <- 3
BB[i] <- x+B-(t/T)*(B[N+1]-y+x)
df <- melt(data = BB, id.vars = "t")
ggplot(data = df, aes(x = t, y = value, colour = variable)) + geom_line()
}
Using ggplot2 as I seen recomended in several Stackoverflow post yieds "number of items to replace is not a multiple of replacement length".
I've seen several answers to that question but being quite a noob in R I don't see how it applies to my problem. Please and thank you in advance.
How about this:
BB <- list() # define BB as a list
for (i in 1:10){
require(ggplot2)
N <- 100
T <- 3
Delta <- T/N
B <- numeric(N+1)
t <- seq(0,T,length=N+1)
for(q in 2:(N+1)){ # Change your index from i to q
B[q] <- B[q-1]+rnorm(1) * sqrt(Delta)
}
x <- 0
y <- 3
BB[[i]] <- x+B-(t/T)*(B[N+1]-y+x) # Assign each iteration to a list entry
}
# Exit the for loop
df <- as.data.frame(cbind(unlist(BB), # unlist the values in BB
rep(t,10), # define t variable by simply repeating it
rep(1:10,each= 101))) # define loop id in a similar manner
names(df) <- c('value','t','variable') # give names to the variables
df$variable <- as.factor(df$variable) # turn variable into a factor
ggplot(data = df, aes(x = t, y = value, colour = variable)) + geom_line()
The resulting plot:

Plot undetermined number of plots using ggplot2

I am trying to plot the contents of a Principal Component Analysis using ggplot2. I would like to generate a single pdf with all plots in it with a user-specified number of principal components to show (so if user says 3, it would plot PC 1 vs 2, 1 vs 3 and 2 vs 3).
I've looked into gridextra and but not entirely sure how to add multiple plots when I don't know exactly how many components will be selected.
Here is a start, get user input (input_nPC), get combination then loop through and plot subset of data:
library(ggplot2)
# example data
myPC <- data.frame(
pc1 = runif(10),
pc2 = runif(10),
pc3 = runif(10),
pc4 = runif(10))
# user input, e.g.: 3 out of 4 PCs
input_nPC <- 3
# check: must be at least 2 PCs
input_nPC <- max(c(2, input_nPC))
# get combination
combo <- combn(input_nPC, 2)
pdf("myOutput.pdf")
for(i in seq(ncol(combo))){
d <- myPC[, combo[, i]]
d_cols <- colnames(d)
gg <- ggplot(d, aes_string(x = d_cols[1], y = d_cols[2])) +
geom_point() +
ggtitle(paste(d_cols, collapse = " vs "))
print(gg)
}
dev.off()
If we need to have output as one page PDF, then using cowplot package:
ggList <-
apply(combo, 2, function(i){
d <- myPC[, i]
d_cols <- colnames(d)
ggplot(d, aes_string(x = d_cols[1], y = d_cols[2])) +
geom_point() +
ggtitle(paste(d_cols, collapse = " vs "))
})
pdf("myOutput.pdf")
cowplot::plot_grid(plotlist = ggList)
dev.off()
Or we can use GGally::ggpairs as below:
library(GGally)
ggpairs(myPC[, 1:input_nPC])

Why are all the plots identical when plotting list of plots generated by loop?

The code below should generate five different plots contained in the list called plist. Why are all the plots identical when calling grid.arrange? The variable df changes at every iteration in the loop.
library(gridExtra)
plist <- list()
for (i in 1:5){
df <- data.frame(x=1:1000, y=rnorm(10))
plist[[i]] <- qplot(df$y, geom="histogram")
}
do.call("grid.arrange", c(plist, ncol=2))
I dont know but the problem is with qplot because this works in making different plots:
library(gridExtra)
plist <- list()
for (i in 1:5){
df <- data.frame(x=1:1000, y=rnorm(10))
plist[[i]] <- #qplot(df$y, geom="histogram")
ggplot(df, aes(x = y))+geom_histogram()
}
do.call("grid.arrange", c(plist, ncol=2))
I do not have answer either, but this works also with qplot.
library(gridExtra)
library(ggplot2)
plist <- list()
for (i in 1:5) {
df <- data.frame(x = 1:1000, y = rnorm(10))
plist[[i]] <- qplot(y, data = df, geom = "histogram")
}
do.call("grid.arrange", c(plist, ncol=2))

How to store plots in a list when inside a loop?

I'm working inside a loop and I'd like to save plots in a list so I can plot them together in a .pdf. The problem is that the list is not filled up properly and re-updates with the results of the last run. So, in the end what I get is a list with five elements that are exactly the same.
I'm aware the loops may seem useless, but I just have them to create a test code (with a reproducible error) as close to the real one as possible. So, I need to leave the loops as they are.
library (ggplot)
library (gridExtra)
plist <- list()
for (z in 1:5){
n <- 100
k <- seq(0, to=4500+z*2000, length=n)
tmp <- numeric(n)
for (i in 1:n){
tmp[i] <- (5*(i*3)^2)}
plist[[z]] <- ggplot() +
geom_line(aes(x = k, y = tmp)) +
theme_bw()
pdf(sprintf("p%s.pdf", z),
width = 6, height = 4, onefile = T)
plot(plist[[z]])
dev.off()
}
do.call(grid.arrange, c(plist, ncol = 5))
This answer is based on: Storing plot objects in a list
library(ggplot2)
library(gridExtra)
plist <- list()
for (z in 1:5){
n <- 100
k <- seq(0, to=4500+z*2000, length=n)
tmp <- numeric(n)
for (i in 1:n){
tmp[i] <- (5*(i*3)^2)}
data <- data.frame(n, k, tmp)
plist[[z]] <- ggplot(data = data) + #data needs to be given!!
geom_line(aes(x = k, y = tmp)) +
theme_bw()
pdf(sprintf("p%s.pdf", z),
width = 6, height = 4, onefile = T)
plot(plist[[z]])
dev.off()
}
do.call(grid.arrange, c(plist, ncol = 5))

Use for loop to plot multiple lines in single plot with ggplot2

I try to plot multiple lines in single plot as follow:
y <- matrix(rnorm(100), 10, 10)
m <- qplot(NULL)
for(i in 1:10) {
m <- m + geom_line(aes(x = 1:10, y = y[,i]))
}
plot(m)
However, it seems that qplot will parse m during plot(m) where i is 10, so plot(m) produces single line only.
What I expect to see is similar to:
plot(1,1,type='n', ylim=range(y), xlim=c(1,10))
for(i in 1:10) {
lines(1:10, y[,i])
}
which should contain 10 different lines.
Is there ggplot2 way to do this?
Instead of ruuning a loop, you should do this the ggplot2 way.
ggplot2 wants the data in the long-format (you can convert it with reshape2::melt()). Then split the lines via a column (here Var2).
y <- matrix(rnorm(100), 10, 10)
require(reshape2)
y_m <- melt(y)
require(ggplot2)
ggplot() +
geom_line(data = y_m, aes(x = Var1, y = value, group = Var2))
The way EDi proposed is the best way. If you you still want to use a for loop you need to use the for loop to generate the data frame.
like below:
# make the data
> df <- NULL
> for(i in 1:10){
+ temp_df <- data.frame(x=1:10, y=y[,i], col=rep(i:i, each=10))
+ df <- rbind(df,temp_df)}
> ggplot(df,aes(x=x,y=y,group=col,colour=factor(col))) + geom_line() # plot data
This outputs:

Resources