如何为Seaborn Stripplot的每个day/tip分组添加均值标记点
要给每个day+tip的分组添加均值标记,关键是按这两个维度计算分组均值,再用和stripplot对齐的方式把均值点画上去。这里有两种简单的实现方式:
方法一:用pointplot叠加均值点
pointplot默认会计算分组均值,且支持dodge参数和stripplot对齐,只需关闭连线即可:
import seaborn as sns import pandas as pd import matplotlib.pyplot as plt # 示例数据 df = pd.DataFrame( { 'bill': [50, 45, 33, 23, 22, 34, 54, 22, 54, 76], 'day': ['sat', 'sat', 'sat', 'sat', 'sat', 'sun', 'sun', 'sun', 'sun', 'sun'], 'tip': ['yes', 'no', 'yes', 'no', 'yes', 'no', 'yes', 'no', 'yes', 'no'] } ) # 绘制stripplot sns.stripplot(x='day', y='bill', data=df, jitter=True, hue='tip', palette='deep', dodge=True) # 叠加均值点:linestyle=''去掉连线,dodge与stripplot保持一致,用显眼的标记样式 sns.pointplot(x='day', y='bill', data=df, hue='tip', palette='deep', dodge=True, linestyle='', marker='o', markersize=10, color='black', estimator='mean') # 调整图例避免重复 handles, labels = plt.gca().get_legend_handles_labels() plt.legend(handles[:2], labels[:2]) plt.show()
方法二:手动计算均值后用scatterplot绘制
如果需要更灵活控制均值点样式,可先手动计算分组均值,再定位绘制:
import seaborn as sns import pandas as pd import matplotlib.pyplot as plt df = pd.DataFrame( { 'bill': [50, 45, 33, 23, 22, 34, 54, 22, 54, 76], 'day': ['sat', 'sat', 'sat', 'sat', 'sat', 'sun', 'sun', 'sun', 'sun', 'sun'], 'tip': ['yes', 'no', 'yes', 'no', 'yes', 'no', 'yes', 'no', 'yes', 'no'] } ) # 1. 绘制stripplot ax = sns.stripplot(x='day', y='bill', data=df, jitter=True, hue='tip', palette='deep', dodge=True) # 2. 计算分组均值 mean_df = df.groupby(['day', 'tip'])['bill'].mean().reset_index() # 3. 获取x轴类别位置,处理dodge偏移量(默认偏移为0.2) x_categories = ax.get_xticks() dodge_offset = 0.2 # 遍历均值数据,绘制每个分组的均值点 for idx, row in mean_df.iterrows(): # 根据tip确定偏移方向:yes和no分别在day位置的左右两侧 x_pos = x_categories[list(ax.get_xticklabels()).index(row['day'])] x_pos += dodge_offset if row['tip'] == 'yes' else -dodge_offset ax.scatter(x_pos, row['bill'], color='black', s=100, zorder=10, marker='X') plt.show()
关键说明
- 两种方法都要确保
dodge=True,让tip子类别在day分组下分开,均值点才能对齐对应散点组。 - 方法一用
pointplot更简洁,自动处理分组和位置;方法二更灵活,适合自定义均值点的位置、样式。
内容的提问来源于stack exchange,提问作者missingfours
相关产品推荐
相关产品推荐

