【问题标题】:Generate multiple x-y plots from the same data frame in the same plot using ggplot2 in R using a loop and display corresponding legend使用循环在 R 中使用 ggplot2 从同一图中的同一数据框生成多个 x-y 图并显示相应的图例
【发布时间】:2014-01-20 14:40:39
【问题描述】:

我有一个使用以下代码生成的数据框,

x <- c(1:10)
y <- x^3
z <- y-20
s <- z/3
t <- s*6
q <- s*y
x1 <- cbind(x,y,z,s,t,q)
x1 <- data.frame(x1)

数据框x1因此具有以下数据,

    x    y   z          s    t             q
1   1    1 -19  -6.333333  -38     -6.333333
2   2    8 -12  -4.000000  -24    -32.000000
3   3   27   7   2.333333   14     63.000000
4   4   64  44  14.666667   88    938.666667
5   5  125 105  35.000000  210   4375.000000
6   6  216 196  65.333333  392  14112.000000
7   7  343 323 107.666667  646  36929.666667
8   8  512 492 164.000000  984  83968.000000
9   9  729 709 236.333333 1418 172287.000000
10 10 1000 980 326.666667 1960 326666.666667

现在我想在同一个图中绘制列 x vs y、z vs s 和 t vs q,所以为此我使用以下代码,

p <- ggplot() + 
  geom_line(data = x1, aes(x = x1[,1], y = x1[,2], color = "red")) +
  geom_line(data = x1, aes(x = x1[,3], y = x1[,4], color = "blue"))  +
  geom_line(data = x1, aes(x = x1[,5], y = x1[,6], color = "green"))  +
  xlab('x') +
  ylab('y')

虽然上面的代码对于只有 6 列的数据框可以正常工作,但我想对有很多列的数据框执行相同的操作。例如,如果数据框中有 20 列,则应该生成一个包含 col 1 vs 2、col 3 vs 4、col 5 vs 6 等的图,直到 col 19 vs 20。为此,我使用下面这段代码,

p <- ggplot() +   geom_line(data = x1, aes(x = x1[,1], y = x1[,2], color = "red")) + xlab('x') + ylab('y')
ctr <- 1
for (iz in seq(3, ncol(x1), by = 2))
{
p$ctr <- p + geom_line(data = x1, aes(x = x1[,iz], y = x1[,iz+1], color = "green"))
ctr <- ctr+1
}

因此,这些图应该逐渐分层,最后一个对象应该包含整个图。使用上面的代码,每次循环运行时,绘图都会被覆盖,有人可以指出如何捕获完整数据。我也想为每个情节显示一个图例。

谢谢

【问题讨论】:

    标签: r loops plot ggplot2 legend


    【解决方案1】:

    如果您将数据放入正确的格式,则不需要循环。您可以在原始数据框的基础上创建一个长数据框。

    x1_long <- data.frame(x = unlist(x1[c(TRUE, FALSE)]),
                          y = unlist(x1[c(FALSE, TRUE)]),
                          ind = gl(ncol(x1) / 2, nrow(x1)))
    

    现在,一个geom_line 命令就足够了:

    library(ggplot2)
    ggplot(x1_long) + 
      geom_line(aes(x = x, y = y, colour = ind))
    

    (注意。红线也画了,但它的值很小。)

    【讨论】:

    • 感谢您的建议我试过了,但在我得到的图中只显示了第一个 x vs y 数据,你知道为什么会这样吗?
    • 我的数据框的结构在上面的代码中是 x1,我不知道是什么原因图表没有更新并显示整个图,如您在上面演示的那样。我可以使用scale_y_log10() 来显示完整数据。
    • 没有非数字值,我现在在我的问题中包含了数据框。
    • 是的,我使用了你的完整代码,是否应该关闭并打开设备以刷新数据?
    • @Amm 哦,对不起,我的代码中有一个小错误。查看更新版本。
    【解决方案2】:

    这个怎么样?

    ggplot() + 
      lapply(seq(1,ncol(x1),2),         # every second col index
             function(x){               # return the geom_line calls in a list
        geom_line(aes_string(x=x1[x],   # remember to use aes_string for x
                             y=x1[x+1]),                           # and y
                  color=factor(x),                                 # then color
                  size=2)                                          # and size
        }) +
      xlab('x') +  ylab('y')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-25
      相关资源
      最近更新 更多