首页 > 解决方案 > 通过循环将多条曲线/函数添加到一个ggplot

问题描述

我想将多条曲线添加到一个ggplot. 使用法线plotcurve(add=TRUE)我可以循环曲线功能并可以添加多个曲线/功能。

由于我想重写我的代码ggplot,我试图弄清楚如何用 ggplot 实现这一点。

我正在使用stat_functionand 一个for循环,但ggplot没有添加curve,只是保存最后一个。

单行的最小可重现示例:

library(ggplot2)
p1<-ggplot()
for (i in 1:10){
  p1<- p1 + stat_function(aes(x=1:200),fun = function(x) {x+i*3}, col=i)
  print(p1)
}

我认为代码应该做什么:

我循环多个stat_function并将其添加到我的情节中p1

我想做的事:

我希望将所有行添加到一个绘图(p1)中。代码原样只显示循环的最后一行,就好像它总是覆盖绘图一样,但据我所知,ggplot这应该只添加一行。还有一个解释为什么这不起作用会很好,也许我只是不明白ggplot这里

标签: rggplot2

解决方案


问题是您所指的所有stat_functions 都指的是同一个 i变量。因此,您添加的每个功能都将与其他功能完美重叠。

解决方案是在本地范围内重新分配变量,为每次迭代制作一个本地副本:

p1 = ggplot(data.frame(x = 1 : 200)) + aes(x)

for (i in 1:10){
    p1 = local({
        j = i
        p1 + stat_function(fun = function(x) x + j * 3, col = j)
    })
}

更令人困惑的是,您实际上不必给局部变量一个新名称。您可以轻松地编写i = i并继续使用i。原因是这个赋值会生成一个新的局部变量i来屏蔽非局部变量i。我希望我们能同意编写这样的代码是令人困惑的,也是一个坏主意。

我还冒昧地通过将数据x移出stat_function, 并直接移入ggplot对象来稍微简化您的代码。

但是,在这里不使用循环和重新分配是完全干净的。相反,您可以使用lapplyor map(来自 purrr 包):

p1 = ggplot(data.frame(x = 1 : 200)) +
    aes(x) +
    map(
        1 : 10,
        ~ stat_function(fun = function (x) x + .x * 3, color = .x)
    )

这更短,更易读(它关注“什么”而不是“如何”,即循环的机制),并且它使用单个赋值。


推荐阅读