Seaborn箱线图中ANOVA检验与科学计数法失效问题排查
问题修复方案
1. Y轴科学计数法显示问题
原代码使用ScalarFormatter但未强制启用科学计数规则,导致大数值未自动切换为科学计数格式。只需替换原有格式设置代码,强制指定Y轴使用科学计数:
ax.ticklabel_format(axis='y', style='sci', scilimits=(0, 0), useMathText=True)
该设置会确保Y轴数值统一以科学计数法展示,同时保留数学文本的规范格式。
2. ANOVA检验结果不显示问题
原代码中annotate使用数据坐标定位,当计算的y_position超出当前轴的显示范围时,标注会被裁剪。改用轴比例坐标(相对于绘图区域的相对位置),可保证标注始终显示在图表上方:
ax.annotate(f'ANOVA p-value: {p_value:.4f} {significance}', xy=(0.5, 1.05), # 水平居中,垂直在轴上方5%位置 xycoords='axes fraction', # 使用轴比例坐标 fontsize=12, ha='center')
无需再依赖数据范围计算y_position,彻底避免因数据波动导致的标注丢失。
修改后的完整代码
import pandas as pd import matplotlib.pyplot as plt import seaborn as sns from scipy.stats import f_oneway import matplotlib.ticker as mticker # 创建数据集 data = { 'a': [533330.45, 488550.63, 433338.27, 63335.47, 613338.78, 658029.33, 423276.31, 486775.20, 465138.94], 'b': [103336.32, 93337.35, 93336.19, 233305.77, 283336.51, 152925.39, 331697.83, 299425.14, 274197.59], 'c': [252919.78, 193330.26, 205333.11, 134333.34, 123332.30, 123336.85, 153332.33, 195452.55, 167399.20], 'd': [44133.07, 43963.73, 35705.67, 135454.11, 137261.84, 152548.42, 233336.48, 213787.00, 257127.76], 'e': [38697.59, 43337.02, 33331.53, 34333.28, 63332.51, 43338.29, 34333.43, 42793.33, 63334.84] } df = pd.DataFrame(data) color_palette = { 'a': 'green', 'b': 'lightgreen', 'c': 'yellow', 'd': 'lightyellow', 'e': 'red' } # 创建画布 plt.figure(figsize=(14, 10)) # 绘制箱线图 ax = sns.boxplot(data=df, palette=color_palette) # 添加散点层展示所有数据点 sns.stripplot(data=df, color="black", ax=ax, jitter=True, dodge=True, alpha=0.5) # 添加水平网格线 ax.yaxis.grid(True, linestyle='dotted', linewidth=0.5, color='lightgray') # 设置Y轴标签及科学计数格式 ax.set_ylabel('values', fontsize=18) ax.ticklabel_format(axis='y', style='sci', scilimits=(0, 0), useMathText=True) ax.yaxis.get_offset_text().set_fontsize(12) # 执行ANOVA检验 _, p_value = f_oneway(df['a'], df['b'], df['c'], df['d'], df['e']) # 添加检验结果标注 significance = "*" if p_value < 0.05 else "ns" ax.annotate(f'ANOVA p-value: {p_value:.4f} {significance}', xy=(0.5, 1.05), xycoords='axes fraction', fontsize=12, ha='center') # 设置X轴刻度标签 ax.set_xticklabels(['a', 'b', 'c', 'd', 'e'], fontsize=20) plt.tight_layout() plt.show()
额外优化说明
- 移除了未使用的冗余导入:
import string、from scipy import stats - 添加
plt.tight_layout()确保图表元素布局合理,避免标签被裁剪
内容的提问来源于stack exchange,提问作者lavo_hos
相关产品推荐
相关产品推荐

