在 seaborn 中对箱线图的 x 轴进行排序

23

我的数据框 round_data 看起来像这样:

      error                         username                    task_path
0      0.02  n49vq14uhvy93i5uw33tf7s1ei07vngozrzlsr6q6cnh8w...    39.png
1      0.10  n49vq14uhvy93i5uw33tf7s1ei07vngozrzlsr6q6cnh8w...    45.png
2      0.15  n49vq14uhvy93i5uw33tf7s1ei07vngozrzlsr6q6cnh8w...    44.png
3      0.25  xdoaztndsxoxk3wycpxxkhaiew3lrsou3eafx3em58uqth...    43.png
...     ...                                                ...       ...
1170  -0.11  9qrz4829q27cu3pskups0vir0ftepql7ynpn6in9hxx3ux...    33.png
1171   0.15  9qrz4829q27cu3pskups0vir0ftepql7ynpn6in9hxx3ux...    34.png


[1198 rows x 3 columns]

我想要一个箱线图,显示每个用户的误差,按其平均表现排序。我所拥有的是:

ax = sns.boxplot(
    x='username', 
    y='error', 
    data=round_data,
    whis=np.inf,
    color='c',
    ax=ax
)

这将导致生成以下图表: boxplot

我该如何按平均误差对x轴(即用户)进行排序?

2个回答

31

我找到了答案:

grouped = round_data[round_data.batch==i].groupby('username')
users_sorted_average = (
    pd.DataFrame({col: vals['absolute_error'] for col, vals in grouped})
    .mean()
    .sort_values(ascending=True)
)

在seaborn绘图函数中将users_sorted_average传递给“order”参数将会产生期望的行为:

ax = sns.boxplot(
    x='username', 
    y='error', 
    data=round_data, 
    whis=np.inf,
    ax=ax,
    color=c,
    order=users_sorted_average.index,
)

enter image description here


3
我正在尝试弄清如何应用它。如果我能让它适用于自己的数据,那将是很棒的事情。我想按中位数值进行排序。可惜这个功能不是内置在库中的。 - rocksNwaves

0

正如 @amaatouq 指出的那样,将所需的排序关键字传递给order = 即可完成任务。此排序关键字必须是组合者数组(在 OP 的情况下为用户名)。

# sample data
df = pd.DataFrame({'username': ['a', 'b', 'c']*1000, 'error': np.random.rand(3000)+[0.5,1,0]*1000, 'col': range(3000)})

# construct sorting key
order = ['c', 'a']          # could also be just a list

order = df.groupby('username')['col'].median().sort_values().index
#                                    ^^^^^^^   sort by median col

order = df.groupby('username')['error'].mean().sort_values().index
#                                      ^^^^^^^   sort by mean error

sns.boxplot(x='username', y='error', data=df, whis=np.inf, color='c', order=order);

result


顺便提一下,如果您正在使用pandas dataframe(如OP中所示),则pandas有一个可以使用的boxplot方法;只需要先通过pivot重新整理dataframe,使每个箱子成为自己的列即可。

df.pivot(values='error', columns='username').pipe(lambda x: x[x.mean().sort_values().index]).boxplot(color='c', grid=False)
# ^^^^^^ reshape dataframe                                  ^^^^^^^^^^ sort by mean "error"  ^^^^^^^ plot boxplot

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