R: Cannot Output Plots To Files From A Loop - r

I am trying to output a series of the file using the R.
Usually, we can use the following code to output a plot:
jpeg("XXXXX_XXXX.jpg")
ggplot(data=YEAR_ZIP_DATA, aes(x=SOME_VARIABLE)) + geom_bar()
dev.off()
The above code can get me a file in the current working directory called XXXXX_XXXX.jpg
Now I want to write a loop to create a series of file: for each year, draw a bar chart for each zip code and save to the current directory. Here is the code:
# year_list: a list of distinctive years
for(year in year_list){
# zip_list: a list of distinctive zip codes
for(zip in zip_list){
# some code to get a filename like 10010_2018.jpg
filename <- (some code)
# some code to subset the data to get the current zip and year
year_zip_data <- (some code)
jpeg(filename)
ggplot(data=year_zip_data, aes(x=SOME_VARIABLE)) + geom_bar()
dev.off()
}
}
However, after the above loop, there is nothing in the current working directory... How should I solve the problem?
Thanks in advance!

Try ggsave function. It directly saves the graphics object created by ggplot.

Related

save multiple plots r into separate jpg

Dear Stackoverflow'ers!
I have simple database, app. 130 variables, 1500 records and lots of similar plots to create. I try to avoid save them by hand. The for loop works perfectly for plots (in RStudio).
Here are the data as .csv on dropbox.
data <- read.csv2("data.csv", header=TRUE)
data <- select(data,v1,v2,v3,v4,v5,v6,v7)
for (i in data) {
sjp.frq(i)
}
I would like to save the plots in some directory as a separate .png or .jpg files. I found some clues here. The code looks like this:
data <- select(df,v1,v2,v3,v4,v5,v6,v7)
variables <- names(data)
for (i in data) {
png(paste0("plots/plot_",names(data)[i],".png"))
sjp.frq(i)
dev.off()
}
I deliberately simplified the sjp.frq expression to not make the code unnessecarely complicated.
And here's the problem. I get only single .png file in folder. Where do I make mistake? There should be seven of them.
Best regards, MaciejB.
PS. I follow the suggestion of making code reproducible and added sample of my databaase. When I use i.e. iris, it works. It seems to be something wrong with my data, some NA's maybe? But when I used na.omit() it's the same.
PS.2 I checked another ploting functions like hist() or plot() but it's the same. Only one plot produced and saved.
This works here!
data1 <- read.csv2("~/Temp/data.csv", header=TRUE)
data <- select(data1,v1,v2,v3,v4,v5,v6,v7)
variables <- names(data)
dane=1:length(variables)
for (i in dane ) { #i=2
png(paste0("Temp/plot_",names(data)[i],".png"))
sjp.frq(data[,i],title = names(data)[i])
dev.off()
}
Here 3 of all plots:

Save all plots already present in the panel of Rstudio

I've made different plots (more than a hundred) for a project and I haven't capture them on the way (yes it's bad , i know). Now, I need to save them all at once but without running again my script (which takes hours). Is there a way to do so within Rstudio ?
Edit: All the plot are already there and I don't want to run them again.
In RStudio, every session has a temporary directory that can be obtained using tempdir(). Inside that temporary directory, there is another directory that always starts with "rs-graphics" and contains all the plots saved as ".png" files. Therefore, to get the list of ".png" files you can do the following:
plots.dir.path <- list.files(tempdir(), pattern="rs-graphics", full.names = TRUE);
plots.png.paths <- list.files(plots.dir.path, pattern=".png", full.names = TRUE)
Now, you can copy these files to your desired directory, as follows:
file.copy(from=plots.png.paths, to="path_to_your_dir")
Additional feature:
As you will notice, the .png file names are automatically generated (e.g., 0078cb77-02f2-4a16-bf02-0c5c6d8cc8d8.png). So if you want to number the .png files according to their plotting order in RStudio, you may do so as follows:
plots.png.detials <- file.info(plots.png.paths)
plots.png.detials <- plots.png.detials[order(plots.png.detials$mtime),]
sorted.png.names <- gsub(plots.dir.path, "path_to_your_dir", row.names(plots.png.detials), fixed=TRUE)
numbered.png.names <- paste0("path_to_your_dir/", 1:length(sorted.png.names), ".png")
# Rename all the .png files as: 1.png, 2.png, 3.png, and so on.
file.rename(from=sorted.png.names, to=numbered.png.names)
Hope it helps.
Although this discussion has been inactive for a while, there are some persons, like myself, who still come across the same problem, and the other solutions don't really seem to even get what the actual question is.
So, hands on. Your plot history gets saved in a variable called .SavedPlots. You can either access it directly, assign it to another variable in code or do the latter from the plots window.
# ph for plot history
ph <- .SavedPlots
In R 3.4.2, I could index ph to reproduce the corresponding plot in a device. What follows is rather straightforward:
Open a new device (png, jpeg, pdf...).
Reproduce your plot ph[index_of_plot_in_history].
Close the device (or keep plotting if it is a pdf with multiple pages).
Example:
for(i in 1:lastplot) {
png('plotname.png')
print(ph[i])
dev.off()
}
Note: Sometimes this doesn't happen because of poor programming. For instance, I was using the MICE package to impute many datasets with a large number of variables, and plotting as shown in section 4.3 of this paper. Problem was, that only three variables per plot were displayed, and if I used a png device in my code, only the last plot of each dataset would be saved. However, if the plots were printed to a window, all the plots of each dataset would be recorded.
If your plots are 3d, you can take a snapshot of all your plots and save them as a .png file format.
snapshot3d(filename = '../Plots/SnapshotPlots.png', fmt = 'png')
Or else, the best way is to create a multi-paneled plotting window using the par(mfrow) function. Try the following
plotsPath = "../Plots/allPlots.pdf"
pdf(file=plotsPath)
for (x in seq(1,100))
{
par(mfrow = c(2,1))
p1=rnorm(x)
p2=rnorm(x)
plot(p1,p2)
}
dev.off()
You can also use png, bmp, tiff, and jpeg functions instead of pdf. You can read their advantages and disadvantages and choose the one you think is good for your needs.
I am not sure how Rstudio opens the device where the plot are drawn, but I guess it uses dev.new(). In that case one quick way to save all opened graphs is to loop through all the devices and write them using dev.print.
Something like :
lapply(dev.list(),function(d){dev.set(d);dev.print(pdf,file=file.path(folder,paste0("graph_",d,".pdf"))})
where folder is the path of the folder where you want to store your graph (could be for example folder="~" if you are in linux and want to store all your graph in your home folder).
If you enter the following function all that will follow will be save in a document:
pdf("nameofthedocument.pdf")
plot(x~y)
plot(...
dev.off()
You can also use tiff(), jpg()... see ?pdf

output ggplot results in one pdf but several pages in R

I have at least 10 plots by ggplot(we can call them plot1, plot2 ....). I can output them into separate pdf files. But I prefer to output them in only one pdf file but several pages. One page, one plot from ggplot.
I tried to list all plots and use ggsave but it can not work. Any idea or script can help? Thank you
See the pdf function for this.
For three plots it would look like this (saving into your working directory with default naming). Run through dev.off line before you can open file.
pdf()
plot1
plot2
plot3
dev.off()
If your plots are already stored in a list named list1:
pdf()
list1
dev.off()
Based on aosmith's answer, here's a simple wrapper function to save lists of ggplot2 plots to a single pdf.
GG_save_pdf = function(list, filename) {
#start pdf
pdf(filename)
#loop
for (p in list) {
print(p)
}
#end pdf
dev.off()
invisible(NULL)
}

Make 1 jpeg file with separately named plot for each original csv file in R, jpeg function?

I am trying to create a loop in R that does the following. I have a map with for example 10 datasets: file1.txt.csv, file2.txt.csv, etc. Now I simply want to create one graph per data set and output that, so that I get file1.jpeg, file2.jpeg, etc.
This is what I got so far:
fileNames <- Sys.glob("*.txt.csv")
for (fileName in fileNames) {
VolumeData <- read.delim(fileName, header = FALSE)
# convert data frame to data table
VolumeDatat <- VolumeData [, -(7:14)]
# set column names
setnames(VolumeDatat, c("MCS", "cell_type", "cell_number", "total_volume"))
jpeg(sub(".txt.csv",".jpg"))
plot(VolumeDatat$total_volume~VolumeDatat$MCS,type="l")
dev.off()
}
And I guess that
jpeg (sub(".txt.csv",".jpg"))
is the essential part for this, but I can't figure this out, also the arguments for jpeg in the library didn't help me much further.
First, I tried with jpeg (fileName.jpeg), which works, but only for the last file in the loop as the file gets overwritten for each time you run the script, e.g. each file.
So now I tried it with some sub-function, cause I thought that might work, but by doing so, I got:
Error in sub(".txt.csv", ".jpg") :
argument "x" is missing, with no default
Could anyone help me with this? I'd be very grateful!

R: using previously determined variable as part of png file name

I am still new to R and I have searched around for a solution to my simple question, but I haven't found an answer that I've been able to get to work. I am looking to use a previously identified variable per data set, here variable=SNPname to include in script for automated generation of graph output in png format.
I am using this to generate a kmeans plot and have:
(cl <- kmeans(FilteredData[,6:7], 5, nstart=25))
png("C:/temp/$SNPnamegraph1.png") #SNPname to include in filename
plot(FilteredData[,6:7], col=cl$cluster)
points(cl$centers, col=1:5, pch=8)
dev.off()
where I want to include that variable in line 2 at the beginning of the file name. Is there a simple way to do this that I am just missing?
Close, you're just missing the use of paste() and setwd()
setwd("C:/temp/") # use this to set where you want things saved
...
c1 <- kmeans...
png(paste(SNPname, " graph1.png", sep=""))
...
If it's in a loop of some kind, you might need to use SNPname[loop_var]

Resources