我需要根据一组参数绘制一系列函数,例如,一系列依赖于均值和标准差的正态分布曲线。 我找到了here,一个几乎完成任务的代码snipet:
p9 <- ggplot(data.frame(x = c(0, 1)), aes(x = x)) +
stat_function(fun = dnorm, args = list(0.2, 0.1),
aes(colour = "Group 1")) +
stat_function(fun = dnorm, args = list(0.7, 0.05),
aes(colour = "Group 2")) +
scale_x_continuous(name = "Probability",
breaks = seq(0, 1, 0.2),
limits=c(0, 1)) +
scale_y_continuous(name = "Frequency") +
ggtitle("Normal function curves of probabilities") +
scale_colour_brewer(palette="Accent") +
labs(colour = "Groups")
p9
在这种情况下,代码会精确绘制两条曲线,如下所示:
我的问题是系列中的曲线数量可以是任意,因此我尝试按如下方式调整代码:
aa <- list(list(0.2, 0.1), list(0.7, 0.05), list(0.45, 0.2))
p9 <- ggplot(data.frame(x = c(0, 1)), aes(x = x))
for (i in 1:3) {
p9 <- p9 + stat_function(fun = dnorm, args = aa[[i]],
aes(colour = paste("Group", i))
}
p9 <- p9 +
scale_x_continuous(name = "Probability",
breaks = seq(0, 1, 0.2),
limits=c(0, 1)) +
scale_y_continuous(name = "Frequency") +
ggtitle("Normal function curves of probabilities") +
scale_colour_brewer(palette="Accent") +
labs(colour = "Groups")
p9
结果几乎是成功的,因为它描绘了三条曲线,除了它不能通过颜色或传奇区分它们,如下所示:
我猜问题来自函数aes()管理其参数的方式。您对如何重写我的代码有任何想法吗?
答案 0 :(得分:4)
ggplot
快速修改:我刚学会了an idiom I just learned from @BrodieG这里非常适用:你可以直接在ggplot
来电添加一个geoms或stats列表,这样你就可以避免卷积Reduce
或lapply
的{{1}},可让您根据需要并行传递尽可能多的变量。结合@ JulioSergio的Map
方法,您可以获得一个可读的代码,可以轻松定制:
aes_
ggplot(data.frame(x = 0:1), aes(x)) +
Map(function(params, name){stat_function(mapping = aes_(color = name),
fun = dnorm, args = params)},
params = aa,
name = paste('Group', seq_along(aa)))
结构非常适合Reduce
Reduce
设置为初始init
调用。可以通过将调色板功能按此时对象中的层数索引来添加颜色:
ggplot
这种方法的缺点在于它没有成为一个很好的传奇,因为它的硬编码颜色。
解决这个问题的一种方法是在绘图之前简单地进行计算,这使得绘图本身非常简单:
Reduce(function(x, y){
x + stat_function(fun = dnorm, args = y,
colour = scales::brewer_pal('qual', 'Set1')(length(aa))[length(x$layers) + 1])},
aa,
init = ggplot(data.frame(x = c(0, 1)), aes(x = x)))
答案 1 :(得分:2)
以下答案使用 aes _()函数代替 aes()来执行美学映射,因为我了解到,它更适合编程。我以alistaire给出的答案作为基础。
library(ggplot2)
aa <- list(list(0.2, 0.1), list(0.7, 0.05), list(0.45, 0.2))
p9 <- Reduce(function(x, y){
x + stat_function(fun = dnorm, args = y,
aes_(colour = paste("Group", length(x$layers)+1)))},
aa,
init = ggplot(data.frame(x = c(0, 1)), aes(x = x)))
p9 <- p9 +
scale_x_continuous(name = "Probability",
breaks = seq(0, 1, 0.2),
limits=c(0, 1)) +
scale_y_continuous(name = "Frequency") +
ggtitle("Normal function curves of probabilities") +
scale_colour_brewer(palette="Accent") +
labs(colour = "Groups")
p9
下图显示了结果:
在这种情况下,优点是结果图像具有图例 用合适的标签。