我想使用数据集的最小值、最大值、平均输出和标准差来创建一个箱线图。我找到的示例绘制了一个数值分布,但在我的情况下,这是不可行的。
有没有办法在Python(Matplotlib)中实现这个?
有没有办法在Python(Matplotlib)中实现这个?
errorbar
图来表示这些信息。import matplotlib.pyplot as plt
import numpy as np
# construct some data like what you have:
np.random.seed(2023)
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)
1. 箱线图展示了分位数。你无法从现有数据中得出这些分位数。我建议不要创建一个带有均值、最小值、最大值和标准差的箱线图的派生图,因为这只会让熟悉箱线图的人感到困惑。我建议将均值、最小值、最大值表示为点(可能使用不同的符号或大小),将标准差表示为误差线。- Rolanderrorbar()
的第一个参数为什么要使用 numpy(np.arange(8)
)?我认为 matplotlib 内部使用列表(列表的列表)。如果我错了,请纠正我。 - MasterControlProgramtype(plt.plot(range(10), range(10))[0].get_xdata())
返回numpy.ndarray
。 - jakevdperrorbar
可能是唯一可以绘制的图形,但如果你想从聚合数据中绘制一个箱线图,matplotlib有一个可以使用的bxp()
方法。请注意,这是一个Axes级别的函数(不能像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);