Matplotlib箱线图仅显示最大和最小异常值

8

我正在使用plt.boxplot()命令制作标准的Matplotlib箱线图。

创建箱线图的代码行是:

bp = plt.boxplot(data, whis=[5, 95], showfliers=True)

因为我的数据分布很大,所以我得到了很多在须茎图范围之外的异常值。为了得到更清晰、出版质量更高的图表,我想只显示数据的最大值和最小值处的单个异常值,而不是所有的异常值。这是否可能?我在文档中没有看到任何内置选项可以实现这一点。
(我可以将须茎图的范围设置为最大/最小值,但这不是我想要的。我想保持须茎图在第5和第95百分位数处。)
下面是我正在处理的图。请注意异常值的密度。 Boxplots

那传单的密度不是重要信息吗? - tacaswell
是的,绝对是。我想这取决于你想要展示什么。但你说得很有道理。 - pjw
2个回答

4

plt.boxplot() 返回一个字典,其中键 fliers 包含上下界的离群值作为 line2d 对象。您可以在绘图之前像这样操纵它们:

仅适用于 matplotlib >= 1.4.0

bp = plt.boxplot(data, whis=[5, 95], showfliers=True)

# Get a list of Line2D objects, representing a single line from the
# minimum to the maximum flier points.
fliers = bp['fliers']

# Iterate over it!
for fly in fliers:
    fdata = fly.get_data()
    fly.set_data([fdata[0][0],fdata[0][-1]],[fdata[1][0],fdata[1][-1]])

在较旧的版本中

如果您使用的是较旧的matplotlib版本,则每个箱形图的离群值由两条线表示,而不是一条。因此,循环应该类似于以下内容:

import numpy as np
for i in range(len(fliers)):
    fdata = fliers[i].get_data()
    # Get the index of the maximum y in data if 
    # i is 0 or even, else get index of minimum y.
    if i%2 == 0:
        id = np.where(fdata[1] == fdata[1].max())[0][0]
    else:
        id = np.where(fdata[1] == fdata[1].min())[0][0]
    fliers[i].set_data([fdata[0][id], fdata[1][id]])

请注意,在matplotlib <1.4x中不存在showfliers参数,whisk参数不接受列表。

当然(对于简单的应用程序),您可以在不包含异常值的箱线图上绘制最大值和最小值点:

bp = plt.boxplot(data, whis=[5, 95], showfliers=False)
sc = plt.scatter([1, 1], [data.min(), data.max()])

其中[1, 1]是点的x坐标。


抱歉,昨天有点晚了。我已经修复了上面的问题。希望它足够明确和易于理解。同时,我已经删除了第二个建议。 - Geotob
现在,最小值和最大值交替出现,因此第1个框显示最大值,第2个框显示最小值,第3个框显示最大值,以此类推......请参见我上面添加的图。 - pjw
这对我在多个箱线图上都没有问题...你用的是哪个matplotlib版本? - Geotob
这明显是与更新到mpl 1.4x版本有关的问题,我很快会在上面进行更新。 - Geotob
你可能想把最后一行放在try:...except IndexError:...中,以防某些盒子没有传单。 - M. Toya
显示剩余2条评论

3
fliers = bp['fliers'] 
for i in range(len(fliers)): # iterate through the Line2D objects for the fliers for each boxplot
    box = fliers[i] # this accesses the x and y vectors for the fliers for each box 
    box.set_data([[box.get_xdata()[0],box.get_xdata()[0]],[np.min(box.get_ydata()),‌​np.max(box.get_ydata())]]) 
    # note that you can use any two values from the xdata vector

以下是仅显示最大值和最小值的结果图: enter image description here


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