I want to use a loop in order to create multiple plots for different values of DPC. The data I have looks like:
df <- data.frame (c ("Results", "Capacity", "Power", "LDI","LDE", "LB", "PDC","D", CostPerkWh)
As output I would like multiple graphs with graphs for each unique value of PDC.
The following plot work:
plot1 <- ggplot(subset(df, df$PDC=='PDC0'),
aes(Capacity, CostPerkWh))+ geom_point()+geom_line()
plot2 <- ggplot(subset(df, df$PDC=='PDC0.25'),
aes(Capacity, CostPerkWh))+ geom_point()+geom_line()
plot3 <- ggplot(subset(df, df$PDC=='PDC0.5'),
aes(Capacity, CostPerkWh))+ geom_point()+geom_line()
plot4 <- ggplot(subset(df, df$PDC=='PDC0.75'),
aes(Capacity, CostPerkWh))+ geom_point()+geom_line()
plot5 <- ggplot(subset(df, df$PDC=='PDC1'),
aes(Capacity, CostPerkWh))+ geom_point()+geom_line()
All these plots work,however I would like to create a loop since I have a large amount of parameters and I found this example.
So I tried to implement it into my own model:
#plot data
StoreResults <- "/Users/IMA/Documents/Results/"
PDC.graph <- function(df, na.rm = TRUE, ...){
PDClist <- unique(df$PDC)
for (i in seq_along(PDClist)){
plot <-
ggplot(subset(df, df$PDC==PDClist[i]),
aes(Capacity, CostPerkWh)) + geom_point()+
ggtitle(paste(PDClist, 'PDC, Power \n', "Capacity \n", sep='')) +
geom_line()
print(plot)
#save plot as PNG
ggsave(plot, file= paste(StoreResults, '/projection_graphs/PDCgraph/',
PDClist[i], ".png", sep=''), scale=2)
}
}
The code does not give me an error message, but I don't see any graphs and nothing gets stored into the folder that is defined; how to resolve this? Or is there a better way to export many graph for different values of PDC?
Didn't you forget running the function you created?
This minimal version works for me:
df = iris
StoreResults <- "/Users/timfaber/Desktop"
PDC.graph <- function(df, na.rm = TRUE, ...){
PDClist <- unique(df$Species)
for (i in seq_along(PDClist)){
ggplot(subset(iris, df$Species==PDClist[i]),
aes(Sepal.Length, Sepal.Width)) + geom_point() +
ggtitle(paste(PDClist[i], 'PDC, Power \n', "Capacity \n", sep=''))
#save plot as PNG
ggsave(plot = last_plot(), file= paste(StoreResults, '/etc/',
PDClist[i], ".png", sep=''), scale=2)
}
}
PDC.Graph(df)
Related
I am running a lot of graphs across different subsets of data, using the split function with the lapply function.
My problem is: How do I easily save all the graphs? Ideally I want to name each fileby the title of the graph (Indicating the subset of data).
data("mtcars")
split <- split(mtcars, list(mtcars$gear, mtcars$am))
my_plot <- function(mtcars) {
ggplot(mtcars, aes(x=mpg, y=cyl)) +
geom_point() +
labs (title= paste(unique(mtcars$gear), paste("- ", unique(mtcars$am)))) }
lapply(split, my_plot)
Thus far, I have been saving the temporary directory (But this is a lot of manual labour)
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)
file.copy(from=plots.png.paths, to="......")
You could include ggsave in your function, then we would loop over the names() of split instead:
data("mtcars")
library(ggplot2)
split <- split(mtcars, list(mtcars$gear, mtcars$am))
my_plot <- function(x) {
p <- ggplot(split[[x]], aes(x=mpg, y=cyl)) +
geom_point() +
labs (title= paste(unique(split[[x]][["gear"]]), paste("- ", unique(split[[x]][["am"]]))))
ggsave(paste0("my_path/mtcars_", x, ".png"))
p
}
lapply(names(split), my_plot)
Alternatively we could use a slightly different workflow with purrr::map and purrr::iwalk(). First we create a list of plots with purrr::map and than loop over the named lists of plots using purrr::iwalk() to save them:
library(purrr)
my_plot <- function(df, nm) {
ggplot(df, aes(x=mpg, y=cyl)) +
geom_point() +
labs (title= paste(unique(df[["gear"]]), paste("- ", unique(df[["am"]]))))
}
# save plots to list
plots <- map(split, my_plot)
# loop over plots and save
iwalk(plots, ~ ggsave(paste0("my_path/mtcars_", .y, ".png"),
plot = .x))
Created on 2023-02-16 by the reprex package (v2.0.1)
I want to make a plot of the Daily Streamflow in each Station and save it in png format. I want a separate png for each station, something like the image below:
I have a list with the data frame for each station, as shown in the figure below:
I am trying using the following code, but it is not working because R aborted, I am not sure if it is because of the quantity of data:
for (i in 1:length(listDF2))
{
df1 <- as.data.frame(listDF2[[i]])
df1[is.na(df1)] <- 0
temp_plot <- ggplot(df1, aes(x = day, y = DailyMeanStreamflow, colour=Station)) +
geom_line(size = 1) +
geom_point(size=1.5, shape=21, fill="white") +
facet_wrap(~ month, ncol = 3) +
labs(title = "Daily Mean Streamflow",
subtitle = "Data plotted by month",
y = "Daily Mean Streamflow [m3/s]", x="Days") +
scale_y_continuous (breaks=seq(0,max(df1$DailyMeanStreamflow, na.rm=TRUE),by=1500)) +
scale_x_continuous (breaks=seq(1,max(df1$day),by=1)) + theme(axis.text.x = element_text(size=9))
print(temp_plot)
name4<- paste("DailyStreamflow_byMonth","_", siteNumber[i], ".png", sep="")
ggsave(temp_plot,filename = name4,width=22,height=11,units="in",dpi=500)
#while (!is.null(dev.list()))
dev.off()
}
I have also a "big" data frame with the data for each station one after the other. This data frame is useful when I want to apply functions like data_frame %>% group_by(station) %>% summarise(...)
Any idea in how to make the plots for each station? Is it better to use the list or the "big" data frame for this purpose?
I am not sure where the problem in your workflow occures. It is quite hard to help you, as we have not minimal working example. Also I am not sure if you just want to produce your plots in a loop or if you (also) want to put them together in one visualization?
Anyways ... I tried to give you a starting point ... maybe this will help?
"%>%" <- magrittr::"%>%"
df_list <- list(
A=dplyr::tibble(ID=1:10,
x=rnorm(10),
y=rnorm(10)),
B=dplyr::tibble(ID=1:10,
x=rnorm(10),
y=rnorm(10)),
C=dplyr::tibble(ID=1:10,
x=rnorm(10),
y=rnorm(10)),
D=dplyr::tibble(ID=1:10,
x=rnorm(10),
y=rnorm(10)))
# Lapply approach
lapply(df_list, function(dat){
p <- dat %>%
ggplot2::ggplot(ggplot2::aes(x=x,y=y)) +
ggplot2::geom_point()
print(p)
})
# Loop approach
for (i in 1:length(df_list)){
p <- df_list[[i]] %>%
ggplot2::ggplot(ggplot2::aes(x=x,y=y)) +
ggplot2::geom_point()
print(p)
fname <- paste("test","_", i, ".png", sep="")
ggsave(p,
filename=fname,
width=22,
height=11,
units="in",
dpi=500)
}
For some reason, in this loop the PDFs that it produces end up corrupt. However, when I plot each individually it is saved and I can open them. Please advise, going mad!
for (l in 1:length(which_genes)) {
gene_name <- which_genes[[l]]
cases_values <- cases[cases$HGNC == genes[gene_name],]
controls_values <- controls[controls$HGNC == genes[gene_name],]
t <- t.test(cases_values[c(2:ncol(cases_values))], controls_values[c(2:ncol(controls_values))])
case <- cbind(t(cases_values[c(2:ncol(cases_values))]), "cases")
cont <- cbind(t(controls_values[c(2:ncol(controls_values))]), "controls")
dat <- as.data.frame(rbind(case, cont))
names(dat) <- c("expression", "type")
dat$expression <- as.numeric(dat$expression)
#plot significant genes
pdf(file = paste(genes[gene_name], "_different.pdf", sep=""))
ggplot(dat, aes(type, expression, fill=type)) +
geom_boxplot() +
ggtitle(paste(genes[gene_name], "pvalue", t$p.value)) +
xlab("cases vs controls")
dev.off()
}
Yet another instance of the failure-to-print error (as described in the R-FAQ). Use this instead inside the loop:
pdf(file = paste(genes[gene_name], "_different.pdf", sep=""))
print( ggplot(dat, aes(type, expression, fill=type)) +
geom_boxplot() +
ggtitle(paste(genes[gene_name], "pvalue", t$p.value)) +
xlab("cases vs controls")
)
dev.off()
If the goal was to have a multi-page output then you should have opened the PDF-device outside the loop, print-ed within the loop, and then closed the device outside.
My code for multiple plots is as
for (i in 3:5) {
#paste(names(normalized_ge_data))
file_name = paste(as.character(i), ".png")
png(file_name)
g + geom_boxplot(aes(fill=factor(ge_data$hasServiced))) + geom_jitter()
dev.off()
}
I want to have files like 3.png, 4.png, and so on.
How to achieve this?
If the OP is looking to strictly print the plots, the best method is probably to store the plots in a list during the loop, and then print each item in the list. Here's a suggestion:
library(ggplot2)
plot_list <- list()
for (ii in 1:5){
temp_df <- data.frame(x=rnorm(n=15, mean=0, sd=5),
y=rnorm(n=15, mean=0, sd=5),
z=rnorm(n=15, mean=0, sd=5))
temp_plot <- ggplot(temp_df, aes(x=x, y=y, color=z))+
geom_point()+
theme_bw()+
ggtitle(paste("Group", ii))
plot_list[[ii]] <- temp_plot
}
lapply(plot_list, print)
Of course, you could alter the lapply call to use ggsave or whatever function you'd like to use to save the plots.
I think for ggplot the best way to do this is with the ggsave() function:
for (i in 3:5) {
qplot(mtcars[, i])
ggsave(file = paste0("plot_", i, ".png"))
}
Documentation here: http://docs.ggplot2.org/0.9.2.1/ggsave.html
Following #Daniel 's suggestion above, this works:
g <- ggplot(mtcars, aes(factor(cyl), mpg))
for (i in 3:5) {
#paste(names(normalized_ge_data))
file_name = paste(as.character(i), ".png")
png(file_name)
print(g + geom_boxplot(aes(fill=factor(cyl))) + geom_jitter())
dev.off()
}
I tried your example with some sample data, and it works for me:
library(sjmisc)
library(ggplot2)
data(efc)
for (i in 3:5) {
file_name = paste0(as.character(i), ".png")
png(file_name)
plot(ggplot(efc, aes(x = 1, y = e17age)) + geom_boxplot() + geom_jitter())
dev.off()
}
w/o the plot, only white, empty png's are created.
I am running R version 3.1.1. in RStudio and am having difficulties with grid.arrange.
I am reading sales data for over 100 stores and plotting the sales over time. I am also trying to group the plots to display a set number at a time.
However, after many different attempts, the command
do.call("grid.arrange", c(plotlist, ncol=nCol))
results in all plots in the plot matrix being identical. Further, plotting individual items from the plotlist demonstrates that all plots are stored as identical elements in the plotlist as well.
Here is code that duplicates the issue:
require(ggplot2)
require(gridExtra)
wss <- data.frame(ind=1:10, dep=(1:10))
plotlist <- list()
for (i in 1:4) {
wss <- data.frame(ind=wss$ind, dep=(i*wss$dep))
plotname <- paste0("Store", i, sep="")
plotlist[[ plotname ]] <- ggplot(data=wss, aes(x=wss$ind, y=wss$dep)) + geom_line() + theme_bw() + ggtitle(paste0("Store #",i, sep="")) + ylab("Sales Revenue") + theme(axis.title.x=element_blank())
}
n <- length(plotlist)
nCol <- floor(sqrt(n))
do.call("grid.arrange", c(plotlist, ncol=nCol))
I had the same issue, and used lapply instead of the "for", it seemed to fix the problem.
pList <- lapply(1:4, function(i){
p <- ggplot(data=wss, aes(x=wss$ind, y=wss$dep)) + geom_line() + theme_bw() + ggtitle(paste0("Store #",i, sep="")) + ylab("Sales Revenue") + theme(axis.title.x=element_blank())
}
# print 1 by 1
for (i in 1:4){
print(pList[[i]])
}
print all
g <- grid.arrange(grobs=pList, ncol=2, nrow=2)