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)
单维度分组参考效果


实现代码
核心思路: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
相关产品推荐
相关产品推荐

