qq plot in loop not plotting [duplicate] - r

In the following example, I want to write the residuals plot of each model in a file. I do not need to see them in my display.
for (i in 1:500){
temp.model<-lme(as.formula(paste("Var",i) ~ X1*X2, sep=""), data = example, random=~1| Exp/Person)
jpeg(paste("C:/Myfolder", i, ".jpg", sep = ""), quality=50, bg="white")
plot(temp.model)
dev.off ()
graphics.off()
}
When I run this code without loop, I obtain what I want. However, it creates blank files within the loop.
Any ideas?
Thank you.

The answer is in the FAQ, FAQ 7.22 in fact. However this is not obvious until you realize that the plot.lme function from the nlme package uses lattice/trellis graphics to do the actual plotting (there are references on the help page for plot.lme, but not obvious).
The short form of the solution (but I still recommend reading the FAQ and the other documentation to fully understand the issue) is to wrap the plot in a print command.

Related

Error: plot.new has not been called yet

The following code produces an image. No problem.
change <- function(score, d, k, p) {k*(score - 1/(1+k^(d/p)))}
parameters <- c(10:110)
colorshelf <-rainbow(length(parameters), start=1/6) #yellow is low
for(i in seq_along(parameters)) {
curve(change(score=1, d=x, k=parameters[i], p=-800), from=-500, to=500, add=T, ylim=c(0, 100), col=colorshelf[i], xlab="rating difference", ylab="gain for winning")
}
legend.index <- round(quantile(seq_along(parameters)))
legend.param <- legend.index + min(parameters)
legend.color <- colorshelf[legend.index]
legend("right", title="k-factor", lty=c(1,1), legend=legend.param, col=legend.color)
Now I would like to save the image to a file with specified resolution. So I add:
png(filename="gain by ratingdiff.png", res=30, width = 1000, height = 1000)
and
dev.off()
before and after the code block. But then I get two errors, complaining about plot.new has not been called yet.
I know this issue came up like a million times. And there are so many posts about this here on stackoverflow. But none of these really helped me out. I tried adding plot.new() at different places in the code. But that did not help.
The help page on plot.new() reads:
"This function (frame is an alias for plot.new) causes the completion of plotting in the current plot (if there is one) and an advance to a new graphics frame. This is used in all high-level plotting functions and also useful for skipping plots when a multi-figure region is in use. "
But is this really what I want? I mean, I want to draw everything in one graphics device, so why would I want to cause the completion of plotting, except maybe at the end of the code.
Others have suggested, the problem is related to the usage of RStudio, but I do not use RStudio. I use Notepad++ in combination with NppToR.
Also, someone suggested to add { } around the code block (did not work).
Please help.
Before using curve()function is needed to run plot(). That is why you have a problem when saving the plot.
Before running:
for(i in seq_along(parameters)) {
curve(change(score=1, d=x, k=parameters[i], p=-800), from=-500, to=500, add=T, ylim=c(0, 100), col=colorshelf[i], xlab="rating difference", ylab="gain for winning")}
you need to run plot() giving the margins, labels and information useful to represent your images.

Why am I unable to see multiple plots appear with a for loop?

This is my code which is part of a larger script.
for(d1 in names(survD)){
survfit1 <- survfit(Surv(time=survD[[d1]][,"time"],
event=survD[[d1]][,"death"],type='right')~1)
png(paste(survPath,"/surv_",d1,".png",sep=""))
plot(survfit1,xlab="Years",ylab="Survival probability",xmax=xmax1)
}
I don't have a good idea of what this code does yet, so I'm trying to look at each individual plot to see what it is. The problem is, whenever I run this in the R command line in the terminal in linux, nothing appears. I have to use dev.off() multiple times and then rerun this code:
plot(survfit1)
for something to appear. How can I see all the plots?
Sounds like this is really what you want:
for(d1 in names(survD)){
survfit1 <- survfit(Surv(time=survD[[d1]][,"time"],
event=survD[[d1]][,"death"],type='right')~1)
x11() ## open up new graphical window for each plot (to avoid overwriting)
plot(survfit1,xlab="Years",ylab="Survival probability",
xmax=xmax1, main = d1) ## use different titles to distinguish those plots
}
This will produce plots on normal graphical windows.
If you want to use the original code, you'd better do this way:
for(d1 in names(survD)){
survfit1 <- survfit(Surv(time=survD[[d1]][,"time"],
event=survD[[d1]][,"death"],type='right')~1)
png(paste(survPath,"/surv_",d1,".png",sep=""))
plot(survfit1,xlab="Years",ylab="Survival probability",xmax=xmax1)
dev.off()
}
Then, have a look at the directory given by getwd(). All the plots are saved in png files.
Calling Sys.sleep(.1) might help during the for loop. Maybe try:
for(d1 in names(survD)){
survfit1 <- survfit(Surv(time=survD[[d1]][,"time"],
event=survD[[d1]][,"death"],type='right')~1)
Sys.sleep(.1)
png(paste(survPath,"/surv_",d1,".png",sep="", collapse="))
plot(survfit1,xlab="Years",ylab="Survival probability",xmax=xmax1)
dev.off()
}

How achieve auto-numbering in R?

This is very elementary for those who use R... (But I do stats with Stata and Mplus.)
I develop many plots (638 in total) and want to save all in separate files. It worked well first, not now
for(i in 001:638){
## command for plot comes here, including mentioning of i ##
dev.copy(png,'plot-%d.png')
dev.off()
}
I want one file for each plot, but end up with a single plot file (plot_1.png), with only the last plot.
Christopher
png function will do this by default. For example, this will create 10 plots in your working directory.
png("plot-%d.png")
for(i in 1:10) plot(1:i)
dev.off()
You'll want to use one of the paste() functions to create your string.
Since you didn't provide a reproducible example I can only guess, but I think that something like this would probably work.
paste("plot",i,".png", sep = "")
in place of your current use of c style % replacement. So this
for(i in 001:638){
#command for plot comes here, including mentioning of i ##
dev.copy(png,paste("plot",i,".png", sep = ""))
dev.off()
}

How can I plot multiple residuals plots in a loop?

In the following example, I want to write the residuals plot of each model in a file. I do not need to see them in my display.
for (i in 1:500){
temp.model<-lme(as.formula(paste("Var",i) ~ X1*X2, sep=""), data = example, random=~1| Exp/Person)
jpeg(paste("C:/Myfolder", i, ".jpg", sep = ""), quality=50, bg="white")
plot(temp.model)
dev.off ()
graphics.off()
}
When I run this code without loop, I obtain what I want. However, it creates blank files within the loop.
Any ideas?
Thank you.
The answer is in the FAQ, FAQ 7.22 in fact. However this is not obvious until you realize that the plot.lme function from the nlme package uses lattice/trellis graphics to do the actual plotting (there are references on the help page for plot.lme, but not obvious).
The short form of the solution (but I still recommend reading the FAQ and the other documentation to fully understand the issue) is to wrap the plot in a print command.

Save ggplot within a function

I'm trying to save a ggplot within a function using graphics devices. But I found the code produces empty graphs. Below is a very very simple example.
library(ggplot2)
ff <- function(){
jpeg("a.jpg")
qplot(1:20, 1:20)
dev.off()
}
ff()
If I only run the content of the function, everything is fine. I know that using ggsave() will do the thing that I want, but I am just wondering why jpeg() plus dev.off() doesn't work. I tried this with different versions of R, and the problem persists.
You should use ggsave instead of the jpeg(); print(p); dev.off() sequence. ggsave is a wrapper that does exactly what you intend to do with your function, except that it offers more options and versatility. You can specify the type of output explicitly, e.g. jpg or pdf, or it will guess from your filename extension.
So your code might become something like:
p <- qplot(1:20, 1:20)
ggsave(filename="a.jpg", plot=p)
See ?ggsave for more details
The reason why the original behaviour in your code doesn't worked is indeed a frequently asked question (on stackoverlflow as well as the R FAQs on CRAN). You need to insert a print statement to print the plot. In the interactive console, the print is silently execututed in the background.
These plots have to be printed:
ff <- function(){
jpeg("a.jpg")
p <- qplot(1:20, 1:20)
print(p)
dev.off()
}
ff()
This is a very common mistake.

Resources