R autoplot works when running line-by-line but not when source-ing R script - r

I'm observing a very strange behaviour with R.
The following code works when I type it in line-by-line into an instance of R run from my terminal. (OS is Debian Linux.)
However it does not work when I try and run source("script.R").
It also does not work from within R Studio.
Specifically, it fails to produce graphical output with autoplot. Writing to pdf file does not work, and if I remove the pdf() and dev.off() lines, no window containing the figure is opened.
Here's a copy of my script...
library(lubridate)
library(ggplot2)
library(matrixStats)
library(forecast)
df_input <- read.csv("postprocessed.csv")
x <- df_input$time
y <- df_input$value
df <- data.frame(x, y)
x <- df$x
y <- df$y
holtmodel <- holt(y)
pdf("autoplot.pdf")
autoplot(holtmodel)
dev.off()
And for convenience, here's a datafile.
"","time","value"
"1",1,2.61066016308988
"2",2,3.41246054742996
"3",3,3.8608767964033
"4",4,4.28686048552237
"5",5,4.4923132964825
"6",6,4.50557049744317
"7",7,4.50944447661246
"8",8,4.51097373134893
"9",9,4.48788748823809
"10",10,4.34603985656981
"11",11,4.28677073671406
"12",12,4.20065901625172
"13",13,4.02514194962519
"14",14,3.91360194972916
"15",15,3.85865748409081
"16",16,3.81318053258601
"17",17,3.70380706527433
"18",18,3.61552922363713
"19",19,3.61405310598722
"20",20,3.64591327503384
"21",21,3.70234435835577
"22",22,3.73503970503372
"23",23,3.81003078640584
"24",24,3.88201196162666
"25",25,3.89872518158949
"26",26,3.97432743542362
"27",27,4.2523675144599
"28",28,4.34654855854847
"29",29,4.49276038902684
"30",30,4.67830892029687
"31",31,4.91896819673664
"32",32,5.04350767355202
"33",33,5.09073406942046
"34",34,5.18510849382162
"35",35,5.18353176529036
"36",36,5.2210776270173
"37",37,5.22643491929207
"38",38,5.11137006553725
"39",39,5.01052467981257
"40",40,5.0361056705898
"41",41,5.18149486951409
"42",42,5.36334869132276
"43",43,5.43053620818444
"44",44,5.60001072279525
Pretty confused because it seems like a trivial script!

change it to:
print(autoplot(holtmodel))
When you step through code, you get an implicit print(...) statement on each code line. When you source() you don't. ggplot (and others!) use print() to trigger their ploting (so that you can conveniently build up a plot step by step without having to wait for flickering figures)

Related

levelplot() not rendering png from commandline [duplicate]

I started using the lattice graphic package but I stumbled into a problem. I hope somebody can help me out.
I want to plot a histogram using the corresponding function.
Here is the file foo.r:
library("lattice")
data <- data.frame(c(1:2),c(2:3))
colnames(data) <- c("RT", "Type")
pdf("/tmp/baz.pdf")
histogram( ~ RT | factor(Type), data = data)
dev.off()
When I run this code using R --vanilla < foo.r it works all fine.
However, if I use a second file bar.r with
source("bar")
and run R --vanilla < bar.r the code produces an erroneous pdf file.
Now I found out that source("bar", echo=TRUE) solves the problem. What is going on here? Is this a bug or am I missing something?
I'm using R version 2.13.1 (2011-07-08) with lattice_0.19-30
It is in the FAQ for R -- you need print() around the lattice function you call:
7.22 Why do lattice/trellis graphics not work?
The most likely reason is that you forgot to tell R to display the
graph. Lattice functions such as xyplot() create a graph object, but
do not display it (the same is true of ggplot2 graphics, and Trellis
graphics in S-Plus). The print() method for the graph object produces
the actual display. When you use these functions interactively at the
command line, the result is automatically printed, but in source() or
inside your own functions you will need an explicit print() statement.
Example of the case
visualise.r
calls plot2this.r
calls ggplot2 and returns p object
Here the fix in the function plot2this.r from return(p) to return(print(p)).
Initial plot2this.r
p <- ggplot(dat.m, aes(x = Vars, y = value, fill=variable))
return(p)
Fix
p <- ggplot(dat.m, aes(x = Vars, y = value, fill=variable))
return(print(p))
Output now: expected output with the wanted plot.

Saving plots to working directory - plots are blank? [duplicate]

I started using the lattice graphic package but I stumbled into a problem. I hope somebody can help me out.
I want to plot a histogram using the corresponding function.
Here is the file foo.r:
library("lattice")
data <- data.frame(c(1:2),c(2:3))
colnames(data) <- c("RT", "Type")
pdf("/tmp/baz.pdf")
histogram( ~ RT | factor(Type), data = data)
dev.off()
When I run this code using R --vanilla < foo.r it works all fine.
However, if I use a second file bar.r with
source("bar")
and run R --vanilla < bar.r the code produces an erroneous pdf file.
Now I found out that source("bar", echo=TRUE) solves the problem. What is going on here? Is this a bug or am I missing something?
I'm using R version 2.13.1 (2011-07-08) with lattice_0.19-30
It is in the FAQ for R -- you need print() around the lattice function you call:
7.22 Why do lattice/trellis graphics not work?
The most likely reason is that you forgot to tell R to display the
graph. Lattice functions such as xyplot() create a graph object, but
do not display it (the same is true of ggplot2 graphics, and Trellis
graphics in S-Plus). The print() method for the graph object produces
the actual display. When you use these functions interactively at the
command line, the result is automatically printed, but in source() or
inside your own functions you will need an explicit print() statement.
Example of the case
visualise.r
calls plot2this.r
calls ggplot2 and returns p object
Here the fix in the function plot2this.r from return(p) to return(print(p)).
Initial plot2this.r
p <- ggplot(dat.m, aes(x = Vars, y = value, fill=variable))
return(p)
Fix
p <- ggplot(dat.m, aes(x = Vars, y = value, fill=variable))
return(print(p))
Output now: expected output with the wanted plot.

R script that should plot xts class data to a png file doesn't produce a png file

I had a working script that used a loop to produce many png file plots of xts class data. Now the script throws an error and if I comment out the line throwing the error (a call to abline() ) then the script executes but without producing a png file. The issue seems to involve plotting xts class data and/or a loop or script.
Searching on stackoverflow didn't provide a solution or reference to this issue. I've reproduced the issue in the following example. In practice, the script would use different filenames within the loop and non-trivial data.
# put following code in 'myscript.R' and execute using source('myscript.R',print.eval=TRUE) or source('myscript.R')
# xts class data
data <- xts(seq(1:10),order.by=as.Date(seq(1:10)))
# a non xts version of same data
#data <- seq(1:10)
for(i in 1:1) {
filename <- 'myfile.png'
png(filename)
plot(data)
lines( (data-1),col='red')
abline(h=1)
dev.off()
}
# The call to abline in above script with xts class data gives error 'plot.new has not been called yet'
# If comment out the call to abline it completes but doesn't produce a png file
# script works fine with abline for non xts data
Using xts >= 0.10.1, this saves to file what you want
for(i in 1:1) {
filename <- 'myfile.png'
png(filename)
plot(data)
print(lines( (data-1),col='red', on = 1))
print(lines(xts(x = rep(1, NROW(data)), order.by = index(data)),col='green', on= 1) )
dev.off()
}
Use the print calls for the extra lines. I'd also use lines for the horizonal line, instead of abline, as this is more consistent with plotting with xts.
Also your error can be avoided if you do print(abline(h=1))

Use of recordPlot() and replayPlot() in Parallel in R to save plot in the same PDF

I would like to plot data in parallel using foreach in R but I didn't find any way to get all my plots in the same pdf file. I thought of using recordPlot to save my plots in a list and then print them in a pdf device but it doesn't work.
I have the following error :
Error in replayPlot(x) : loading snapshot from a different session
I tried as well with ggplot but this is to slow with my large dataset.
Here is a piece of code showing my problem :
# Creating a dataframe : df
df=as.data.frame(matrix(nrow=1, ncol=10))
df=apply(df, 2, function(x) runif(100))
# Plotting function
par.plot=function(dat){
plot(dat)
p=recordPlot()
return(p)}
#Applying the function in parallel
library("parallel")
library("foreach")
library("doParallel")
cl <- makeCluster(detectCores())
registerDoParallel(cl, cores = detectCores())
plot.lst = foreach(i = 1:nrow(df)) %dopar% {
par.plot(df[i,])
}
# Trying to get 1st plot
plot.lst[[1]]
Error in replayPlot(x) : loading snapshot from a different session
Replacing %dopar% by %do% is working when I try to get my plots, because they seems to have been generated in the same environment.
I know I can call a pdf device inside the loop to generate a file for each iteration, but I would like to know if there is a way to get one file for all my plots at the output of my function.
Or do you know an easy way to merge my pdf files afterwards ?
Thanks for your help.
Charles
In my opinion your question can be devided into two distinctive parts:
1. Using the replayPlot function in th%dopar% without getting the weird error
2. Somehow getting 1 file at the end
The first question is easy to answer. The reason you get this error is that the R somehow remembers where (in OS level) the plots has been generated. You can get the same effect by using Rstudio server and trying to replay some of the recorded plots after couple of hours of closing the browser tab. In brief, the issue is that R remembers the PID of the process that generated the plot (Don't know why though!):
# generate a plot
plot(iris[, 1:2]
# record the plot
myplot <- recordPlot()
# check the PID
attr(x = myplot, which = "pid")
the good thing is you can overwrite this by assigning your current PID:
attr(x = myplot, which = "pid") <- Sys.getpid()
so you should only change the last line of your code to the following:
pdf(file = "plot.lst.pdf"))
graphics.off()
lapply(plot.lst, function(x){
attr(x = x, which = "pid") <- Sys.getpid()
replayPlot(x)})
graphics.off()
The part above entirely solves your problem, but in case you are interested in merging PDF files, follow this discussion:
Merging existing PDF files using R

R package lattice won't plot if run using source()

I started using the lattice graphic package but I stumbled into a problem. I hope somebody can help me out.
I want to plot a histogram using the corresponding function.
Here is the file foo.r:
library("lattice")
data <- data.frame(c(1:2),c(2:3))
colnames(data) <- c("RT", "Type")
pdf("/tmp/baz.pdf")
histogram( ~ RT | factor(Type), data = data)
dev.off()
When I run this code using R --vanilla < foo.r it works all fine.
However, if I use a second file bar.r with
source("bar")
and run R --vanilla < bar.r the code produces an erroneous pdf file.
Now I found out that source("bar", echo=TRUE) solves the problem. What is going on here? Is this a bug or am I missing something?
I'm using R version 2.13.1 (2011-07-08) with lattice_0.19-30
It is in the FAQ for R -- you need print() around the lattice function you call:
7.22 Why do lattice/trellis graphics not work?
The most likely reason is that you forgot to tell R to display the
graph. Lattice functions such as xyplot() create a graph object, but
do not display it (the same is true of ggplot2 graphics, and Trellis
graphics in S-Plus). The print() method for the graph object produces
the actual display. When you use these functions interactively at the
command line, the result is automatically printed, but in source() or
inside your own functions you will need an explicit print() statement.
Example of the case
visualise.r
calls plot2this.r
calls ggplot2 and returns p object
Here the fix in the function plot2this.r from return(p) to return(print(p)).
Initial plot2this.r
p <- ggplot(dat.m, aes(x = Vars, y = value, fill=variable))
return(p)
Fix
p <- ggplot(dat.m, aes(x = Vars, y = value, fill=variable))
return(print(p))
Output now: expected output with the wanted plot.

Resources