如何在Plotly多项式回归线的特定点计算并添加斜率(切线)
计算Plotly LOWESS趋势线特定点的斜率并添加到图表里
咱们先来理一理:你用的是LOWESS局部加权回归,这玩意儿不像OLS有明确的系数表达式,所以得用数值方法来算特定点的斜率。下面一步步来操作:
1. 先拿到LOWESS趋势线的拟合数据
Plotly Express自带了px.get_trendline_results()函数,能直接提取趋势线的拟合结果。咱们用它把拟合出来的x和y值取出来,后续计算斜率全靠这些数据。
2. 计算目标点的斜率(数值微分)
因为LOWESS是局部拟合的非参数模型,没有现成的斜率公式,所以咱们用数值差分来近似斜率:
- 如果目标点不在拟合数据的首尾,用中心差分(取前后两个点的差值计算),精度更高;
- 如果是首尾的边界点,就用前向或后向差分来算。
3. 把切线和斜率标注加到图表里
拿到斜率后,咱们先算出切线方程,然后用add_shape()画一条虚线切线,再用add_annotation()把斜率数值标在旁边,这样一眼就能看明白。
完整代码示例
import plotly.express as px import numpy as np # 假设你的final_df已经准备好 fig = px.scatter( x=final_df.index, y=final_df.nr_deaths, trendline="lowess", trendline_color_override="red", trendline_options=dict(frac=0.1), opacity=.5, title='Deaths per year' ) # 步骤1:获取LOWESS拟合结果 trendline_results = px.get_trendline_results(fig) lowess_fit = trendline_results.iloc[0]["px_fitted_results"] fit_x = lowess_fit.x # 拟合趋势线的x值 fit_y = lowess_fit.y # 拟合趋势线的y值 # 步骤2:计算目标点的斜率 target_x = 2015 # 替换成你想要计算斜率的特定x值 # 找到拟合数据中最接近target_x的点的索引 idx = np.argmin(np.abs(fit_x - target_x)) # 计算斜率:优先用中心差分,边界点用前后差分 if 0 < idx < len(fit_x) - 1: # 中心差分:(y[i+1]-y[i-1])/(x[i+1]-x[i-1]) slope = (fit_y[idx+1] - fit_y[idx-1]) / (fit_x[idx+1] - fit_x[idx-1]) elif idx == 0: # 第一个点用前向差分 slope = (fit_y[idx+1] - fit_y[idx]) / (fit_x[idx+1] - fit_x[idx]) else: # 最后一个点用后向差分 slope = (fit_y[idx] - fit_y[idx-1]) / (fit_x[idx] - fit_x[idx-1]) # 获取目标点对应的拟合y值 target_y = fit_y[idx] # 步骤3:添加切线到图表 # 定义切线的x范围(可以根据你的数据调整长度) tangent_x_range = [target_x - 3, target_x + 3] # 根据切线方程计算对应的y值:y = slope*(x - target_x) + target_y tangent_y_range = [slope*(x - target_x) + target_y for x in tangent_x_range] fig.add_shape( type="line", x0=tangent_x_range[0], y0=tangent_y_range[0], x1=tangent_x_range[1], y1=tangent_y_range[1], line=dict(color="blue", width=2, dash="dash"), name=f"Tangent at x={target_x}" ) # 添加斜率标注 fig.add_annotation( x=target_x, y=target_y, text=f"Slope: {slope:.2f}", # 保留两位小数,可按需调整 showarrow=True, arrowhead=2, ax=60, ay=-60, # 调整箭头位置,避免遮挡数据点 font=dict(size=12, color="blue") ) # 更新图例(可选) fig.update_layout(legend_title_text="Series") fig.show()
小提示
- 如果你的目标x值不在拟合的
fit_x中,代码会自动找到最接近的点计算斜率,这符合LOWESS局部拟合的特性; - 可以调整
tangent_x_range的数值来改变切线长度,让它在图表里更协调; - 标注的位置可以通过
ax和ay参数微调,避免遮挡重要数据。
内容的提问来源于stack exchange,提问作者Createdd
相关产品推荐
相关产品推荐

