You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用seaborn/matplotlib为时间戳x轴的销量数据绘制平滑拟合线

平滑拟合线实现方案

错误原因

你此前的代码存在两个核心问题:

  • 生成插值采样点xnew时误用了销量sales的数值区间,应该使用时间day_id的区间
  • scipy插值方法不支持直接传入datetime类型的时间戳,需要先转换为数值格式

方案1:修正的样条插值实现

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from scipy.interpolate import make_interp_spline

# 原有绘图逻辑
sns.lineplot(x = 'day_id', y = 'sales', data = df, label='实际销量')
plt.axvline('2021-08-28',0,1, ls = '--', lw = 3, c ='black')
plt.text('2021-08-28',5,'2021-08-28', ha='center', va='center',
         bbox={'facecolor':'white','alpha':1,'edgecolor':'none','pad':1})

# 转换时间为数值型时间戳
x_ts = df['day_id'].astype(np.int64)
# 生成300个均匀时间采样点
xnew_ts = np.linspace(x_ts.min(), x_ts.max(), 300)
# 三次样条拟合
spl = make_interp_spline(x_ts, df['sales'], k=3)
y_smooth = spl(xnew_ts)
# 数值时间戳转回日期格式,适配原有x轴
xnew_date = pd.to_datetime(xnew_ts)
# 绘制平滑线
plt.plot(xnew_date, y_smooth, c='red', lw=2, label='平滑趋势线')
plt.legend()
plt.show()

方案2:更易用的局部加权平滑(LOWESS)实现

不需要手动处理时间格式转换,直接用seaborn内置方法完成拟合,更适合快速展示整体趋势:

import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd

# 原有绘图逻辑
sns.lineplot(x = 'day_id', y = 'sales', data = df, label='实际销量')
plt.axvline('2021-08-28',0,1, ls = '--', lw = 3, c ='black')
plt.text('2021-08-28',5,'2021-08-28', ha='center', va='center',
         bbox={'facecolor':'white','alpha':1,'edgecolor':'none','pad':1})

# 绘制LOWESS平滑线,scatter=False关闭散点绘制
sns.regplot(x=df['day_id'].astype(np.int64), y=df['sales'],
            lowess=True, scatter=False, color='red',
            line_kws={'lw':2}, label='平滑趋势线')
# 还原x轴为日期显示格式
plt.xticks(plt.xticks()[0], pd.to_datetime(plt.xticks()[0]).strftime('%Y-%m-%d'))
plt.legend()
plt.show()

可通过调整lowess的frac参数控制平滑程度,默认值为0.6,数值越大拟合线越平滑。如果只需要整体升降趋势,可以去掉lowess=True参数,使用默认的线性拟合即可。

内容的提问来源于stack exchange,提问作者Jonas Palačionis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 12:45:03