我想使用数据集的最小、最大和平均输出以及标准差创建箱线图。我发现示例绘制了数值分布,但就我而言,这是不可行的。
有没有办法在Python(Matplotlib)中做到这一点?
上面@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)
考虑到可用的信息(平均值、标准差、最小值、最大值),
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);