This R code is to create an animated plot, I have run it and it did run but I have not been able to view it. it is said to save it output on pdf file though I saw the file but unable to open it. I got the code at How do I transfer output of animation R package on a beamer frame
because I want to learn how to input R animated plot on latex thus I was given this as an example. can you show me how I can view its output either on Rstudio or where the code saves it to? If you mean that the output can be viewed on pdf that is originally saved to, show me how? I am using Acrobat Reade Dc.
brownianMotion <- function(n=10,xlim=c(-20,20),ylim=c(-20,20),steps=50)
{
x=rnorm(n)
y=rnorm(n)
for (i in 1:steps) {
plot(x,y,xlim = xlim,ylim = ylim)
text(x,y)
# iterate over particles
for(k in 1:n){
walk=rnorm(2); # random move of particle
x[k]=x[k]+walk[1] # new position
y[k]=y[k]+walk[2]
# simple model for preventing a particle from moving past the limits
if(x[k]<xlim[1]) x[k]=xlim[1]
if(x[k]>xlim[2]) x[k]=xlim[2]
if(y[k]<ylim[1]) y[k]=ylim[1]
if(y[k]>ylim[2]) y[k]=ylim[2]
}
}
}
pdf("frames.pdf") # output device and file name
par(xaxs="i", yaxs="i", pty="s") # square plot region
par(mai=c(0.9,0.9,0.2,0.2)) # plot margins
brownianMotion(n=20, steps=400) # 20 particles, 400 time steps
There are two things here :
you need to add dev.off() after plotting so that the current plot is saved to the output device
the loop over step is rewriting the same filename for each plot, so that you end-up in having only the last frame in frames.pdf. Following this tutorial, you should rather write separate pdf files to an output folder, then animate them within LaTeX.
brownianMotion <- function(n=10,xlim=c(-20,20),ylim=c(-20,20),steps=50){
x=rnorm(n)
y=rnorm(n)
for (i in 1:steps) {
pdf(paste0("out/frames", i, ".pdf")) # save frames{i}.pdf to 'out' folder
plot(x,y,xlim = xlim,ylim = ylim)
text(x,y)
dev.off() # Adding dev.off()
...
}
}
par(xaxs="i", yaxs="i", pty="s") # square plot region
par(mai=c(0.9,0.9,0.2,0.2)) # plot margins
if (!dir.exists("out")) dir.create("out") # create 'out' folder if it doesn't exist
brownianMotion(n=20, steps=4) # 20 particles, 4 steps
The out folder will be located where your working directory is (use getwd() to see it).
Related
I am wondering if there is a way to send the output plot from the checkresiduals() function to a pdf file.
I have the following command :-
checkresiduals(ts_regr_auto_new_objects[[1]], test = FALSE, plot = TRUE)
This generates a series of plots including ACF plot, residual density plot and the residual plot.
Will try and attach the image - for some reason its not doing it now but hopefully can reproduce the image again later.
The image is attached now :-
I can save the save the image as a pdf file from the RStudio console but I would like to be able to do so from code as this is a part of a larger application code.
Best regards
Deepak
I'm not familiar with checkresiduals, but generally it should be possible to save PDF with base R:
# start PDF output
pdf(file = "plot.pdf", paper = "a4")
# some graphics
hist(rnorm(100))
# end of output, save file
dev.off()
So for your case probably this:
pdf(file = "plot.pdf", paper = "a4")
checkresiduals(ts_regr_auto_new_objects[[1]], test = FALSE, plot = TRUE)
dev.off()
See documentation... Hope this helps.
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))
I have read, if tikz takes a raster image it is to be stored as png. Having that, tikz produces the rest of the graph around it and include the raster image in the final tex-file back again.
Now I have the following:
pic <- T
if(pic)
{
tikz(file=paste(plotpath,"Rohdaten_S1_S2_D21.tex",sep=""),width=width,height=height,engine = "pdftex",)
#png(filename=paste(plotpath,"Rohdaten_S1_S2_D6.png",sep=""),width=width,height=height,res=res,units="in")
par(mfrow=c(2,1),mar=c(1.1,3,2,0),mgp=c(1.5,0.5,0),ps=f.size,cex=1,xaxt="n")
}
if(!pic) par(mfrow=c(2,1),mar=c(1,4,3,0))
for(i in 1:2)
{
x <- sensors[[i]]$time
y <- sensors[[i]]$depth
z <- sensors[[i]]$velo
image(x,y,z)
# plot.image(x,y,z
# ,xlim=c(max(x)-400,max(x)),zlim=2*c(-1,1)
# ,xlab="",ylab="$d/\\mathrm{m}$",zlab="$v/(\\mathrm{mm/s})$"
# ,z.adj=c(0,0),ndz=5,z.cex=1
# )
abline(v=(1:10)/0.026+par("usr")[1],lty=2)
if(!pic) abline(h=(1:floor(max(y/0.02)))*0.02)
mtext(text=paste("Sensor",i),side=3,line=0.1,adj=0)
par(mar=c(3,3,0.1,0),xaxt="s")
}
title(xlab="t/s")
if(pic) dev.off()
even the simple image() function will produce a 100MB large .tex file.
No png is produced, everything is in the .tex file?!
What am I doing wrong? Is there a switch to be set TRUE? What do I have to do to put the rasterimage apart from the nice looking text.
Thank you for your help.
The solution is quite simple, but not obvious.
the image()-function in R produces vector graphics in the first
instance. There is a switch image(...,useRaster = T) with which
one can force the image()-function to produce raster graphics.
the image()-function aspects a regular grid (quadratic pixels). Otherwise an error occurs.
How to get a regular grid?
Suppose you have an image with the coordinates x[],y[] and the scalar matrix z[,]. Then the re-sampled regular grid can be calculated:
x.new<-seq(min(xlim),max(xlim),length.out=dim.max[1])
y.new<-seq(min(ylim),max(ylim),length.out=dim.max[2])
z<-apply(z,2,function(y,x,xout) return(approx(x,y,xout=xout+min(diff(x))/2,method="constant",rule=2)$y),x,x.new)
z<-t(apply(z,1,function(y,x,xout) return(approx(x,y,xout=xout+min(diff(x))/2,method="constant",rule=2)$y),y,y.new))
tikz(file ='a.tex',width = 2, height = 2)
image(x,y,z,useRaster = T)
dev.off()
The important things are the method = "constant" and the rule = 2 statements in the approx()-function. These enables a "shifting" to the regular grid.
Applying all this and tikz() will split the picture in a a.tex-file and a a_ras1.png-file.
I hope this will help sombody programming R and using tikzDevice to produce pictures for tex documents.
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
I have run into the following problem and I would appreciate if someone could give me some input.
I would like to export multiple figures to a single jpeg file. I first create a graphics lattice and then I export. My main issue is that it works with the pdf and not the jpeg. Any ideas?
Thank you
#set the windows of the frames
par(mfcol=c(3,2))
#create the jpeg file
jpeg(filename=names(a1),".jpg",sep=""),
quality=100,
width=1024,
height=768)
#plot 1
plot(a1,b1)
#plot 2
plot(a1,b2)
#plot 3
plot(a1,b3)
#plot 4
plot(a2, c1)
#plot 5
plot(a2, c2)
#plot 6
plot(a2, c3)
#dev.off shuts down the specified (by default the current) graphical device
#here it passes the picture to the file
dev.off()
It is not clear whether you want multiple 1024x768 images in a single jpeg file - which doesn't make sense - are whether you want a single jpeg image containing the 6 plots.
As I said, JPEGs are not a multi-page format, unlike a PDF. Hence you can get R to export to multiple JPEG files but not have all the separate figures in one JPEG.
R's devices allow for wildcards in the filenames, so if you want the six plots exported to files foo001.jpeg, foo002.jpeg, foo00x.jpeg then you can use the following
jpeg(filename = "foo%03d.jpeg", ....)
.... # plotting commands here
dev.off()
What happens if you do multiple plots without the wildcard/placeholder is document in say ?jpeg:
If you plot more than one page on one of these devices and do not
include something like ‘%d’ for the sequence number in ‘file’, the
file will contain the last page plotted.
Devices that handle multiple pages because the underlying file format allows it can take multiple plots into the single file as there is makes sense, e.g. pdf() and postscript(). Those devices have argument onefile which can be used to indicate if multiple plots in a single file are required.
However, the par(mfcol=c(3,2)) makes me think you want a 3x2 set of plots in the same device region. That is allowed, but you need to call par() after you open the jpeg() device, not before. What your code, as shown, does is split the active device into 3x2 plotting regions and then opens a new device which picks up the default parameters, not the ones you set on the device active before you called jpeg(). This is illustrated below:
> plot(1:10)
> dev.cur()
X11cairo
2
> op <- par(mfrow = c(3,2))
> jpeg("~/foo.jpg")
> par("mfrow")
[1] 1 1
> dev.off()
X11cairo
2
> par("mfrow")
[1] 3 2
Hence you want perhaps wanted something like:
jpeg(filename=names(a1),".jpg",sep=""), quality=100,
width=1024, height=768)
op <- par(mfcol=c(3,2))
#plot 1
plot(a1,b1)
#plot 2
plot(a1,b2)
#plot 3
plot(a1,b3)
#plot 4
plot(a2, c1)
#plot 5
plot(a2, c2)
#plot 6
plot(a2, c3)
par(op)
dev.off()
?
The corrected code
#data
a1<-seq(1,20,by=1)
b1<-seq(31,50,by=1)
b2<-seq(51,70,by=1)
b3<-seq(71,90,by=1)
#create the jpeg file
jpeg(filename="a.jpg",
quality=100,
width=1024,
height=768)
#set the create the frames
par(mfcol=c(3,1))
#plot the graphs
plot(a1,b1)
plot(a1,b2)
plot(a1,b3)
#par(op)
#dev.off shuts down the specified (by default the current) graphical device
#here it passes the picture to the file
dev.off()