如何将Seaborn图表中的图例(分组1-19)设置为X轴刻度?
问题
现有如下Pandas DataFrame:
| Group | IP | IB | FP | CP | CS | PB |
|---|---|---|---|---|---|---|
| 0 | 1 | 100 | 20 | 50 | 120 | 40 |
| 1 | 1 | 100 | 20 | 50 | 120 | 40 |
| 2 | 1 | 100 | 20 | 50 | 120 | 40 |
| 3 | 1 | 100 | 20 | 50 | 120 | 40 |
| 4 | 1 | 100 | 20 | 50 | 120 | 40 |
| ... | ... | ... | ... | ... | ... | ... |
| 95 | 18 | 150 | 40 | 50 | 150 | 60 |
| 96 | 19 | 200 | 20 | 70 | 150 | 40 |
| 97 | 19 | 200 | 20 | 70 | 150 | 40 |
| 98 | 19 | 200 | 20 | 70 | 150 | 40 |
| 99 | 19 | 200 | 20 | 70 | 150 | 40 |
使用以下代码通过Seaborn绘图:
df_m = pd.melt(df, id_vars='Group', value_vars=['PB']) fig, ax = plt.subplots(figsize=(15,10)) sns.stripplot(x='variable', y='value', data=df_m, hue='Group', dodge=True, ax=ax, linewidth=1) sns.boxplot(x='variable', y='value', data=df_m, hue='Group') handles, labels = ax.get_legend_handles_labels() ax.legend(handles[:19], labels[:19], title='Group')
希望将图例中的分组1-19设置为X轴刻度,尝试了以下代码但图表出现挤压:
ax.set_xticks(range(19)) ax.set_xticklabels(['G1', 'G2', 'G3', 'G4', 'G5', 'G6', 'G7', 'G8', 'G9', 'G10', 'G11', 'G12', 'G13', 'G14', 'G15', 'G16', 'G17', 'G18', 'G19']);
需要解决图表挤压的问题。
解决方案
问题核心是当前绘图逻辑把所有分组数据挤在同一个X轴位置(variable对应的PB类别),强行设置19个刻度必然重叠。推荐两种解决方式:
方式一:直接将Group作为X轴类别(简洁直观)
无需对DataFrame做melt处理,直接把分组作为X轴独立类别,每个分组占据单独的空间:
fig, ax = plt.subplots(figsize=(15,10)) # 先画箱线图,避免散点被覆盖 sns.boxplot(x='Group', y='PB', data=df, ax=ax, showfliers=False) # 添加散点图展示原始数据 sns.stripplot(x='Group', y='PB', data=df, color='black', size=5, ax=ax) # 设置自定义X轴刻度标签 ax.set_xticklabels(['G1', 'G2', 'G3', 'G4', 'G5', 'G6', 'G7', 'G8', 'G9', 'G10', 'G11', 'G12', 'G13', 'G14', 'G15', 'G16', 'G17', 'G18', 'G19']) # 移除图例(分组已通过X轴展示) ax.get_legend().remove()
方式二:保留原hue+dodge逻辑,手动调整X轴位置
如果想维持原绘图结构,需要手动计算每个分组的偏移位置,让刻度分散开:
df_m = pd.melt(df, id_vars='Group', value_vars=['PB']) fig, ax = plt.subplots(figsize=(15,10)) # 确保dodge=True让分组数据偏移 sns.stripplot(x='variable', y='value', data=df_m, hue='Group', dodge=True, ax=ax, linewidth=1) sns.boxplot(x='variable', y='value', data=df_m, hue='Group', dodge=True, ax=ax) # 计算每个分组对应的X轴位置(默认dodge偏移量为0.2) original_pos = ax.get_xticks()[0] xticks = [original_pos + 0.2*(i-9) for i in range(19)] ax.set_xticks(xticks) ax.set_xticklabels(['G1', 'G2', 'G3', 'G4', 'G5', 'G6', 'G7', 'G8', 'G9', 'G10', 'G11', 'G12', 'G13', 'G14', 'G15', 'G16', 'G17', 'G18', 'G19']) # 移除原X轴标签和图例 ax.set_xlabel('') ax.get_legend().remove()
第一种方式逻辑更清晰,是处理这类分组可视化的常规做法,优先推荐。
内容的提问来源于stack exchange,提问作者A.E
相关产品推荐
相关产品推荐

