使用预先计算的(汇总)统计数据绘制箱线图。

24

我需要做一个箱线图(在Python和matplotlib中),但我没有原始的“原始”数据。我有的是最大值、最小值、平均数、中位数和IQR(正态分布)的预先计算值,但我仍然想做一个箱线图。当然,绘制异常值是不可能的,但除此之外,我想所有的信息都在那里。

我已经搜索了所有相关的答案但都没有成功。我找到的最接近的答案是同样的问题,但是针对R语言(我不熟悉)。请参见是否可以轻松地从以前计算的统计数据中绘制盒形图(在R中?)


1
此功能存在于主分支上,并将包含在1.4版本中(该版本应很快发布)。https://github.com/matplotlib/matplotlib/pull/2643 - tacaswell
在这里你不需要任何特殊的函数 - 只需使用常规的matplotlib boxplot函数,因为如果你的整个数据集仅包含例如最小值、q1、中位数、q3和最大值,那么当它计算数据集的摘要统计信息时,它们将是这些精确的点!试一试,看看效果。 - user2739472
3个回答

21
感谢@tacaswell的评论,我找到了所需的文档,并使用Matplotlib 1.4.3编写了一个示例。但是,这个示例不会自动缩放图形到正确的大小。
import matplotlib.pyplot as plt

item = {}

item["label"] = 'box' # not required
item["mean"] = 5 # not required
item["med"] = 5.5
item["q1"] = 3.5
item["q3"] = 7.5
#item["cilo"] = 5.3 # not required
#item["cihi"] = 5.7 # not required
item["whislo"] = 2.0 # required
item["whishi"] = 8.0 # required
item["fliers"] = [] # required if showfliers=True

stats = [item]

fig, axes = plt.subplots(1, 1)
axes.bxp(stats)
axes.set_title('Default')
y_axis = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
y_values = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
plt.yticks(y_axis, y_values)

相关文档链接:


1
对于像我一样遇到问题的人:现在 matplotlib 网站上也有一些更详细的文档可供参考:https://matplotlib.org/gallery/statistics/bxp.html - malexmave

9
在旧版本中,您必须手动更改箱线图元素:
Mean=[3.4] #mean
IQR=[3.0,3.9] #inter quantile range
CL=[2.0,5.0] #confidence limit
A=np.random.random(50)
D=plt.boxplot(A) # a simple case with just one variable to boxplot
D['medians'][0].set_ydata(Mean)
D['boxes'][0]._xy[[0,1,4], 1]=IQR[0]
D['boxes'][0]._xy[[2,3],1]=IQR[1]
D['whiskers'][0].set_ydata(np.array([IQR[0], CL[0]]))
D['whiskers'][1].set_ydata(np.array([IQR[1], CL[1]]))
D['caps'][0].set_ydata(np.array([CL[0], CL[0]]))
D['caps'][1].set_ydata(np.array([CL[1], CL[1]]))
_=plt.ylim(np.array(CL)+[-0.1*np.ptp(CL), 0.1*np.ptp(CL)]) #reset the limit

enter image description here


3
对于那些因语法而感到困惑和绝望的人:现在有更简单的方法来完成这个任务,可以查看matplotlib文档:https://matplotlib.org/gallery/statistics/bxp.html - malexmave

9

参考@MKroehnert的回答以及箱线图绘制函数,以下内容可能有帮助:

import matplotlib.pyplot as plt

stats = [{
    "label": 'A',  # not required
    "mean":  5,  # not required
    "med": 5.5,
    "q1": 3.5,
    "q3": 7.5,
    # "cilo": 5.3 # not required
    # "cihi": 5.7 # not required
    "whislo": 2.0,  # required
    "whishi": 8.0,  # required
    "fliers": []  # required if showfliers=True
    }]

fs = 10  # fontsize

fig, axes = plt.subplots(nrows=1, ncols=1, figsize=(6, 6), sharey=True)
axes.bxp(stats)
axes.set_title('Boxplot for precalculated statistics', fontsize=fs)
plt.show()

1
只是想补充一下这个精彩的答案,如果你想在使用for循环将多个stats附加到一个list中后绘制多个箱线图,例如(循环之前:final_data = list(),循环内但结束时:final_data.append(stats)),然后将它们全部绘制在一个图上,请删除此答案中stats字典周围的[]。可能是一个简单的解决方案,但我花了几分钟才弄清楚。 - JamesT

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接