You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Seaborn箱线图的每个x标签单独按中位数排序?

解决Seaborn箱线图按分组内中位数单独排序的问题

Seaborn默认的boxplot没法直接实现每个x分组下的hue类别(比如你的模型)按各自中位数排序,因为hue_order是全局生效的。要实现需求,得先预处理数据计算分组内的中位数排序,再用分面绘图来分别指定每个分组的排序:

步骤1:计算每个x分组下的模型中位数排序

假设你的数据框df包含三列:noise_level(x轴标签,如"gaussian 1")、model(模型名称)、metric(箱线图的数值列)。先计算每个噪声水平下各模型的中位数,再生成对应分组的排序模型列表:

import pandas as pd

# 计算每个噪声水平+模型组合的中位数
median_df = df.groupby(['noise_level', 'model'])['metric'].median().reset_index()
# 按噪声水平分组,对每个组内的模型按中位数降序排序(升序把False改成True)
sorted_model_dict = median_df.groupby('noise_level').apply(
    lambda group: group.sort_values('metric', ascending=False)['model'].tolist()
).to_dict()

步骤2:用FacetGrid分面绘制,每个分组单独指定排序

用FacetGrid把每个噪声水平拆成子图,在每个子图里用对应分组的排序模型列表作为hue_order:

import seaborn as sns
import matplotlib.pyplot as plt

# 创建分面网格,每个子图对应一个噪声水平
g = sns.FacetGrid(df, col='noise_level', col_wrap=3, sharex=False, sharey=True)
# 给每个子图绘制箱线图,动态获取当前分组的模型排序
g.map_dataframe(
    sns.boxplot,
    x='noise_level',
    y='metric',
    hue='model',
    hue_order=lambda data: sorted_model_dict[data['noise_level'].iloc[0]]
)
# 添加统一图例
g.add_legend()
plt.tight_layout()
plt.show()

替代方案(不拆分面)

如果想把所有分组放在同一个图里,可以重新构造数据,给每个模型在对应噪声水平下分配排序后的位置,再用x轴表示noise_level,hue按排序后的模型顺序,但这种方法需要手动调整x轴元素位置,不如分面直观。

内容的提问来源于stack exchange,提问作者luc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 04:42:37