带有最小值、最大值、平均值和标准差的箱线图

问题描述 投票:0回答:2

我想使用数据集的最小、最大和平均输出以及标准差创建箱线图。我发现示例绘制了数值分布,但就我而言,这是不可行的。

有没有办法在Python(Matplotlib)中做到这一点?

python matplotlib boxplot
2个回答
45
投票

上面@Roland给出的答案很重要:箱形图显示了根本不同的数量,如果您使用现有的数量制作类似的图,可能会让用户感到困惑。我可能会使用堆叠误差条图来表示此信息。例如:

import matplotlib.pyplot as plt
import numpy as np

# construct some data like what you have:
x = np.random.randn(100, 8)
mins = x.min(0)
maxes = x.max(0)
means = x.mean(0)
std = x.std(0)

# create stacked errorbars:
plt.errorbar(np.arange(8), means, std, fmt='ok', lw=3)
plt.errorbar(np.arange(8), means, [means - mins, maxes - means],
             fmt='.k', ecolor='gray', lw=1)
plt.xlim(-1, 8)


0
投票

考虑到可用的信息(平均值、标准差、最小值、最大值),

errorbar
可能是唯一可以绘制的图形,但如果你想根据聚合数据绘制箱线图,matplotlib有
bxp()
方法可以使用。请注意,它是一个轴级函数(不能称为
plt.bxp
)。它使用字典列表,其中每个字典包含有关特定箱线图的数据。

但是,箱线图至少需要中位数、第一和第三四分位数,如果不进一步假设数据集的分布,则无法从平均值、标准差等推断出这些数据。

假设数据集呈正态分布。然后我们可以使用均值和标准差来估计中位数、第一和第三四分位数。使用这些值,我们还可以近似晶须。假设异常值不可用,我们可以绘制一个基本的箱线图,如下所示。

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

# construct some data
x = np.random.default_rng(0).normal(size=(1000, 8))

means = x.mean(axis=0)
q1 = means + std * stats.norm.ppf(0.25)
q3 = means + std * stats.norm.ppf(0.75)
whislo = q1 - (q3 - q1)*1.5
whishi = q3 + (q3 - q1)*1.5

keys = ['med', 'q1', 'q3', 'whislo', 'whishi']
stats = [dict(zip(keys, vals)) for vals in zip(means, q1, q3, whislo, whishi)]
plt.subplot().bxp(stats, showfliers=False);


现在假设我们可以访问中位数、第一和第三四分位数(下面的

median
q1
q3
)。此外,假设我们可以访问
q1-(q3-q1)*1.5
下方和
q3+(q3-q1)*1.5
上方的值,这些值可用于定位晶须。另外,假设我们可以访问胡须之外的值 (
fliers
)。然后将所有这些信息传递给
bxp()
绘制一个与
plt.boxplot
绘制的图表完全相同的图表。

# construct some data
x = np.random.default_rng(0).normal(size=(1000, 8))
median = np.median(x, axis=0)
q1 = np.quantile(x, 0.25, axis=0)
q3 = np.quantile(x, 0.75, axis=0)

# compute whiskers' locations
whislo = [np.min(x[x[:, i] > v, i]) for i, v in enumerate(q1 - (q3 - q1)*1.5)]
whishi = [np.max(x[x[:, i] < v, i]) for i, v in enumerate(q3 + (q3 - q1)*1.5)]
# identify fliers
fliers = [x[(x[:, i] < lo) | (x[:, i] > hi), i] for i, (lo, hi) in enumerate(zip(whislo, whishi))]

keys = ['med', 'q1', 'q3', 'whislo', 'whishi', 'fliers']
stats = [dict(zip(keys, vals)) for vals in zip(median, q1, q3, whislo, whishi, fliers)]

plt.subplot().bxp(stats);

您可以验证上面的图与

绘制的图完全相同
plt.boxplot(x);
© www.soinside.com 2019 - 2024. All rights reserved.