简体   繁体   English

改进 ggplot2 中概率密度函数的绘图

[英]improving plotting of probability density functions in ggplot2

I am using ggplot to draw multiple known density functions, for example the gamma density function:我正在使用 ggplot 绘制多个已知的密度函数,例如伽马密度 function:

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

Created on 2020-07-31 by the reprex package (v0.3.0)代表 package (v0.3.0) 于 2020 年 7 月 31 日创建

However this code is far from being efficient and it goes against ggplot philosophy (perhaps because we are not plotting any “real” data set?).然而,这段代码远非高效,而且违背了 ggplot 的理念(也许是因为我们没有绘制任何“真实”数据集?)。 Is there a way to write this more efficient and to be scalable to different number of pairs of parameters?有没有办法更有效地编写这个并且可以扩展到不同数量的参数对? I would like to have just one line of stat_function and simplify the scale_color_identity if posible.我只想有一行stat_function并在可能的情况下简化scale_color_identity Retaining mathematical expressions in the color labels is mandatory在颜色标签中保留数学表达式是强制性的

Perhaps use some lapply?也许使用一些 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()

Created on 2020-07-31 by the reprex package (v0.3.0)代表 package (v0.3.0) 于 2020 年 7 月 31 日创建

I'm a bit mystified as to why so many people try to do so much with the stat functions in ggplot instead of passing the data they actually want to plot.我有点困惑为什么这么多人试图用ggplot中的stat函数做这么多,而不是将他们真正想要的数据传递给 plot。 Using stat_function is good for drawing the odd line directly, but trying to coerce it into doing complicated stuff like drawing families of distributions by referencing external vectors just seems like doing it the hard way.使用stat_function可以很好地直接绘制奇数线,但试图强迫它做复杂的事情,比如通过引用外部向量来绘制分布族,这似乎很难做到。

It's easier to reason about, and takes less code, to just work out what you want to plot and to plot it:更容易推理并且需要更少的代码,只需计算出您想要 plot 和 plot 的内容:

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()

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM