在 ggplot2 中,箱线图线的末端代表啥?

Posted

技术标签:

【中文标题】在 ggplot2 中,箱线图线的末端代表啥?【英文标题】:In ggplot2, what do the end of the boxplot lines represent?在 ggplot2 中,箱线图线的末端代表什么? 【发布时间】:2011-06-24 05:38:44 【问题描述】:

我找不到关于箱线图线的端点代表什么的描述。

例如,这里是线结束位置上方和下方的点值。

(我意识到盒子的顶部和底部分别是第 25 和第 75 个百分位数,而中心线是第 50 个百分位数)。我假设,因为线条上方和下方的点不代表最大/最小值。

【问题讨论】:

【参考方案1】:

箱线图末尾的“点”代表异常值。确定一个点是否为异常值有许多不同的规则,但 R 和 ggplot 使用的方法是“1.5 规则”。如果一个数据点是:

小于 Q1 - 1.5*IQR 大于 Q3 + 1.5*IQR

然后该点被归类为“异常值”。晶须定义为:

上须线 = min(max(x), Q_3 + 1.5 * IQR)

下须 = max(min(x), Q_1 – 1.5 * IQR)

其中 IQR = Q_3 – Q_1,盒子长度。所以上须线位于最大 x 值和 Q_3 + 1.5 IQR 的较小处, 而下晶须位于最小 x 值和 Q_1 – 1.5 IQR 的较大处。

其他信息

请参阅wikipedia boxplot 页面了解替代异常值规则。 实际上有多种计算分位数的方法。查看 `?quantile 以了解 九种 不同方法的描述。

示例

考虑以下示例

> set.seed(1)
> x = rlnorm(20, 1/2)#skewed data
> par(mfrow=c(1,3))
> boxplot(x, range=1.7, main="range=1.7")
> boxplot(x, range=1.5, main="range=1.5")#default
> boxplot(x, range=0, main="range=0")#The same as range="Very big number"

这给出了以下情节:

当我们将范围从 1.7 减小到 1.5 时,我们会减少晶须的长度。然而,range=0 是一个特例——它等同于 "range=infinity"

【讨论】:

查看?boxplot?boxplot.stats 的帮助页面。 ggplot 使用标准 R 函数进行这些计算。 在 ggplot2 中,上须线计算为 max(x[x 类似。 @TemplateRex 是正确的。我添加了一个带有示例的答案,该示例显示了晶须值与使用 Q1 - 1.5*IQR 计算的值不同的地方【参考方案2】:

我认为 ggplot 使用标准默认值,与 boxplot 相同:“胡须延伸到最极端的数据点,距离盒子不超过盒子长度的 [1.5] 倍”

见:boxplot.stats

【讨论】:

我称之为 Tukey 箱线图是为了避免与人们创建的无数其他类型的(更糟糕的)箱线图混淆。 据我了解?boxplot.stats,标准是+/-1.58 * IQR/sqrt(n) 而不是[1.5] times the length of the box。我是不是误会了什么? @Henrik:你把胡须和凹口搞混了。 麦吉尔的论文可读性很强:lis.epfl.ch/~markus/References/McGill78.pdf 指向 McGill 论文的链接不再有效。我找不到新的(免费)链接。该论文可以从jstor.org/stable/2683468?seq=1#page_scan_tab_contents 下载,但价格为 14 美元(或者您需要有机构访问权限)。【参考方案3】:

P1IMSA Tutorial 8 - Understanding Box and Whisker Plots 视频提供了 (Tukey) 盒须图的可视化分步说明。

在 4m 23s 我解释了胡须末端的含义及其与 1.5*IQR 的关系。

虽然视频中显示的图表是使用 D3.js 而不是 R 呈现的,但它的解释与提到的箱线图的 R 实现相吻合。

【讨论】:

【参考方案4】:

正如@TemplateRex 在评论中强调的那样,ggplot 不会在上/下四分位数加/减 IQR 的 1.5 倍处绘制胡须。它实际上在 max(x[x Q1 + 1.5 * IQR]) 处绘制它们。例如,这是使用 geom_boxplot 绘制的图,其中我在值 Q1 - 1.5*IQR 处添加了一条虚线:

Q1 = 52

第三季度 = 65

Q1 - 1.5 * IQR = 52 - 13*1.5 = 32.5(虚线)

下须线 = min(x[x > Q1 + 1.5 * IQR]) = 35(其中 x 是用于创建箱线图的数据,离群值位于 x = 27)。

MWE 请注意,这不是我用来生成上图的确切代码,但它明白了这一点。

library("mosaic") # For favstats()

df <-  c(54, 41, 55, 66, 71, 50, 65, 54, 72, 46, 36, 64, 49, 64, 73, 
         52, 53, 66, 49, 64, 44, 56, 49, 54, 61, 55, 52, 64, 60, 54, 59, 
         67, 58, 51, 63, 55, 67, 68, 54, 53, 58, 26, 53, 56, 61, 51, 51, 
         50, 51, 68, 60, 67, 66, 51, 60, 52, 79, 62, 55, 74, 62, 59, 35, 
         67, 58, 74, 48, 53, 40, 62, 67, 57, 68, 56, 75, 55, 41, 50, 73, 
         57, 62, 61, 48, 60, 64, 53, 53, 66, 58, 51, 68, 69, 69, 58, 54, 
         57, 65, 78, 70, 52, 59, 52, 65, 70, 53, 57, 72, 47, 50, 70, 41, 
         64, 59, 58, 65, 57, 60, 70, 46, 40, 76, 60, 64, 51, 38, 67, 57, 
         64, 51)
df <- as.data.frame(df)


Q1 <- favstats(df)$Q1
Q3 <- favstats(df)$Q3

IQR <- Q3 - Q1

lowerlim <- Q1 - 1.5*IQR
upperlim <- Q3 + 1.5* IQR

boxplot_Tukey_lower <- min(df[df > lowerlim])
boxplot_Tukey_upper <- max(df[df < upperlim])



ggplot(df, aes(x = "", y = df)) +
  stat_boxplot(geom ='errorbar', width = 0.5) +
  geom_boxplot() + 
  geom_hline(yintercept = lowerlim, linetype = "dashed") +
  geom_hline(yintercept = upperlim, linetype = "dashed")

【讨论】:

感谢您的贡献。为您的情节提供确切的代码通常会有所帮助。 (不需要您拥有的主题调用和实验室标题,只需使用 ggplot() + geom_boxplot()。理想情况下,一个完全可重现的示例会很棒,例如在内置数据集上。也许尝试“reprex”包。 favstats 来自哪里?我想可能是马赛克包,所以我添加了调用,但是当我尝试重现它时这不起作用。 它是马赛克。不知道为什么它不适合你。 在新的 R 会话中(使用 reprex 包):Q1 &lt;- favstats(df)$Q1 #&gt; Warning in fav_stats(x, ..., na.rm = na.rm): Auto-converting data.frame to #&gt; numeric. #&gt; Error in fav_stats(x, ..., na.rm = na.rm): 'list' object cannot be coerced to type 'double' 换句话说你的代码不起作用;)

以上是关于在 ggplot2 中,箱线图线的末端代表啥?的主要内容,如果未能解决你的问题,请参考以下文章

Python Matplotlib 箱线图颜色

R 的问题:使用 ggplot2 更改多个箱线图的标题

箱线图(ggplot2)未按预期工作

Boxplot ggplot2:在分组箱线图中显示平均值和观察次数

使用ggplot2画基因表达样本的箱线图

如何使用ggplot2显示箱线图中的所有平均值? [复制]