【问题标题】:R_Multiple plots on same figure using a for loopR_Multiple 使用 for 循环在同一图形上绘制
【发布时间】:2014-06-16 00:30:32
【问题描述】:

我有 2 个数据框,mydf1 和 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

我想根据 id 绘制变量 a、b 和 c(示例图如下所示)。 我也想要变量 b 和 c 的类似图表,我想循环执行,然后将其导出到本地文件夹。所以,我使用以下代码

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()
}

我的问题是 我想在一个图中获得所有三个不同的图表,(id vs a (mydf1 and mydf2) , id vs b(mydf1 and mydf2), id vs c(mydf1 and mydf2) .(如图第一行的 2 和第二行的第三个图例) 我尝试了以下

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()
}

但它没有用。有什么建议吗? ps:这是我的任务的简化版本。实际上我有数百列,这就是我使用循环操作的原因

样图id vs a (mydf1 and mydf2)绘制在同一张图上

【问题讨论】:

  • 为什么不多用几次points?
  • 抱歉问题不清楚。我现在已经编辑过了。我希望我的问题现在很清楚

标签: r for-loop plot


【解决方案1】:

目前尚不清楚您要做什么。您想要两张地块,一张用于mydf1,一张用于mydf2,还是全部在一张图上?如果是两个面板,你应该改成mfrow=c(2,1)而不是c(2,2),目前正在制作4个面板?

如果您希望它们都在一个图上,请删除 par(mfrow... 行。

然后在绘图中,您将从mydf1 绘制第一个系列,从mydf2 绘制另外两个系列。这真的是你想要的吗?

使用基本图形,您应该将 plot 行移到循环外,这样它就完成了一次,将循环更改为从 3 开始,然后将 points 语句保留在循环内。或者,您可以将if 语句放入循环中,看看是否是第一次。

您在情节语句中也有一个拼写错误,mydf(无编号)。

并将您的 dev.off() 移到循环之外,这样它只会关闭图一次。

这是一些生成单面板图的代码,您应该能够对其进行修改以实现所需的输出...

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()

编辑:在您澄清问题之后,我认为唯一的问题是 dev.off() 应该在循环之外。 (对于任何值得展示的情节,我建议使用 PNG 或 PDF 而不是 JPEG……)

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()

【讨论】:

  • 谢谢@beroe。对不起,不清楚的问题。我现在已经编辑过了。我希望我的问题现在很清楚
  • 在这种情况下,您可能只需将 dev.off 移到循环之外。我会为此图推荐 PDF 或至少 PNG。 JPG 将为这么多地块生成工件...
【解决方案2】:

我会做类似的事情

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(d3, aes(x=id, y=value)) + 
  geom_point(aes(colour = as.factor(g))) +
  facet_wrap(~variable)

最终导出

ggsave(file = paste0(tempdir(), 'myplot.png'),
last_plot()
)

【讨论】:

  • 感谢@Paulo Cardoso。最后一个是我想要的,它看起来也不错。但是我不能在没有任何包的情况下使用 r 的基本功能吗?即使是一个简单的情节对我来说也可以。
  • 我怕不是。这看起来正是因为 ggplot 呈现此输出。为什么这会是个问题?
  • 没问题@Paulo Cardoso。我只是想知道是否有办法使用基本功能来做到这一点。无论如何谢谢。
猜你喜欢
  • 2020-09-06
  • 2016-09-29
  • 1970-01-01
  • 2021-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-20
相关资源
最近更新 更多