【问题标题】:Label outliers in a boxplot - Python在箱线图中标记异常值 - Python
【发布时间】:2020-08-27 06:22:38
【问题描述】:

我正在分析极端天气事件。我的数据框名为 df,如下所示:

|    Date    |      Qm      |
|------------|--------------|                                              
| 1993-01-01 |  4881.977061 |
| 1993-02-01 |  4024.396839 |
| 1993-03-01 |  3833.664650 |
| 1993-04-01 |  4981.192526 |
| 1993-05-01 |  6286.879798 |  
| 1993-06-01 |  6939.726070 |
| 1993-07-01 |  6492.936065 |
|    ...     |      ...     |

我想知道极端事件是否与测量的异常值发生在同一年。因此,我使用 seaborn 绘制了箱线图:

# Qm boxplot analysis

boxplot = sns.boxplot(x=df.index.month,y=df['Qm'])
plt.show()

现在,我想在同一个数字中显示与异常值对应的年份。因此,用它们的日期标记它们。

我已经检查了多个包含箱线图的库,但不知道如何标记它们。

PD:我在这个例子中使用了 seaborn,但是任何可以提供帮助的库都将受到高度赞赏

谢谢!

【问题讨论】:

    标签: python label seaborn boxplot


    【解决方案1】:

    我不知道如何将标签连同您的数据一起交给seaborn.boxplotpandas.DataFrame.boxplot。作为解决方法,您可以使用 matplotlib's annotate function 手动注释您的绘图。

    这是一个例子:

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    
    np.random.seed(42)
    df = pd.DataFrame( np.random.randn(50, 2), columns=['Col1', 'Col2'])
    boxplot = df.boxplot(
        column=['Col1', 'Col2'],
        flierprops=dict(markerfacecolor='r', marker='s', label='not shown'))
    boxplot.annotate(
        '1993',
        (1, -2.65),
        xytext=(0.3, 0.15),
        textcoords='axes fraction',
        arrowprops=dict(facecolor='black', arrowstyle='wedge'),
        fontsize=11)
    plt.show()
    

    结果图:

    【讨论】:

      【解决方案2】:

      您可以遍历数据框并将每个值与异常值的限制进行比较。默认情况下,这些限制是 1.5 timesIQR 超过低四分位数和高四分位数。对于该范围之外的每个值,您可以在其旁边绘制年份。如果您想显示更多或更少的年份,请随意调整此定义。

      这里有一些代码来说明这个想法。在代码中,年份的最后两位数字显示在异常值的位置旁边。

      import matplotlib.pyplot as plt
      import numpy as np
      import pandas as pd
      import seaborn as sns
      
      Y = 26
      df = pd.DataFrame({'Date': pd.date_range('1993-01-01', periods=12 * Y, freq='M'),
                         'Qm': np.random.normal(np.tile(5000 + 1000 * np.sin(np.linspace(0, 2 * np.pi, 12)), Y), 1000)})
      df.set_index('Date', inplace=True)
      boxplot = sns.boxplot(x=df.index.month, y=df['Qm'])
      month_q1 = df.groupby(df.index.month).quantile(0.25)['Qm'].to_numpy()
      month_q3 = df.groupby(df.index.month).quantile(0.75)['Qm'].to_numpy()
      outlier_top_lim = month_q3 + 1.5 * (month_q3 - month_q1)
      outlier_bottom_lim = month_q1 - 1.5 * (month_q3 - month_q1)
      
      for row in df.itertuples():
          month = row[0].month - 1
          val = row.Qm
          if val > outlier_top_lim[month] or val < outlier_bottom_lim[month]:
              plt.text(month, val, f' {row[0].year % 100:02d}', ha='left', va='center')
      plt.xlabel('Month')
      plt.tight_layout()
      plt.show()
      

      【讨论】:

        猜你喜欢
        • 2021-11-06
        • 1970-01-01
        • 2017-03-21
        • 1970-01-01
        • 2013-02-17
        • 2013-07-17
        • 1970-01-01
        • 1970-01-01
        • 2018-07-02
        相关资源
        最近更新 更多