【问题标题】:improving plotting of probability density functions in ggplot2改进ggplot2中概率密度函数的绘图
【发布时间】:2020-07-31 14:44:30
【问题描述】:

我正在使用 ggplot 绘制多个已知的密度函数,例如 gamma 密度函数:

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 年 7 月 31 日创建

然而,这段代码远非高效,而且违背了 ggplot 理念(也许是因为我们没有绘制任何“真实”数据集?)。有没有办法更有效地编写这个并且可以扩展到不同数量的参数对?我想只写一行stat_function 并在可能的情况下简化scale_color_identity。在颜色标签中保留数学表达式是强制性的

【问题讨论】:

    标签: r ggplot2 probability-density


    【解决方案1】:

    也许使用一些 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 年 7 月 31 日创建

    【讨论】:

    • 你对lapply的使用非常少见,没见过,喜欢
    【解决方案2】:

    我有点困惑,为什么这么多人尝试使用 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()
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-07
      • 2019-07-19
      • 1970-01-01
      • 2012-11-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多