Reputation: 1456
I have a list of data.frames and I want to plot each row of each data.frame using ggplot. I'm looking to store these into a variable so then I can plot these in a png in a 20x12 format. Meaning 20 graphs across and 12 down.
Each data.frame in the list would get it's own png file.
df = data.frame(matrix(rnorm(n=240), nrow = 240, ncol = 602))
df_list = list(df,df,df)
plots=list(list(list()))
for (i in 1:length(df_list)){
for (k in 1:240){
testdf = as.numeric(t(df[[i]][k,2:ncol(df[[i]])]))
testtime = seq_along(df[[i]])
test =((cbind(testtime,testdf)))
test = as.data.frame(test)
plots[[k]]=ggplot(aes(`1`,testdf),data=test)+geom_line()
}
plots[i]=rbind(plots[[k]],plots)
}
The following code gets me the last loop of [i] but it doesnt save the first few loops. Any ideas?
Bonus Points if you know how to plot each [i] into separate png files in a matrix of plots measuring 20x12.
Upvotes: 2
Views: 2179
Reputation: 146110
Okay. I don't like your data - it's all boring straight lines. Let's generate some new data - and since it's all numeric I'll leave it as a matrix instead of converting to data frame:
input = replicate(
n = 3,
matrix(rnorm(n = 240 * 602), nrow = 240, ncol = 602),
simplify = F
)
Just like in Mark's answer, I'll convert it to long format. Since it's a matrix, we don't need all the data frame editing tools, I'll just as.vector
the matrix and add on the index
and id
columns.
The plotting code is mostly untouched from Mark's answer.
plots <- lapply(input, function(mm) {
# if you really need to start with data frames, not matrices
# just put here: mm = as.matrix(mm)
df_long = data.frame(id = 1:nrow(mm), index = rep(1:ncol(mm), each = nrow(mm)), value = as.vector(mm))
ggplot(df_long, aes(x = index, y = value)) +
geom_line() +
facet_wrap(~id, nrow = 20) +
theme(strip.text = element_blank())
})
Now, these plots are big! You've got 240 subplots in each list item - I would advise against trying to look at them too much in the GUI. Instead, let's save them as nicely compressed png
s and view the files.
for (i in seq_along(plots)) {
ggsave(filename = sprintf("myplot%s.png", i),
plot = plots[[i]],
height = 30, width = 18)
}
I can't upload a plot because it exceeds the maximum filesize - and even then each subplot is pretty small. You may want to up the height and width even more.
This answer is very close to Mark's excellent answer - the only differences are the method of reshaping the data and the extra bit on saving.
Upvotes: 1
Reputation: 9570
If you are willing to tidy your data, you can use this, which will automatically generate the 20x12 layout for each of the data.frames:
library(tidyverse)
df = data.frame(matrix(rnorm(n=240), nrow = 240, ncol = 602)) %>%
mutate(id = 1:nrow(.)) %>%
gather(index, value, -id) %>%
mutate(index = parse_number(index))
df_list = list(df,df,df)
catch <- lapply(df_list, function(df){
ggplot(df
, aes(x = index
, y = value)) +
geom_line() +
facet_wrap(~id
, nrow = 20
, ncol = 12) +
theme(strip.text = element_blank())
})
One of the plots:
Note that you will want to make thematic changes, particularly if you want to be able to label the individuals, but this at least generates the layout you wanted.
Upvotes: 3