如何在Seaborn箱线图中添加总观测数、均值、最值等统计标注
如何在Seaborn箱线图中添加总观测数、均值、最值等统计标注
嗨,我来帮你搞定这个需求!要给Seaborn箱线图加上总观测数、均值、最值这些统计标注其实不难,咱们一步步来修改你的代码就行~
首先,咱们得先算出每个分组(也就是你代码里的method)对应的统计数据,然后把这些数据以文本的形式标注到图上合适的位置。我直接在你的现有代码基础上修改,你看了就懂:
修改后的完整代码
import seaborn as sns import matplotlib.pyplot as plt import pandas as pd sns.set_theme(style="ticks") # 初始化图,稍微加宽画布给标注留空间 f, ax = plt.subplots(figsize=(10, 6)) ax.set_xscale("log") # 加载行星数据集 planets = sns.load_dataset("planets") # 绘制水平箱线图 sns.boxplot( planets, x="distance", y="method", hue="method", whis=[0, 100], width=.6, palette="vlag" ) # 添加散点展示每个观测值 sns.stripplot(planets, x="distance", y="method", size=4, color=".3") # ------------------- 新增统计标注部分 ------------------- # 1. 计算每个分组的统计量:总观测数、均值、最小/最大值 stats = planets.groupby('method')['distance'].agg( 总观测数='count', 均值='mean', 最小值='min', 最大值='max' ).reset_index() # 2. 匹配每个method对应的y轴位置(分类y轴从0开始索引) y_tick_labels = [label.get_text() for label in ax.get_yticklabels()] y_pos = {method: idx for idx, method in enumerate(y_tick_labels)} # 3. 确定标注的x位置(选数据最大值的1.1倍,适配log刻度) x_max = planets['distance'].max() x_label_pos = x_max * 1.1 # 4. 遍历每个分组,添加标注文本 for _, row in stats.iterrows(): y = y_pos[row['method']] # 格式化文本,让显示更整洁 label = (f"N: {row['总观测数']}\n" f"均值: {row['均值']:.1f}\n" f"最值: {row['最小值']:.1f}-{row['最大值']:.1f}") # 把标注放在每个箱线的右侧,垂直居中 ax.text(x_label_pos, y, label, va='center', ha='left', fontsize=9, color='#333333') # 调整x轴范围,确保标注能完全显示 ax.set_xlim(right=x_label_pos * 1.2) # ------------------------------------------------------- # 优化视觉效果 ax.xaxis.grid(True) ax.set(ylabel="") sns.despine(trim=True, left=True) plt.show()
关键步骤解释
- 统计量计算:用
pandas.groupby按method分组,直接聚合出我们需要的4个统计量,这一步是标注的基础~ - y轴位置匹配:因为Seaborn的分类y轴是按顺序索引的(从0开始),所以我们把每个method对应到它的y坐标,这样标注才能精准对应到每个箱线。
- 标注位置调整:我选了数据最大值的1.1倍作为x位置,这样标注会在所有箱线的右侧,不会和箱线或者散点重叠;同时加宽了图的宽度,给标注留出足够空间。
- 文本格式化:把统计量换行显示,还保留了一位小数,看起来更清爽,不会乱糟糟的。
这样修改后,你的图右侧就会每个分组都显示对应的总观测数、均值和最值范围啦,完全符合你的需求~
备注:内容来源于stack exchange,提问作者John Honai
相关产品推荐
相关产品推荐

