我正在制作一个使用seaborn包装的时间序列箱图,但我不能在我的异常值上贴上标签。
我的数据是3列的数据框:[Month , Id , Value]
我们可以这样伪造:
### Sample Data ###
Month = numpy.repeat(numpy.arange(1,11),10)
Id = numpy.arange(1,101)
Value = numpy.random.randn(100)
### As a pandas DataFrame ###
Ts = pandas.DataFrame({'Value' : Value,'Month':Month, 'Id': Id})
### Time series boxplot ###
ax = seaborn.boxplot(x="Month",y="Value",data=Ts)
我每个月都有一个箱图,我试图将Id作为三个异常值的标签放在这里(1)。
答案 0 :(得分:1)
首先,您需要检测数据框中哪些Id
是离群值,可以使用以下方法:
outliers_df = pd.DataFrame(columns = ['Value', 'Month', 'Id'])
for month in Ts['Month'].unique():
outliers = [y for stat in boxplot_stats(Ts[Ts['Month'] == month]['Value']) for y in stat['fliers']]
if outliers != []:
for outlier in outliers:
outliers_df = outliers_df.append(Ts[(Ts['Month'] == month) & (Ts['Value'] == outlier)])
创建一个与原始数据帧相似的数据帧,仅包含离群值。
然后,您可以在此图上注释Id
:
for row in outliers_df.iterrows():
ax.annotate(row[1]['Id'], xy=(row[1]['Month'] - 1, row[1]['Value']), xytext=(2,2), textcoords='offset points', fontsize=14)
完整代码:
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.cbook import boxplot_stats
sns.set_style('darkgrid')
Month = np.repeat(np.arange(1,11),10)
Id = np.arange(1,101)
Value = np.random.randn(100)
Ts = pd.DataFrame({'Value' : Value,'Month':Month, 'Id': Id})
fig, ax = plt.subplots()
sns.boxplot(ax=ax, x="Month",y="Value",data=Ts)
outliers_df = pd.DataFrame(columns = ['Value', 'Month', 'Id'])
for month in Ts['Month'].unique():
outliers = [y for stat in boxplot_stats(Ts[Ts['Month'] == month]['Value']) for y in stat['fliers']]
if outliers != []:
for outlier in outliers:
outliers_df = outliers_df.append(Ts[(Ts['Month'] == month) & (Ts['Value'] == outlier)])
for row in outliers_df.iterrows():
ax.annotate(row[1]['Id'], xy=(row[1]['Month'] - 1, row[1]['Value']), xytext=(2,2), textcoords='offset points', fontsize=14)
plt.show()
输出: