【问题标题】:How to shade specific region under ggplot2 density curve?如何在ggplot2密度曲线下遮蔽特定区域?
【发布时间】:2015-12-19 18:48:58
【问题描述】:

Related post here

我的意图是对位于两点之间的密度曲线下方的区域进行阴影处理。在此示例中,我想对值 0.25 和 0.5 之间的区域进行着色。

我已经能够用以下方法绘制我的密度曲线:

    setwd("D:/Workspace")

    # -- create dataframe

    coursename <- c('Math','Math','Math','Math','Math')
    value <- c(.12, .4, .5, .8, .9)
    df <- data.frame(coursename, value)

    library(ggplot2)

    density_plot <- ggplot(aes(x=value, colour=coursename, fill=coursename), data=df) +
                      geom_density(alpha=.3) +
                      geom_vline(aes(xintercept=.5), colour="blue", data=df, linetype="dashed", size=1) +
                      scale_x_continuous(breaks=c(0, .25, .5, .75, 1), labels=c("0", ".25", ".5", ".75", "1")) +
                      coord_cartesian(xlim = c(0.01, 1.01)) +
                      theme(axis.title.y=element_blank(), axis.text.y=element_blank()) +
                      ggtitle("sample data")

    density_plot

我尝试使用以下代码对 0.25 和 0.5 之间的区域进行着色:

    x1 <- min(which(df$value >=.25))
    x2 <- max(which(df$value <=.5))

    with(density_plot, polygon(x=c(x[c(x1,x1:x2,x2)]), y=c(0, y[x1:x2], 0), col="gray"))

但它只会产生以下错误:

Error in xy.coords(x, y) : object 'y' not found

【问题讨论】:

  • 有两件事可以直接回到你的 q 中。 (1) 找不到y,因为您在对polygon 的调用中引用了y[x1:x2](并且没有y); (2) 您正在尝试混合 ggplot2/grid 和基本图形。

标签: r graphics ggplot2 polygon


【解决方案1】:

使用stage()scales::oob_censor(),您可以在单个图中定义密度函数下的区域。这消除了构建绘图两次或预先定义近似值的需要,但代价是获得警告。

library(ggplot2)
library(scales)

df <- data.frame(
  coursename = c('Math','Math','Math','Math','Math'), 
  value = c(.12, .4, .5, .8, .9)
)

ggplot(df, aes(value)) +
  geom_density() +
  geom_area(
    aes(x = stage(value, after_stat = oob_censor(x, c(0.25, 0.5)))),
    stat = "density"
  )
#> Warning: Removed 349 rows containing missing values (position_stack).

reprex package (v1.0.0) 于 2021 年 6 月 1 日创建

【讨论】:

    【解决方案2】:

    或者对自己使用 ggplot2!

    coursename <- c('Math','Math','Math','Math','Math')
    value <- c(.12, .4, .5, .8, .9)
    df <- data.frame(coursename, value)
    
    library(ggplot2)
    
    ggplot() +
      geom_density(data=df, 
                   aes(x=value, colour=coursename, fill=coursename),
                   alpha=.3) +
      geom_vline(data=df, 
                 aes(xintercept=.5), 
                 colour="blue", linetype="dashed", size=1) +
      scale_x_continuous(breaks=c(0, .25, .5, .75, 1), 
                         labels=c("0", ".25", ".5", ".75", "1")) +
      coord_cartesian(xlim = c(0.01, 1.01)) +
      theme(axis.title.y=element_blank(), 
            axis.text.y=element_blank()) +
      ggtitle("sample data") -> density_plot
    
    density_plot
    
    dpb <- ggplot_build(density_plot)
    
    x1 <- min(which(dpb$data[[1]]$x >=.25))
    x2 <- max(which(dpb$data[[1]]$x <=.5))
    
    density_plot +
      geom_area(data=data.frame(x=dpb$data[[1]]$x[x1:x2],
                           y=dpb$data[[1]]$y[x1:x2]),
                aes(x=x, y=y), fill="grey")
    

    (这与 jlhoward 的答案几乎相同,但从 ggplot 中获取计算值)。

    【讨论】:

      【解决方案3】:

      你可以做到,但 AFAIK 你必须“手动”计算密度:

      dens.fun <- function(z)with(density(df$value),approx(x,y,z)$y)
      density_plot+
        geom_area(data=data.frame(value=seq(0.25,0.5,len=100)),
                      aes(x=value, y=dens.fun(value), color=NULL),
                      fill="grey")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-06-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多