改进 ggplot2 中概率密度函数的绘制
improving plotting of probability density functions in ggplot2
我正在使用 ggplot 绘制多个已知的密度函数,例如伽马密度函数:
library(tidyverse)
apar<-c(1,2,7.5,9)
bpar<-c(2,2,1.3,0.5)
gmaxlim<-c(0, 25)
pgma1<-ggplot(data = data.frame(x = gmaxlim), aes(gmaxlim)) +
stat_function(fun = dgamma, n = 101, args = list(shape = apar[1], scale = bpar[1]),aes(color="black")) +
stat_function(fun = dgamma, n = 101, args = list(shape = apar[2], scale = bpar[2]),aes(color="red")) +
stat_function(fun = dgamma, n = 101, args = list(shape = apar[3], scale = bpar[3]),aes(color="blue")) +
stat_function(fun = dgamma, n = 101, args = list(shape = apar[4], scale = bpar[4]),aes(color="green")) +
ylab(expression(paste("f(x|",alpha,",",beta,")"))) +xlab("x") + scale_x_continuous(breaks=seq(gmaxlim[1],gmaxlim[2], by =5)) +
scale_color_identity(name = "",
breaks = c("black", "red", "blue","green"),
labels = c(substitute(paste(alpha,"= ", v," ,",beta,"= ",s),list(v=apar[1],s=bpar[1])),
substitute(paste(alpha,"= ", v," ,",beta,"= ",s),list(v=apar[2],s=bpar[2])),
substitute(paste(alpha,"= ", v," ,",beta,"= ",s),list(v=apar[3],s=bpar[3])),
substitute(paste(alpha,"= ", v," ,",beta,"= ",s),list(v=apar[4],s=bpar[4]))),
guide = "legend")+
theme_bw()
pgma1
由 reprex package (v0.3.0)
于 2020-07-31 创建
然而,这段代码远非高效,而且它违背了 ggplot 的理念(也许是因为我们没有绘制任何“真实”数据集?)。有没有一种方法可以更有效地编写它并且可以扩展到不同数量的参数对?我想只有一行 stat_function
并在可能的情况下简化 scale_color_identity
。必须在颜色标签中保留数学表达式
也许使用一些 lapply?
library(tidyverse)
apar <- c(1,2,7.5,9)
bpar <- c(2,2,1.3,0.5)
gmaxlim <- c(0, 25)
mycols <- c("black", "red", "blue", "green")
ggplot(data = data.frame(x = gmaxlim), aes(gmaxlim)) +
lapply(seq_along(apar), function(i){
stat_function(fun = dgamma, n = 101,
args = list(shape = apar[i], scale = bpar[i]), aes( color=mycols[i]))
}) +
scale_color_identity(name="", breaks = mycols,
labels = lapply(seq_along(apar), function(i)
substitute(paste(alpha,"= ", v," ,",beta,"= ",s),
list(v=apar[i], s=bpar[i]))), guide = "legend") +
theme_bw()
由 reprex package (v0.3.0)
于 2020-07-31 创建
我有点不明白为什么这么多人试图用 ggplot
中的 stat
函数做这么多,而不是传递他们真正想要绘制的数据。使用 stat_function
可以直接绘制奇数线,但是试图强制它做一些复杂的事情,比如通过引用外部向量来绘制分布族,这似乎很难做到。
推理更容易,代码更少,只需计算出您想要绘制的内容并绘制它:
apar <- c(1, 2, 7.5, 9)
bpar <- c(2, 2, 1.3, 0.5)
x <- seq(0, 25, 0.25)
y <- as.vector(sapply(1:4, function(i) dgamma(x, apar[i], scale = bpar[i])))
df <- data.frame(x = rep(x, 4), y, group = rep(letters[1:4], each = length(x)))
labs <- sapply(1:4, function(i) {
substitute(paste(alpha,"= ", v," ,",beta,"= ",s),
list(v = apar[i], s = bpar[i]))})
ggplot(data = df, aes(x, y)) + geom_line(aes(color = group)) +
ylab(expression(paste("f(x|", alpha, ",", beta,")"))) +
scale_color_manual(values = c(1, 2, 4, 3), labels = labs) +
theme_bw()
我正在使用 ggplot 绘制多个已知的密度函数,例如伽马密度函数:
library(tidyverse)
apar<-c(1,2,7.5,9)
bpar<-c(2,2,1.3,0.5)
gmaxlim<-c(0, 25)
pgma1<-ggplot(data = data.frame(x = gmaxlim), aes(gmaxlim)) +
stat_function(fun = dgamma, n = 101, args = list(shape = apar[1], scale = bpar[1]),aes(color="black")) +
stat_function(fun = dgamma, n = 101, args = list(shape = apar[2], scale = bpar[2]),aes(color="red")) +
stat_function(fun = dgamma, n = 101, args = list(shape = apar[3], scale = bpar[3]),aes(color="blue")) +
stat_function(fun = dgamma, n = 101, args = list(shape = apar[4], scale = bpar[4]),aes(color="green")) +
ylab(expression(paste("f(x|",alpha,",",beta,")"))) +xlab("x") + scale_x_continuous(breaks=seq(gmaxlim[1],gmaxlim[2], by =5)) +
scale_color_identity(name = "",
breaks = c("black", "red", "blue","green"),
labels = c(substitute(paste(alpha,"= ", v," ,",beta,"= ",s),list(v=apar[1],s=bpar[1])),
substitute(paste(alpha,"= ", v," ,",beta,"= ",s),list(v=apar[2],s=bpar[2])),
substitute(paste(alpha,"= ", v," ,",beta,"= ",s),list(v=apar[3],s=bpar[3])),
substitute(paste(alpha,"= ", v," ,",beta,"= ",s),list(v=apar[4],s=bpar[4]))),
guide = "legend")+
theme_bw()
pgma1
由 reprex package (v0.3.0)
于 2020-07-31 创建然而,这段代码远非高效,而且它违背了 ggplot 的理念(也许是因为我们没有绘制任何“真实”数据集?)。有没有一种方法可以更有效地编写它并且可以扩展到不同数量的参数对?我想只有一行 stat_function
并在可能的情况下简化 scale_color_identity
。必须在颜色标签中保留数学表达式
也许使用一些 lapply?
library(tidyverse)
apar <- c(1,2,7.5,9)
bpar <- c(2,2,1.3,0.5)
gmaxlim <- c(0, 25)
mycols <- c("black", "red", "blue", "green")
ggplot(data = data.frame(x = gmaxlim), aes(gmaxlim)) +
lapply(seq_along(apar), function(i){
stat_function(fun = dgamma, n = 101,
args = list(shape = apar[i], scale = bpar[i]), aes( color=mycols[i]))
}) +
scale_color_identity(name="", breaks = mycols,
labels = lapply(seq_along(apar), function(i)
substitute(paste(alpha,"= ", v," ,",beta,"= ",s),
list(v=apar[i], s=bpar[i]))), guide = "legend") +
theme_bw()
由 reprex package (v0.3.0)
于 2020-07-31 创建我有点不明白为什么这么多人试图用 ggplot
中的 stat
函数做这么多,而不是传递他们真正想要绘制的数据。使用 stat_function
可以直接绘制奇数线,但是试图强制它做一些复杂的事情,比如通过引用外部向量来绘制分布族,这似乎很难做到。
推理更容易,代码更少,只需计算出您想要绘制的内容并绘制它:
apar <- c(1, 2, 7.5, 9)
bpar <- c(2, 2, 1.3, 0.5)
x <- seq(0, 25, 0.25)
y <- as.vector(sapply(1:4, function(i) dgamma(x, apar[i], scale = bpar[i])))
df <- data.frame(x = rep(x, 4), y, group = rep(letters[1:4], each = length(x)))
labs <- sapply(1:4, function(i) {
substitute(paste(alpha,"= ", v," ,",beta,"= ",s),
list(v = apar[i], s = bpar[i]))})
ggplot(data = df, aes(x, y)) + geom_line(aes(color = group)) +
ylab(expression(paste("f(x|", alpha, ",", beta,")"))) +
scale_color_manual(values = c(1, 2, 4, 3), labels = labs) +
theme_bw()