Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R_Multiple plots on same figure using a for loop

Tags:

for-loop

plot

r

I have 2 data frames, mydf1 and mydf2

> mydf1
  id a  b  c
1  1 2 10  2
2  2 3 11  4
3  3 5 12  6
4  4 7 13  8
5  5 8 14 10
> mydf2
  id  a  b  c
1  1  4 20  4
2  2  6 22  8
3  3 10 24 12
4  4 14 26 16
5  5 16 28 20

I would like to plot variables a,b & c against id (sample graphs is given below). I want similar graphs for variables b and c too and I want to do it in a loop and then export it to a local folder. So, I am using the following code

for (i in 2:4) {
    jpeg(paste("C:/Data/myplot",i,".jpg"))
         ymin<-min(mydf1[,i],mydf2[,i])
         ymax<-max(mydf1[,i],mydf2[,i])
         plot(mydf1[,1],mydf1[,i],ylim=c(ymin,ymax),xlab="id",ylab=colnames(mydf)[i])
         points(mydf2[,1],mydf2[,i],pch=2)
         legend("topright",c("mydf1","mydf2"),pch=c(1,2))     
         dev.off()
}

My problem is that I would like to get all three different graphs, (id vs a (mydf1 and mydf2) , id vs b(mydf1 and mydf2), id vs c(mydf1 and mydf2) in one figure.(something like 2 along the first row of the figure and the third one in the second row with legend) I tried the following

jpeg("C:/Data/myplot.jpg")
    par(mfrow=c(2,2))
for (i in 2:4) { 
    ymin<-min(mydf1[,i],mydf2[,i])
    ymax<-max(mydf1[,i],mydf2[,i])
    plot(mydf1[,1],mydf1[,i],ylim=c(ymin,ymax),xlab="id",ylab=colnames(mydf)[i])
    points(mydf2[,1],mydf2[,i],pch=2)
    legend("topright",c("mydf1","mydf2"),pch=c(1,2))     
    dev.off()
}

But it didn't work. Any suggestion to do this? p.s: This is the simplified version of my task. Actually I have hundreds of columns, that's why I am using a loop operation

enter image description here Sample plot id vs a (mydf1 and mydf2) plotted on the same graph

like image 219
rm167 Avatar asked Mar 12 '26 09:03

rm167


2 Answers

It is unclear what you are trying to do. Do you want 2 plots, one for mydf1 and one for mydf2 or all on one figure? If two panels, you should change to mfrow=c(2,1) instead of c(2,2) which is currently making 4 panels?

If you want them all on a single plot, then remove the par(mfrow... line.

Then within the plots, you are plotting the first series from mydf1 and the other two series from mydf2. Is that actually what you want?

Using base graphics, you should move your plot line outside the loop so it is done once, change the loop to start at 3, and then keep the points statements inside the loop. Alternatively, you could put an if statement inside the loop to see if it is the first time.

You also have a typo in the plot statement with mydf (no number).

And move your dev.off() outside the loop so it only closes the figure once.

Here is some code that generates a single-panel plot, and you should be able to modify it to work for your desired output...

jpeg("myplot.jpg")
    for (i in 2:4) { 
        ymin<-min(mydf1[,i],mydf2[,i])
        ymax<-max(mydf1[,i],mydf2[,i])
        if (i==2){
            plot(mydf1[,1],mydf1[,i],ylim=c(ymin,ymax),xlab="id",ylab=colnames(mydf1)[i])
            legend("topright",c("mydf1","mydf2"),pch=c(1,2))     
            }
        else{
            points(mydf2[,1],mydf2[,i],pch=2)
        }  
    }
dev.off()

EDIT: After your clarified question, I think the only problem is that dev.off() should be outside the loop. (I recommend PNG or PDF instead of JPEG for any plot worth presenting....)

png("myplot.png")
par(mfrow=c(2,2))
    for (i in 2:4) { 
        ymin<-min(mydf1[,i],mydf2[,i])
        ymax<-max(mydf1[,i],mydf2[,i])
            plot(mydf1[,1],mydf1[,i],ylim=c(ymin,ymax),xlab="id",ylab=colnames(mydf1)[i])
            legend("topright",c("mydf1","mydf2"),pch=c(1,2))     
            points(mydf2[,1],mydf2[,i],pch=2)
    }
dev.off()

enter image description here

like image 168
beroe Avatar answered Mar 13 '26 21:03

beroe


I'd do something like

mydf1$g <- 1
mydf2$g <- 2
d3 <- rbind(mydf1, mydf2)
library(reshape2)
d3 <- melt(d3, id.vars = c('id', 'g'))
library(ggplot2)
ggplot(d3, aes(x=id, y=value)) + 
  geom_point(aes(colour = as.factor(g), shape = variable))

ggplot example

or using facets

ggplot(d3, aes(x=id, y=value)) + 
  geom_point(aes(colour = as.factor(g))) +
  facet_wrap(~variable)

ggplot with faceting

to finally export it

ggsave(file = paste0(tempdir(), 'myplot.png'),
last_plot()
)
like image 39
Paulo E. Cardoso Avatar answered Mar 13 '26 23:03

Paulo E. Cardoso