You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Matplotlib 1.4.0与2.2.0对同一数据生成的箱线图存在差异?

箱线图百分位数显示差异的原因及正确结果分析

你遇到的这个版本差异问题,核心是Matplotlib在不同版本中对whis参数的解析逻辑、以及百分位数的计算方式发生了关键变更,咱们一步步拆解清楚:

先明确你的数据和预期值

你的数据集是:

values = np.array([0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,49.33,0.00,0.00,25.33])

排序后为:[0,0,0,0,0,0,0,0,0,0,25.33,49.33]。按标准线性插值计算,95%百分位数应为:

第95%位置 = 12 * 0.95 = 11.4,对应第11个元素(25.33)和第12个元素(49.33)的插值:25.33 + (49.33-25.33)*0.4 = 36.13

版本差异的具体原因

1. Matplotlib 1.4.0(旧版本):参数解析逻辑错误

在Matplotlib 1.5.0之前,boxplot的whis参数不支持直接传入百分位数列表——这个功能是1.5.0版本才新增的!当时whis的默认行为是设置为四分位距(IQR)的倍数,所以你传入的[5.0,95.0]被当成了:

  • 下限 = Q1 - 5*IQR
  • 上限 = Q3 + 95*IQR

而你的数据中,Q1和Q3都是0,IQR=0,所以上下须会被直接拉伸到数据的最大值(49.33)和最小值(0),完全不符合你想要的百分位数边界预期。

2. Matplotlib 2.2.0(新版本):百分位数计算方法不同

Matplotlib 1.5+支持用whis=[5,95]直接指定百分位数,但它默认的百分位数计算方式是取最接近排名的原始数据值,不做线性插值:
你的数据共12个元素,95%位置是11.4,Matplotlib会取最接近的整数索引(第10位,对应值25.33),所以图里的上限显示为25左右,和你手动计算的线性插值结果不符。

哪个结果是正确的?

严格来说,两个版本都没有正确实现你想要的“基于线性插值的5/95百分位数”:

  • 旧版本完全误解了你的参数意图,结果完全偏离预期;
  • 新版本虽然识别了参数,但计算逻辑和标准线性插值不一致。

如果想要得到符合预期的36.13作为95%百分位数上限,可以手动计算百分位数后自定义箱线图的须和帽,示例代码如下:

import numpy as np
import matplotlib.pyplot as plt

values = np.array([0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,49.33,0.00,0.00,25.33])
# 用线性插值计算5%和95%分位数
p5 = np.percentile(values, 5, interpolation='linear')
p95 = np.percentile(values, 95, interpolation='linear')
# 计算四分位数(箱线图的箱体边界)
q1, q3 = np.percentile(values, [25, 75])

f, ax1 = plt.subplots()
# 先绘制基础箱线图
box = ax1.boxplot(values, showfliers=False)
# 手动调整下须和下帽的位置
box['whiskers'][0].set_ydata([p5, q1])
box['caps'][0].set_ydata([p5, p5])
# 手动调整上须和上帽的位置
box['whiskers'][1].set_ydata([q3, p95])
box['caps'][1].set_ydata([p95, p95])

plt.show()

内容的提问来源于stack exchange,提问作者PyLabour

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:08:44