多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Plotly.py 线性与非线性趋势线完全指南:OLS、LOWESS、移动平均与 `trendline_options` 深度解析

Plotly.py 线性与非线性趋势线完全指南:OLS、LOWESS、移动平均与 `trendline_options` 深度解析 数据可视化数据分析【免费下载链接】plotly.pyThe interactive graphing library for Python :sparkles:项目地址https://gitcode.com/gh_mirrors/pl/plotly.py点击查看免费下载Plotly Express 提供了开箱即用的统计趋势线能力通过trendline参数你可以在散点图上叠加普通最小二乘OLS回归线、LOWESS 局部加权平滑曲线以及基于 Pandas 的滚动rolling、指数加权ewm和扩张expanding均值曲线。本文以 doc/python/linear-fits.md 为主线结合 plotly/express/trendline_functions/init.py 等源码实现完整讲解每种趋势线的配置参数、底层拟合原理、结果提取方法以及仅显示趋势线等实战技巧帮助你在一张图中快速完成数据探索与统计建模的可视化。环境准备安装statsmodels与示例数据趋势线功能依赖以下第三方库statsmodelsOLS 与 LOWESS 趋势线的底层拟合引擎。运行pip install statsmodels或按 statsmodels 官方安装文档 安装其依赖即可启用。pandasrolling、ewm、expanding三类趋势线内部通过 Pandas Series 的窗口函数实现见 trendline_functions/init.py 中_pandas函数对pandas的强制导入。文中示例使用的内置数据集均定义在 plotly/data/init.pypx.data.tips()餐厅小费数据含total_bill、tip、sex、smoker等列适合演示分组拟合每行代表一笔餐厅账单见 数据定义。px.data.gapminder()全球人口经济数据可指定year2007含gdpPercap、lifeExp等列适合演示对数变换拟合。px.data.stocks(datetimesTrue)6 只科技股 2018/2019 年的收盘价宽表date列可转为 datetime 类型见 数据定义适合时间序列上的移动平均演示indexedTrue时date列为索引。一、OLS 线性回归趋势线一行代码完成最小二乘拟合Plotly Express 的px.scatter支持trendline参数传入ols即可为散点图添加普通最小二乘回归线。将鼠标悬停在趋势线上会显示拟合出的直线方程与 R²决定系数。import plotly.express as px df px.data.tips() fig px.scatter(df, xtotal_bill, ytip, trendlineols) fig.show()OLS 趋势线的底层实现从源码看trendlineols最终调用 trendline_functions/init.py 中的ols()函数校验trendline_options的键必须属于[add_constant, log_x, log_y]否则抛出ValueError若log_x/log_y为True先对输入取以 10 为底的对数输入含非正值会抛错若add_constantTrue默认调用sm.add_constant(x)拟合截距项调用sm.OLS(y, x, missingdrop).fit()完成拟合predict()得到趋势线取值构造 hover 提示文本格式为y_label 斜率 * x_label 截距并附上R²...见 ols 源码。趋势线逐条追加入图中px.scatter会为每个数据 trace 追加一条modelines的趋势线 trace并将x标签映射为%{x}、y标签映射为%{y} b(trend)/b见 _core.py 趋势线处理。trendline_options对 OLS 的完整参数参数键类型/默认值含义add_constantbool默认True为False时趋势线强制过原点不拟合 y 截距为True时拟合截距项log_xbool默认False对 x 取以 10 为底的对数后再拟合。注意输入不能含 0 或负数log_ybool默认False对 y 取对数后拟合预测值再还原为原始尺度同样要求输入全为正非法键会触发校验错误OLS trendline_options keys must be one of [add_constant, log_x, log_y] but got ...。二、按分组拟合多条趋势线并提取完整模型参数trendline与color、symbol、facet_col等分组参数组合时Plotly Express会对每个 trace每个分组分别拟合一条趋势线并把所有拟合结果存入 figure 内部可通过px.get_trendline_results(fig)取回。import plotly.express as px df px.data.tips() fig px.scatter(df, xtotal_bill, ytip, facet_colsmoker, colorsex, trendlineols) fig.show() results px.get_trendline_results(fig) print(results) results.query(sex Male and smoker Yes).px_fit_results.iloc[0].summary()get_trendline_results的工作原理px.get_trendline_results(fig)的实现非常轻量——直接返回fig._px_trendlines见 get_trendline_results 源码。这是一个pandas.DataFrame每一行对应一个拟合子集包含该子集的全部标识列如sex、smoker等与px_fit_results列px_fit_results列存放的是statsmodels.api.OLS.fit()返回的完整结果对象因此可以调用.summary()、.params、.rsquared、.pvalues等方法做深入统计检验。这些结果是在拟合过程中逐行收集的分组循环里把mapping_labels.copy()含分组标签与fit_results打包进trendline_rows最后统一构造成 DataFrame 赋给fig._px_trendlines见 _core.py 结果收集。测试用例 tests/test_optional/test_px/test_trendline.py 验证了OLS 模式下的px_fit_results条目len(params) 2截距 斜率且非 OLS 模式返回的结果为空表。三、trendline_scopeoverall用整个数据集拟合一条趋势线自 v5.2 起可用默认情况下trendline_scopetrace即按 trace 分组逐条拟合。若希望基于完整数据集只拟合一条趋势线并让这条线叠加显示在所有分面facet与动画帧上可设置trendline_scopeoverallimport plotly.express as px df px.data.tips() fig px.scatter(df, xtotal_bill, ytip, symbolsmoker, colorsex, trendlineols, trendline_scopeoverall) fig.show()overall模式下趋势线的颜色默认取自数据 trace 的颜色序列可用trendline_color_override强制覆盖为指定颜色import plotly.express as px df px.data.tips() fig px.scatter(df, xtotal_bill, ytip, facet_colsmoker, colorsex, trendlineols, trendline_scopeoverall, trendline_color_overrideblack) fig.show()从 _core.py 的make_trendline_spec与第 2815-2830 行可见overall分支单独构造一条趋势线 trace使用all的行/列范围复制到所有子图且只有在未指定trendline_color_override时才会从颜色序列中取色。四、OLS 的 X/Y 对数变换拟合独立于坐标轴刻度自 v5.2 起可用trendline_options中的log_x/log_y控制的是拟合计算时是否对数据取对数与坐标轴本身是否为对数刻度log_xTrue参数完全独立。因此可以组合出四种场景场景一仅对数变换拟合但坐标轴保持线性刻度import plotly.express as px df px.data.gapminder(year2007) fig px.scatter(df, xgdpPercap, ylifeExp, trendlineols, trendline_optionsdict(log_xTrue), titleLog-transformed fit on linear axes) fig.show()场景二坐标轴与拟合都使用对数import plotly.express as px df px.data.gapminder(year2007) fig px.scatter(df, xgdpPercap, ylifeExp, log_xTrue, trendlineols, trendline_optionsdict(log_xTrue), titleLog-scaled X axis and log-transformed fit) fig.show()注意log_xTrue时拟合输入不可含非正值源码中对应检查为np.any(x 0)时抛出ValueError见 ols 源码。若只是想让坐标轴显示为对数刻度而不改变拟合方式仅传入log_xTrue即可。五、LOWESS 非线性平滑趋势线Plotly Express 同样支持非参数回归的 LOWESSLOcally WEighted Scatterplot Smoothing趋势线适合刻画非线性趋势。同样需要安装statsmodels。import plotly.express as px df px.data.stocks(datetimesTrue) fig px.scatter(df, xdate, yGOOG, trendlinelowess) fig.show()用frac控制平滑程度自 v5.2 起可用LOWESS 的唯一可选参数是frac表示参与局部加权平滑的数据点比例。默认值为0.6666源码中为0.6666666见 lowess 源码此时曲线较为平滑调低frac会让曲线更紧密地贴合数据点import plotly.express as px df px.data.stocks(datetimesTrue) fig px.scatter(df, xdate, yGOOG, trendlinelowess, trendline_optionsdict(frac0.1)) fig.show()frac会被直接透传给statsmodels.api.nonparametric.lowess(y, x, missingdrop, fracfrac)。与 OLS 不同LOWESS 不产出拟合统计结果get_trendline_results对 LOWESS 返回空表hover 提示仅为LOWESS trendline标识。六、移动平均类趋势线rolling / ewm / expanding自 v5.2 起可用trendline还支持rolling、ewm、expanding三种基于 Pandas 窗口函数的趋势线非常适合时间序列的平滑展示。trendline_options中除保留键function与function_args外其余键会被原样透传给对应的 Pandas 方法Series.rolling/Series.ewm/Series.expanding。滚动均值rolling meanimport plotly.express as px df px.data.stocks(datetimesTrue) fig px.scatter(df, xdate, yGOOG, trendlinerolling, trendline_optionsdict(window5), title5-point moving average) fig.show()指数加权移动平均EWM半衰期 2 个点import plotly.express as px df px.data.stocks(datetimesTrue) fig px.scatter(df, xdate, yGOOG, trendlineewm, trendline_optionsdict(halflife2), titleExponentially-weighted moving average (halflife of 2 points)) fig.show()扩张均值expanding mean随数据累积不断纳入历史点import plotly.express as px df px.data.stocks(datetimesTrue) fig px.scatter(df, xdate, yGOOG, trendlineexpanding, titleExpanding mean) fig.show()底层实现统一入口_pandas三种模式共用_pandas辅助函数见 trendline_functions/init.py其执行流程为从trendline_options中弹出function默认mean与function_args默认空 dict两个保留键将 y 数据构造成pd.Series索引为 x 的原始值日期时区被保留动态调用series.rolling(**options)、series.ewm(**options)或series.expanding(**options)得到聚合对象再调用getattr(agg_obj, function_name)(**function_args)完成聚合按non_missing掩码筛掉缺失值后返回。因此window、halflife、min_periods等所有 Pandas 窗口函数关键字都可以直接使用。需要注意的是源码注释特别说明当前 Narwhals 后端尚不支持rolling/ewm/expanding因此这类趋势线内部始终回退到 Pandas Series 计算。七、自定义聚合函数移动中位数、扩张最大值rolling、expanding、ewm三类趋势线默认执行mean聚合但通过trendline_options的function键可以换成 Pandas 聚合对象上的任意方法例如移动中位数或扩张最大值import plotly.express as px df px.data.stocks(datetimesTrue) fig px.scatter(df, xdate, yGOOG, trendlinerolling, trendline_optionsdict(functionmedian, window5), titleRolling Median) fig.show()import plotly.express as px df px.data.stocks(datetimesTrue) fig px.scatter(df, xdate, yGOOG, trendlineexpanding, trendline_optionsdict(functionmax), titleExpanding Maximum) fig.show()当所选的聚合函数本身需要额外参数时例如rolling的win_typegaussian要求必须提供std使用function_args字典传入import plotly.express as px df px.data.stocks(datetimesTrue) fig px.scatter(df, xdate, yGOOG, trendlinerolling, trendline_optionsdict(window5, win_typegaussian, function_argsdict(std2)), titleRolling Mean with Gaussian Window) fig.show()上述三个例子的聚合调用链分别等价于Series.rolling(window5).median()、Series.expanding().max()、Series.rolling(window5, win_typegaussian).mean(std2)。八、仅显示趋势线隐藏散点有时我们只关心趋势本身而不需要原始散点。Plotly Express 生成的趋势线 trace 的mode为lines因此可以过滤fig.data只保留线型 trace同时趋势线默认showlegendFalse需要手动开启图例import plotly.express as px df px.data.stocks(indexedTrue, datetimesTrue) fig px.scatter(df, trendlinerolling, trendline_optionsdict(window5), title5-point moving average) fig.data [t for t in fig.data if t.mode lines] fig.update_traces(showlegendTrue) # trendlines have showlegendFalse by default fig.show()九、缺失值处理与常见错误速查趋势线对缺失值的处理有明确约定并由测试用例 tests/test_optional/test_px/test_trendline.py 系统覆盖x 或 y 中的None/NaN会被剔除non_missing掩码趋势线仅基于有效点拟合若剔除后有效点不足 2 个趋势线 trace 的 x 为None不绘制但 scatter trace 仍保留剔除后只要剩余点数足够趋势线正常绘制OLS 的 hover 文本必定包含Rsup2/sup测试断言见 test_trendline.py。常见错误汇总错误场景报错信息源码位置trendline传入非法值Value: ... for trendline must be one of ...校验逻辑合法值即ols、lowess、rolling、ewm、expandingOLS 使用非法 options 键OLS trendline_options keys must be one of [add_constant, log_x, log_y]LOWESS 使用非法 options 键LOWESS trendline_options keys must be one of [frac]log_xTrue且 x 含非正值Cant do OLS trendline with log_xTrue when x contains non-positive values.log_yTrue且 y 含非正值Cant do OLS trendline with log_yTrue when y contains non-positive values.未安装 pandas 就使用窗口类趋势线Trendline requires pandas to be installed十、五种趋势线能力总览trendline值类型依赖可用trendline_options键是否产出get_trendline_results结果ols线性回归statsmodelsadd_constant、log_x、log_y是完整 statsmodels 结果对象含summary()、params、rsquaredlowess非线性平滑statsmodelsfrac默认0.6666否rolling滚动窗口pandas透传Series.rolling参数 functionfunction_args否ewm指数加权pandas透传Series.ewm参数 functionfunction_args否expanding扩张窗口pandas透传Series.expanding参数 functionfunction_args否五个合法取值均定义在 trendline_functions/init.py 的__all__中[ols, lowess, rolling, ewm, expanding]并通过 _core.py 顶部 注册进trendline_functions字典供px.scatter等图表函数统一调度trendline_options会被作为第一个位置参数传入对应趋势线函数见 文档字符串说明。实际使用时的推荐组合需要严谨的统计推断斜率、p 值、R²选ols并配合px.get_trendline_results数据呈明显非线性、想快速观察趋势形态选lowess微调frac处理时间序列、强调局部均值或衰减权重时选rolling/ewm/expanding并按需用function切换到median、max等聚合方式。赞分享数据可视化数据分析【免费下载链接】plotly.pyThe interactive graphing library for Python :sparkles:项目地址https://gitcode.com/gh_mirrors/pl/plotly.py点击查看免费下载相关推荐把awesome-IoT-hybrid变成选型工具三步搭建从硬件到App的全栈物联网方案把awesome IoT hybrid变成选型工具三步搭建从硬件到App的全栈物联网方案 awesome IoT hybrid 是一份精选的 IoT物联网数据可视化数据分析scikit-learn 线性模型完全指南从 OLS 到鲁棒回归与广义线性模型scikit learn 线性模型完全指南从 OLS 到鲁棒回归与广义线性模型 导读 本文是 scikit learn 官方用户指南《Linear Model人工智能机器学习数据科学Kronos金融大模型从K线Token化到A股回测的完整实践Kronos金融大模型从K线Token化到A股回测的完整实践 Kronos是首个开源的金融市场K线基础模型在45个以上全球交易所的数据上完成预训练。它把开高人工智能大模型基础模型预训练金融科技上一篇Easy-Vibe 前端实战用现代组件库 AI IDE 完成 Vibe Coding 界面升级HeroUI / shadcn/ui / Ant Design 全攻略下一篇终极Shader School指南从GLSL基础到高级着色器开发的完整路径创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表