如何为Seaborn分组小提琴图添加基于平均Fare的颜色刻度
给Seaborn拆分小提琴图按分组平均票价着色的实现方法
要实现给每个半小提琴基于对应class+alive分组的平均fare值着色并添加颜色刻度,你可以按以下步骤操作:
步骤1:预计算分组平均票价
先从泰坦尼克数据集里算出每个(舱位+存活状态)组合的平均票价,作为颜色映射的依据:
import seaborn as sns import matplotlib.pyplot as plt import numpy as np # 加载数据集 df = sns.load_dataset("titanic") # 计算每个(class, alive)分组的平均fare group_means = df.groupby(["class", "alive"])["fare"].mean().reset_index() # 生成分组到平均票价的映射字典 fare_map = {(row["class"], row["alive"]): row["fare"] for _, row in group_means.iterrows()}
步骤2:绘制基础小提琴图并自定义着色
先绘制拆分的小提琴图,再遍历每个小提琴元素,根据对应分组匹配平均票价,给半小提琴上色:
# 初始化颜色映射和归一化器(把fare值映射到颜色范围) cmap = plt.cm.viridis norm = plt.Normalize(vmin=group_means["fare"].min(), vmax=group_means["fare"].max()) # 绘制基础小提琴图,用临时灰色占位hue颜色 ax = sns.violinplot( data=df, x="class", y="age", hue="alive", split=True, inner="quart", palette=["gray", "gray"] ) # 遍历每个小提琴组件,按分组着色 for violin in ax.collections: # 获取当前小提琴对应的舱位标签 x_pos = violin.get_offsets()[0][0] class_label = ax.get_xticklabels()[int(x_pos)].get_text() # 拆分小提琴的左右半部分,分别对应alive的两个取值 paths = violin.get_paths() for i, path in enumerate(paths): alive_label = ["yes", "no"][i] if x_pos % 1 == 0 else ["no", "yes"][i] # 获取该分组的平均票价 avg_fare = fare_map[(class_label, alive_label)] # 给半小提琴填充对应颜色 path.set_facecolor(cmap(norm(avg_fare))) path.set_edgecolor("white") # 加白边区分半小提琴 # 添加颜色条,展示票价与颜色的对应刻度 sm = plt.cm.ScalarMappable(norm=norm, cmap=cmap) sm.set_array([]) plt.colorbar(sm, ax=ax, label="平均票价(Fare)") plt.title("不同舱位、存活状态下年龄分布(颜色对应平均票价)") plt.show()
关键说明
- 先用灰色绘制小提琴,避免默认hue颜色干扰,之后再替换为基于平均票价的颜色
- 通过遍历小提琴的路径(paths),拆分左右半部分匹配
alive的两个类别,对应到分组的平均票价 - 用
ScalarMappable生成颜色条,把平均票价的数值范围和颜色映射关联,实现颜色刻度的可视化
内容的提问来源于stack exchange,提问作者Aleksander
相关产品推荐
相关产品推荐

