如何调整Plotly Express的LOWESS趋势线参数以优化拟合效果
结论
Plotly 4.14.3版本的内置LOWESS趋势线没有开放参数调整入口,内置实现固定使用默认的frac=2/3的拟合窗口,无法通过现有接口修改,这是该版本的已知问题。
这种固定的偏大的默认frac值,正是你当前数据集拟合效果差的核心原因:默认参数生成的拟合线过于平滑,丢失了数据的局部波动特征,而手动调用statsmodels的lowess接口时可以自由调整frac参数,匹配数据的实际特征,自然能得到更好的拟合效果。
可行实现方案
由于内置参数无法调整,最灵活的方式是手动调用statsmodels的LOWESS接口生成符合预期的拟合线,再叠加到Plotly散点图上,完全不需要依赖px的内置trendline逻辑:
- 适配接口输入:因为statsmodels的LOWESS方法不直接支持datetime类型的x值,需要先把日期转换为可计算的数值格式。
- 自定义参数生成拟合结果:调用lowess方法时自由调整frac参数,匹配你想要的拟合平滑度。
- 格式对齐:把拟合结果的x值转回原始日期格式,避免坐标轴错位。
- 叠加元素:在原有散点图上添加拟合折线即可。
可直接运行的代码示例
import pandas as pd import plotly.express as px import plotly.graph_objects as go from statsmodels.nonparametric.smoothers_lowess import lowess # 转换日期为数值,适配statsmodels lowess接口要求 x_ordinal = df['date'].map(pd.Timestamp.toordinal) # 自定义frac值生成拟合结果,0.3为示例参数,可根据需求调整 smoothed_result = lowess(endog=df['y'], exog=x_ordinal, frac=0.3) # 将拟合的数值x转回原始datetime格式,匹配坐标轴 smoothed_x = [pd.Timestamp.fromordinal(int(item)) for item in smoothed_result[:, 0]] smoothed_y = smoothed_result[:, 1] # 绘制原始散点,不再使用内置trendline功能 fig = px.scatter(data_frame=df, x="date", y="y") # 叠加自定义LOWESS拟合线 fig.add_trace(go.Scatter( x=smoothed_x, y=smoothed_y, mode="lines", name="自定义LOWESS拟合线" )) fig.show()
补充说明
- frac参数的调整逻辑:值越小,拟合线越贴近原始数据点,灵活性越高;值越大,拟合线越平滑,局部波动会被抹平。
- 如果后续升级到Plotly 5.10及以上版本,可直接通过
trendline_options字典传入自定义LOWESS参数,不需要手动生成拟合线,示例写法为px.scatter(..., trendline="lowess", trendline_options=dict(frac=0.3))。但你当前使用的4.14.3版本不支持该参数入口,因此优先使用手动叠加的方案。
内容的提问来源于stack exchange,提问作者GitHunter0
相关产品推荐
相关产品推荐

