如何在Seaborn箱线图上标注均值数值(非showmeans选项)
为Seaborn箱线图标注均值数值
问题说明
使用Seaborn绘制箱线图时,希望为每个箱线图标注均值的具体数值,而非仅通过showmeans显示均值标记。以下是原代码及当前效果:
原代码
import seaborn as sns import pandas as pd import matplotlib.pyplot as plt import matplotlib.font_manager as fm import matplotlib import math data = { 'GROUP': ['AAA1', 'AAA1', 'AAA1', 'AAA1'], 'NAME': [1, 2, 3, 4], 'QTY': [56, 43, 55, 59], 'TEM0001': ['A52', 'B52', 'A22', 'A22'], 'TEM0002': ['B52', 'C32', 'B56', 'B56'], 'TEM0003': ['C52', 'D54', 'C32', 'C4'], 'TEM0004': ['D54', 'E43', 'D33', 'D33'], 'TEM0005': ['E43', 'T56', 'E44', 'E44'], } df = pd.DataFrame(data) df column_indices = range(3,10) fig, axes = plt.subplots(math.ceil( len(column_indices)/4), 4, figsize=(10,8)) axes = axes.flatten() for i, col_idx in enumerate(column_indices): df_selected = df.iloc[:, [2, col_idx]] bp = sns.boxplot(data=df_selected, x=df_selected.columns[1], y='QTY', hue=df_selected.columns[1], ax=axes[i]) m1= df_selected.groupby(df_selected.columns[1])['QTY'].median().values for j in range(len(column_indices), len(axes)): axes[j].axis('off') plt.tight_layout() plt.show()
当前效果
多个子图布局的箱线图,每个子图按对应TEM列的分组展示QTY的分布,但未标注每组的均值数值。
修改后的代码(实现均值标注)
import seaborn as sns import pandas as pd import matplotlib.pyplot as plt import math data = { 'GROUP': ['AAA1', 'AAA1', 'AAA1', 'AAA1'], 'NAME': [1, 2, 3, 4], 'QTY': [56, 43, 55, 59], 'TEM0001': ['A52', 'B52', 'A22', 'A22'], 'TEM0002': ['B52', 'C32', 'B56', 'B56'], 'TEM0003': ['C52', 'D54', 'C32', 'C4'], 'TEM0004': ['D54', 'E43', 'D33', 'D33'], 'TEM0005': ['E43', 'T56', 'E44', 'E44'], } df = pd.DataFrame(data) column_indices = range(3, 10) fig, axes = plt.subplots(math.ceil(len(column_indices)/4), 4, figsize=(10,8)) axes = axes.flatten() for i, col_idx in enumerate(column_indices): df_selected = df.iloc[:, [2, col_idx]] group_col = df_selected.columns[1] # 绘制箱线图 bp = sns.boxplot(data=df_selected, x=group_col, y='QTY', hue=group_col, ax=axes[i]) # 计算每组的均值 mean_values = df_selected.groupby(group_col)['QTY'].mean().reset_index() # 获取每个箱线图的位置,用于标注 for idx, row in mean_values.iterrows(): # 获取x轴位置(箱线图的中心) x_pos = idx # 均值数值 mean_val = row['QTY'] # 在箱线图上方标注均值,可调整y位置避免遮挡 axes[i].text(x_pos, mean_val + 0.5, f'{mean_val:.1f}', ha='center', va='bottom', fontsize=9) # 可选:设置子图标题 axes[i].set_title(f'{group_col} 分布') for j in range(len(column_indices), len(axes)): axes[j].axis('off') plt.tight_layout() plt.show()
关键修改点
- 替换原代码中的中位数计算为均值计算:用
groupby().mean()获取每组的均值 - 添加
axes[i].text()方法,在每个箱线图的对应x位置、均值上方标注数值,通过ha='center'保证居中对齐 - 可调整
mean_val + 0.5中的偏移量,避免标注与箱线图元素重叠 - 可选添加子图标题,提升可读性
内容的提问来源于stack exchange,提问作者joo
相关产品推荐
相关产品推荐

