【问题标题】:How to jitter the outliers of a boxplot?如何抖动箱线图的异常值?
【发布时间】:2020-08-21 14:22:33
【问题描述】:

我正在尝试使用 matlotlib 来控制使用 seaborn 生成的“缺口”箱形图中异常值的外观。我的代码如下所示:

ax = sns.boxplot(y= "class", x = "Proba",hue = "Stage", data = df_tidy, notch = True,
                 showmeans= True, meanprops={"marker": ".", "markerfacecolor":"red", "markeredgecolor": "red"},
                 flierprops = dict(markerfacecolor = '.1', markersize = .0018, linestyle = "none", markeredgecolor='steelblue'),
                 boxprops=dict(alpha=.7), width=.3)

但是,我有相当多的异常值,这使得箱线图在美学上看起来有点不吸引人;具体来说,我在胡须之外看到了近乎连续的异常值流。不幸的是,我无法为这个示例生成虚构数据,因为它需要在一个本来很大的数据集中有许多异常值才能发生。

我尝试在某种程度上使用异常值的替代颜色来“改进”这一点并减小它们的大小,但并没有太大改善结果。一个效果适中的选项是将 flierprops 中的“linestyle”参数设置为“dotted”。

但是,有没有办法将“抖动”参数传递给 flierprops 字典?有人可以建议一种使异常值抖动的方法吗?

【问题讨论】:

    标签: python matplotlib seaborn


    【解决方案1】:

    代码的第一部分尝试创建一个 MRE。

    要拥有非常小的标记,可以将 linecolor 设置为“none”,以使标记周围的线条完全不可见,并使用像素标记 ','。使用 alpha 可以进一步增强同一点附近的许多标记。您可能需要对您的数据进行试验,以找出产生最佳结果的 alpha 量。

    在参考this post 并进行了一些实验之后,看起来在这种情况下我们可以得到属于ax 的行。列表中每七个Line2D 似乎对应于异常值。我们可以提取它们的 y 位置,添加一些抖动并替换它们。

    import matplotlib.pyplot as plt
    import seaborn as sns
    import numpy as np
    
    N = 100000
    x = np.where(np.random.randint(20, size=N * 6) > 0,
                 np.random.normal(np.repeat([30, 35], N * 3), 10, N * 6) * np.tile([1, 1.3, 1.1], N * 2),
                 np.random.normal(80, 5, N * 6))
    y = np.tile(['A', 'B', 'C'], N * 2)
    hue = np.repeat(['X', 'Y'], N * 3)
    
    ax = sns.boxplot(y=y, x=x, hue=hue, notch=True,
                     showmeans=True, meanprops={"marker": ".", "markerfacecolor": "red", "markeredgecolor": "red"},
                     flierprops=dict(marker=',', markerfacecolor='steelblue', markeredgecolor='none', alpha=.1),
                     boxprops=dict(alpha=.7), width=.3)
    
    for line in ax.get_lines()[6::7]:
        # line.set_mec('purple') # to test that we have the correct Line2Ds
        yoffsets = line.get_ydata()
        line.set_ydata(yoffsets + np.random.uniform(-0.05, 0.05, yoffsets.size))
    

    【讨论】:

    • 谢谢@JohanC。您的回答会有所帮助,但如果在 flierprops 字典中启用抖动功能会很棒 - 特别是当异常值的数量可能比本示例中的大得多时。
    • 这大大改善了@Johan。不幸的是,我的异常值似乎太多了,但您的回答是“正确的”并解决了我原来的问题。谢谢!
    • 我现在将代码更改为具有更多点的测试并使用 alpha。 (测试数据现在也有一些正态分布的异常值,而不是统一的)
    • 使用 alpha 的好主意。这看起来很漂亮@JohanC。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 2017-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多