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

Seaborn小提琴图:多特征下hue与split参数组合应用方法

Seaborn嵌套拆分小提琴图实现方案

需求说明

基于seaborn内置tips数据集,实现单图展示三个分类维度与total_bill(总账单金额)的分布关联:

  • 横轴为星期维度(day字段)
  • 每个星期下并排展示2个独立小提琴,分别对应吸烟者、非吸烟者群体
  • 每个小提琴内部通过split模式拆分,分别展示男性、女性群体的分布差异,全图共8个互不重叠的分布半区
  • 直接叠加两个violinplot调用会出现图层覆盖、分组错位问题;直接传入多分类hue会为每个特征组合生成独立小提琴,不符合预期。

数据集样例

total_bill   tip     sex smoker   day    time  size
0         16.99  1.01  Female     No   Sun  Dinner     2
1         10.34  1.66    Male     No   Sun  Dinner     3
2         21.01  3.50    Male     No   Sun  Dinner     3
3         23.68  3.31    Male     No   Sun  Dinner     2
4         24.59  3.61  Female     No   Sun  Dinner     4
..          ...   ...     ...    ...   ...     ...   ...
239       29.03  5.92    Male     No   Sat  Dinner     3
240       27.18  2.00  Female    Yes   Sat  Dinner     2
241       22.67  2.00    Male    Yes   Sat  Dinner     2
242       17.82  1.75    Male     No   Sat  Dinner     2
243       18.78  3.00  Female     No  Thur  Dinner     2

原有错误实现代码

import seaborn as sns
import matplotlib.pyplot as plt

tips = sns.load_dataset("tips")
ax = sns.violinplot(x="day", y="total_bill", hue="smoker", data=tips, palette="muted", split=False)
ax = sns.violinplot(x="day", y="total_bill", hue="sex", data=tips, palette="muted", split=True)

单维度分组参考效果

按smoker分组的小提琴图
按sex拆分的小提琴图

实现代码

核心思路:seaborn原生violinplot不支持hue嵌套拆分,通过手动设置x轴位置偏移,将按sex拆分的两组小提琴分别对齐到吸烟、非吸烟组的对应位置,调整宽度避免重叠。

import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Patch

# 加载数据集
tips = sns.load_dataset("tips")

# 初始化画布
plt.figure(figsize=(10, 6))
ax = plt.gca()

# 定义横轴分类顺序与位置参数
day_cat = ["Thur", "Fri", "Sat", "Sun"]
x_base = np.arange(len(day_cat))
violin_width = 0.35  # 单个小提琴宽度,控制两组间距

# 绘制吸烟组拆分小提琴:位置左移半宽
sns.violinplot(
    x=x_base - violin_width/2,
    y="total_bill",
    hue="sex",
    data=tips[tips["smoker"] == "Yes"],
    palette="Set2",
    split=True,
    width=violin_width,
    ax=ax
)

# 绘制非吸烟组拆分小提琴:位置右移半宽
sns.violinplot(
    x=x_base + violin_width/2,
    y="total_bill",
    hue="sex",
    data=tips[tips["smoker"] == "No"],
    palette="Set2",
    split=True,
    width=violin_width,
    ax=ax
)

# 调整横轴刻度
ax.set_xticks(x_base)
ax.set_xticklabels(day_cat)
ax.set_xlabel("Week Day")
ax.set_ylabel("Total Bill Amount")

# 去重图例并补充分组说明
handles, labels = ax.get_legend_handles_labels()
ax.legend(
    handles=handles[:2] + [
        Patch(facecolor="white", edgecolor="gray", label="Left violin: Smoker"),
        Patch(facecolor="white", edgecolor="gray", label="Right violin: Non-smoker")
    ],
    labels=labels[:2] + ["Left violin: Smoker", "Right violin: Non-smoker"],
    bbox_to_anchor=(1.03, 1),
    loc="upper left"
)

plt.tight_layout()
plt.show()

参数调整说明

  • 修改violin_width可调整吸烟/非吸烟两个并排小提琴的间距,值越大间距越小
  • 修改palette参数可自定义性别分组的配色
  • 如需调整吸烟/非吸烟组的左右位置,交换两个violinplot调用的偏移量即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 04:48:04