0

Thought it would be easy but am running out of ideas here. I have three data.frame that I would like to plot in a single figure such that plot-A would contain line plots using data of column A from all the data.frame i.e., DF1,DF2,DF3, plot-B should contain line plots using data of column B from all data.frame and likewise for C. In the past I use facet_wrap, however, I have no idea how to go about this. here is my simple code which does not produce any plot but will give an idea what I want. A ggplot option would be great.

library(gridExtra)

DF1 = data.frame(Month = 1:12, A = runif(12, 1,10), B = runif(12,5,10), C = runif(12, 3,9))
DF2 = data.frame(Month = 1:12, A = runif(12, 4,13), B = runif(12,6,14), C = runif(12, 3,12))
DF3 = data.frame(Month = 1:12, A = runif(12, 2,15), B = runif(12,1,9), C = runif(12, 3,15))

G1 = plot(DF1$Month, y=DF1$A, "l")
lines(DF2$A, col = "red")
lines(DF3$A, col = "blue")

G2 = plot(DF1$Month, y=DF1$B, "l")
lines(DF2$B, col = "red")
lines(DF3$B, col = "blue")

G3 = plot(DF1$Month, y=DF1$C, "l")
lines(DF2$C, col = "red")
lines(DF3$C, col = "blue")

grid.arrange(G1,G2,G3, ncol = 3)

Note: in my example, I have three columns in each data.frame, however, I would like to apply the code over data.frame that have a large number of columns- not just three. so automating the process would help.

CForClimate
  • 335
  • 5
  • 19
  • *"single figure"* and *"plot-A would contain"* ... do you mean one PNG (or such) with three plots side-by-side? – r2evans Oct 31 '19 at 02:00
  • @r2evans One PNG with three side by side plots – CForClimate Oct 31 '19 at 02:54
  • (Just curious, is there a reason in the base-R calls that you name `y=` but neither `x=` nor `type=`?) – r2evans Oct 31 '19 at 02:57
  • Not sure if understood but `x` would be same for all- irresepective of `data.frame` used. I was just trying to convey my message, we can definitely use `type` with additional feature of `plot` functionality. – CForClimate Oct 31 '19 at 03:11
  • 1
    Your choice to not name `x=` and to name `y=` and not name `type=` is not invalid code, but it seems to straddle code practice/convention, that's all. Like I said, I'm just curious about that one, it is not meant as judgement or a criticism. (BTW: based on your comment to Louis, I suggest you need to be a little clearer in your question that you are trying to automate this based on larger numbers of columns. It's generally a good reproducible question, but that part was not clear to me either.) – r2evans Oct 31 '19 at 03:16
  • Thank you @r2evans- all these help. I immigrate from MATLAB so still learning by doing/asking/reading :). I agree, I should have made my question more clearer. If you have thoughts on automating this over larger numbers of columns- I would highly appreciate. – CForClimate Oct 31 '19 at 03:28

2 Answers2

2

Use:

par(mfrow=c(1,3))

DF1 = data.frame(Month = 1:12, A = runif(12, 1,10), B = runif(12,5,10), C = runif(12, 3,9))
DF2 = data.frame(Month = 1:12, A = runif(12, 4,13), B = runif(12,6,14), C = runif(12, 3,12))
DF3 = data.frame(Month = 1:12, A = runif(12, 2,15), B = runif(12,1,9), C = runif(12, 3,15))

plot(DF1$Month, y=DF1$A, "l")
lines(DF2$A, col = "red")
lines(DF3$A, col = "blue")

plot(DF1$Month, y=DF1$B, "l")
lines(DF2$B, col = "red")
lines(DF3$B, col = "blue")

plot(DF1$Month, y=DF1$C, "l")
lines(DF2$C, col = "red")
lines(DF3$C, col = "blue")

You can reset the plotting area back to 1 x 1 with dev.off()

EDIT: A ggplot solution would be:

library(ggplot2)
library(gridExtra)
p1 <- ggplot(NULL)+
  geom_line(data = DF1,aes(x=Month,y=A),color="black")+
  geom_line(data = DF2,aes(x=Month,y=A),color="red")+
  geom_line(data = DF3,aes(x=Month,y=A),color="blue")

p2 <- ggplot(NULL)+
  geom_line(data = DF1,aes(x=Month,y=B),color="black")+
  geom_line(data = DF2,aes(x=Month,y=B),color="red")+
  geom_line(data = DF3,aes(x=Month,y=B),color="blue")

p3 <- ggplot(NULL)+
  geom_line(data = DF1,aes(x=Month,y=C),color="black")+
  geom_line(data = DF2,aes(x=Month,y=C),color="red")+
  geom_line(data = DF3,aes(x=Month,y=C),color="blue")

grid.arrange(p1,p2,p3,nrow=1)
LouisMP
  • 321
  • 1
  • 12
  • Hello Louis, this works. However, if each of my `data.frame` have around 12 columns then this solution would be too laborious. I guess, using `gather` or `melt` to arrange the three `data.frame` into sort of a summary `data.frame` and then using `facet_wrap` or `Facet_grid` may be a good way to automate the process- Sadly I have some understanding however, just can't come up with a solution. thanks for suggesting workaround. – CForClimate Oct 31 '19 at 03:06
2

Like this

The only manual step is giving each data.frame an identifying column (possibly automate using this? Add column containing data frame name to a list of data frames)

Then you combine them all into one dataframe and gather the columns so that the data.frame is in long form. You can then use with facet_grid/facet_wrap as you mentioned

DF1 = data.frame(Month = 1:12, A = runif(12, 1,10), B = runif(12,5,10), C = runif(12, 3,9))
DF2 = data.frame(Month = 1:12, A = runif(12, 4,13), B = runif(12,6,14), C = runif(12, 3,12))
DF3 = data.frame(Month = 1:12, A = runif(12, 2,15), B = runif(12,1,9), C = runif(12, 3,15))


DF1$df <- "1"
DF2$df <- "2"
DF3$df <- "3"

library(tidyr)
library(ggplot2)
AllDf <- rbind(DF1,DF2,DF3)

AllDf_l <- AllDf %>% gather(Var,Value, A:C)

ggplot(AllDf_l, aes(x = Month, y = Value, colour = df))+geom_line()+
  facet_grid(Var~.)
Sarah
  • 3,022
  • 1
  • 19
  • 40