如何在Plotly箱线图中显示ANOVA的P值
问题:为Plotly箱线图添加ANOVA P值
我已经创建了如下箱线图:
现在想为每个作物添加ANOVA的P值,比如针对作物Mn24,我手动计算P值的代码如下:
from scipy.stats import f_oneway control= [15.72, 15.3, 17.55, 15.67, 16.59, 16.33, 17.57, 9.64, 18.81, 19.21, 13.19, 15.23, 15.5, 17.62, 16.19, 16.87, 14.84, 16, 17.28, 16.21] min_uvc = [ 14.19, 16.36, 18.48, 14.42, 17.21, 15.53, 13.87, 14.4, 12.82, 18.22, 16.16, 12.32, 17.3,, 12.91, 13.95, 15.16, 18.72, 15.04, 14.23, 15.44] min_uvc = [ 19.15, 16.8, 16.2, 14.71, 17.71, 17.25, 16, 17.55, 14.68, 14.01, 17.4, 16.12, 17, 16.23, 15.89, 15.67, 16.5, 18.15, 17.15, 17 ] f_oneway(control, min_uvc, min_uvc)
计算结果为:
F_onewayResult(statistic=0.6694852492816592, pvalue=0.5159512878772639)
我希望将每个作物的P值显示在箱线图上,效果类似下图:
我查阅了Plotly箱线图官方文档但未找到相关帮助,请问有什么实现建议或指引吗?相关数据可参考指定gist文件。
解决方案
核心思路
Plotly原生箱线图没有直接嵌入统计值的功能,需通过批量计算P值+手动添加文本注释的方式实现,具体步骤如下:
1. 批量计算所有作物的ANOVA P值
先读取数据并按作物分组,对每组内的不同处理组计算ANOVA的P值:
import pandas as pd from scipy.stats import f_oneway # 读取数据(替换为你的数据加载方式) df = pd.read_csv("你的数据文件路径") # 按作物分组计算P值 p_values = {} # 替换为实际的列名:作物列、处理组列、数值列 for crop, group in df.groupby("作物列名"): # 提取当前作物下各处理组的数据列表 treatment_groups = [data for _, data in group.groupby("处理组列名")["数值列名"]] # 执行ANOVA计算 _, p_val = f_oneway(*treatment_groups) p_values[crop] = round(p_val, 4) # 保留4位小数,可按需调整
2. 在箱线图上添加P值注释
创建箱线图后,通过add_annotation()为每个作物对应的x轴位置添加P值文本:
import plotly.express as px # 创建基础箱线图 fig = px.box(df, x="作物列名", y="数值列名", color="处理组列名") # 获取x轴的作物顺序和对应坐标位置 x_categories = fig.layout.xaxis.categoryarray x_positions = list(range(len(x_categories))) # 遍历每个作物添加注释 for pos, crop in zip(x_positions, x_categories): # 获取当前作物的最大y值,设置注释的垂直位置(加少量偏移避免与箱线重叠) max_y = df[df["作物列名"] == crop]["数值列名"].max() y_pos = max_y + (df["数值列名"].max() * 0.02) # 偏移量可按需调整 # 添加P值注释 fig.add_annotation( x=pos, y=y_pos, text=f"P = {p_values[crop]}", showarrow=False, font=dict(size=10, color="black") ) # 调整y轴范围,避免注释被裁剪 fig.update_layout(yaxis_range=[df["数值列名"].min() * 0.95, df["数值列名"].max() * 1.05]) fig.show()
3. 细节优化
- 若P值极小(如<0.0001),可改用科学计数法显示:
text=f"P = {p_values[crop]:.2e}" - 可根据显著性设置文本颜色,比如P<0.05时用红色:
font=dict(size=10, color="red" if p_values[crop]<0.05 else "black") - 若箱线图有复杂分组,可通过
fig.layout.xaxis.tickvals确认x轴坐标位置,确保注释对齐正确
内容的提问来源于stack exchange,提问作者user2129623
相关产品推荐
相关产品推荐

