我需要绘制一组根据一组参数变化的函数,例如,一组依赖于均值和标准差的正态分布曲线。我在这里找到了一个几乎可以完成任务的代码片段:
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
Run Code Online (Sandbox Code Playgroud)
在这种情况下,代码正好绘制了两条曲线,如下所示:
我的问题是系列中的曲线数量可以是任意的,因此我尝试按如下方式调整代码:
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
Run Code Online (Sandbox Code Playgroud)
结果几乎是成功的,因为它描绘了三个曲线,只是它没有通过颜色和图例来区分它们,如下所示:
我猜问题出在函数 aes() 管理其参数的方式上。您对如何重写我的代码有任何想法吗?
ggplot快速编辑:我刚刚从@BrodieG那里学到了一个非常适用的习语:您可以将 geoms 或 stats 的列表直接添加到ggplot调用中,这样您就可以避免Reduceforlapply或 even的卷积Map,这可以让您通过尽可能多的并行变量。结合@JulioSergio 的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)))
Run Code Online (Sandbox Code Playgroud)

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)))
Run Code Online (Sandbox Code Playgroud)

这种方法的缺点是它不会成为一个很好的图例,因为它是硬编码颜色。
解决这个问题的一种方法是在绘图之前简单地进行计算,这使得绘图本身非常简单:
library(tidyverse)
aa <- list(list(0.2, 0.1), list(0.7, 0.05), list(0.45, 0.2))
aa %>% set_names(paste('Group', 1:3)) %>%
map_df(~dnorm(seq(0, 1, length = 100), .x[[1]], .x[[2]])) %>%
mutate(x = seq(0, 1, length = 100)) %>%
gather(Group, y, -x) %>%
ggplot(aes(x, y, color = Group)) +
geom_line()
Run Code Online (Sandbox Code Playgroud)

| 归档时间: |
|
| 查看次数: |
924 次 |
| 最近记录: |