ggplot2:在for循环中使用stat_function()获取颜色图例

时间:2015-06-04 22:33:57

标签: r ggplot2

我正在尝试使用stat_function()为绘图添加一些分布。我可以使用以下代码成功完成此操作:

library("ggplot2")
library("dplyr")

gg_color_hue <- function(n) {
  hues = seq(15, 375, length=n+1)
  hcl(h=hues, l=65, c=100)[1:n]
}

plotMixMdlComps <- function(x, mu, sigma, lam) {
  lam * dnorm(x, mu, sigma )
}

clusterDf <- data.frame(cluster = c(6,5,4,8,0,7,3),
                        mu = c(0.73908779, 0.43233777, 0.28041006, 0.35627709,
                               0.09330585, 0.18250758, 0.56998734),
                        sigma = c(0.06472281, 0.03218096, 0.02779751,
                                  0.02208605, 0.02716692, 0.01890661,
                                  0.02995616),
                        lambda = c(0.042749908, 0.254485536, 0.205602343,
                                   0.404705236, 0.061058220, 0.024166972,
                                   0.007231783))

cols <- nrow(clusterDf) %>%
  gg_color_hue()

inDf <- data.frame(x = c(0,1))

p <- ggplot(inDf, aes(x)) +
  xlim(0,1) +
  ylim(0,10)

for (i in 1:nrow(clusterDf)) {
  p <- p + stat_function(geom = "line", fun = plotMixMdlComps,
                         arg = list(clusterDf[i, "mu"],
                                    clusterDf[i, "sigma"],
                                    clusterDf[i, "lambda"]),
                         lwd = 1.5, colour = cols[i])
}

p

这会生成如下图:

enter image description here

但我希望有一个传奇出现。在线阅读后,似乎我可以将颜色参数包装在aes()中,如下所示:

p <- ggplot(inDf, aes(x)) +
  xlim(0,1) +
  ylim(0,10)

for (i in 1:nrow(clusterDf)) {
  p <- p + stat_function(geom = "line", fun = plotMixMdlComps,
                         arg = list(clusterDf[i, "mu"],
                                    clusterDf[i, "sigma"],
                                    clusterDf[i, "lambda"]),
                         lwd = 1.5, aes(colour = cols[i]))
}
p

但最终会产生这样的情节,

enter image description here

我认为这与NSE(我仍然无法理解它)有关,只有&#34;解决&#34;它被称为cols [i]。所以每个stat_function最终解析为具有相同的cols [i],这应该是cols [7]。有没有办法让ggplot来解决&#34;这立即而不是等待p被调用?

谢谢,

2 个答案:

答案 0 :(得分:2)

stat_function上的帮助有一个示例,用于在同一个图中显示两个函数。它还会两次添加stat_function并指定显式颜色,并且不会生成自动图例:

f <- ggplot(data.frame(x = c(0, 10)), aes(x))
f + stat_function(fun = sin, colour = "red") +
  stat_function(fun = cos, colour = "blue")

因此,我怀疑使用图例绘制多个函数不在stat_function的范围内。

根据krlmlr的注释,您可以按如下方式创建数据集:

x <- seq(0,1,0.01)
names(clusterDf)[4]<-"lam"
fun_data <- lapply(1:nrow(clusterDf),function(i) {
               args <- clusterDf[i,-1]
               data.frame(cluster=clusterDf$cluster[i],
                          x=x,
                          y=do.call(plotMixMdlComps,c(list(x=x),args))
               )
}) %>% bind_rows

现在可以使用ggplot直接绘制:

ggplot(fun_data,aes(x=x,y=y,colour=as.factor(cluster))) + geom_line(lwd=1.5)

这让ggplot为你挑选颜色。如果您想使用您指定的颜色(在您的情况下,与ggplot选择的颜色相同),您可以将scale_colour_manual(values=cols)添加到绘图中。

修改

或者,您也可以使用mdply包中的plyr创建地图数据:

library(plyr)
x <- seq(0,1,0.01)
names(clusterDf)[4]<-"lam"
fun_data <- mdply(clusterDf,function(cluster,mu,sigma,lam) {
    data.frame(cluster=cluster,
               x=x,
               y=plotMixMdlComps(x,mu,sigma,lam)
    )
}) %>% bind_rows

答案 1 :(得分:0)

距离原始帖子已经有很长时间了,ggplot2中的内容已经发生了很大变化。现在,也可以通过在stat_function中使用Tidy求值的准引用或通过使用aes()aes_()中以编程方式应用美学映射。 See release note of ggplot2 3.0.0