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

如何在Seaborn与Pandas中实现图例按类别分栏显示?

解决Seaborn散点图图例按类别分组分栏的问题

使用Seaborn基于Pandas DataFrame绘制散点图时,通过hue和style区分不同类别,设置图例多列显示在图表上方后,因不同类别条目数量不一致导致布局混乱,希望图例分栏换行时能对应类别组的切换(同一类别的所有条目放在同一栏)。

以下提供两种可行解决方案:

方案一:拆分独立图例,分别对应hue和style

将hue和style对应的图例拆分为两个独立的图例,分别放置在图表上方的左右区域,每个图例内的条目垂直排列,布局更清晰:

import numpy as np
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt

f, ax = plt.subplots()
df = pd.DataFrame({'col1': [1, 2, 3, 1, 2, 3, 4, 1, 2, 3],
                      'col1b': [1.1, 1.9, 3.1, 0.9, 2.1, 3.2, 4.1, 1, 1.8, 3.2],
                      'col2': [1, 1, 1, 2, 2, 2, 2, 3, 3, 3],
                      'col3': [10, 20, 15, 10, 20, 15, 30, 10, 20, 15]})

# 绘制散点图
sns.scatterplot(data=df, x='col1', y='col1b', hue='col2', style='col3', ax=ax)

# 获取并分离hue和style的图例元素
handles, labels = ax.get_legend_handles_labels()
hue_indices = [labels.index(str(i)) for i in df['col2'].unique()]
style_indices = [labels.index(str(i)) for i in df['col3'].unique()]

hue_handles = [handles[i] for i in hue_indices]
hue_labels = [labels[i] for i in hue_indices]
style_handles = [handles[i] for i in style_indices]
style_labels = [labels[i] for i in style_indices]

# 移除默认图例
ax.legend_.remove()

# 创建hue图例并添加到轴上
leg_hue = ax.legend(hue_handles, hue_labels, loc='lower center', bbox_to_anchor=(0.3, 1), 
                    ncol=1, title='col2', frameon=False)
ax.add_artist(leg_hue)

# 创建style图例
ax.legend(style_handles, style_labels, loc='lower center', bbox_to_anchor=(0.7, 1), 
          ncol=1, title='col3', frameon=False)

plt.savefig('mwe_fixed.png')

方案二:重新排列图例元素顺序,合并为单个分栏图例

将hue对应的所有图例条目放在前面,style的条目放在后面,设置分栏后,换行时刚好从hue组切换到style组:

import numpy as np
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt

f, ax = plt.subplots()
df = pd.DataFrame({'col1': [1, 2, 3, 1, 2, 3, 4, 1, 2, 3],
                      'col1b': [1.1, 1.9, 3.1, 0.9, 2.1, 3.2, 4.1, 1, 1.8, 3.2],
                      'col2': [1, 1, 1, 2, 2, 2, 2, 3, 3, 3],
                      'col3': [10, 20, 15, 10, 20, 15, 30, 10, 20, 15]})

# 绘制散点图
sns.scatterplot(data=df, x='col1', y='col1b', hue='col2', style='col3', ax=ax)

# 获取图例元素并重新排序:先hue,后style
handles, labels = ax.get_legend_handles_labels()
hue_labels_list = [str(i) for i in df['col2'].unique()]
style_labels_list = [str(i) for i in df['col3'].unique()]
new_order = [labels.index(l) for l in hue_labels_list + style_labels_list]

new_handles = [handles[i] for i in new_order]
new_labels = [labels[i] for i in new_order]

# 移除默认图例,创建新的分栏图例
ax.legend_.remove()
sns.move_legend(
    ax, "lower center",
    bbox_to_anchor=(.5, 1), ncol=2, title=None, frameon=False,
    handles=new_handles, labels=new_labels
)

plt.savefig('mwe_fixed.png')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 04:49:59