【发布时间】:2015-06-04 22:33:57
【问题描述】:
我正在尝试使用 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
这会生成一个像这样的图形:
但我想有一个传奇出现。在线阅读后,看来我可以像这样将颜色参数包装在 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
但这最终会产生这样的情节,
我认为这与 NSE 有关(我仍然无法理解它),它只在调用时“解析”cols[i]。因此,每个 stat_function 最终都会解析为具有相同的 cols[i],应该是 cols[7]。有没有办法让 ggplot 立即“解决”这个问题,而不是等待 p 被调用?
谢谢,
【问题讨论】:
-
ggplot2 旨在处理长格式数据。重塑您的数据,以便有一列“变量”(具有值“mu”、“sigma”和“lambda”)和一列具有相应值的“值”。 (在您的示例中,它应该有 21 行。)然后将“变量”列映射到“颜色”美学,图例将自动出现。
-
@krlmlr 不确定如何使用 stat_function() 进行这项工作? plotMixMdlComps() 函数从 clusterDf 的每一行获取值来生成分布。如果我融化它,我如何 stat_function 检索每个集群所需的值?
-
抱歉,您的问题只看了一半。但总体思路保持不变:使用您的
plot...函数和一些x值(不要太少,不要太多)创建一个长格式的数据框,其中包含您想要的线上每个点的一行地块。 (现在包含length(x) * 7行。)然后,对整个数据框仅使用aes(x=x, y=y, color=cluster),并且不要使用循环来构建绘图。