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

如何在Plotly滑块的同一步骤中展示移动平均与Savitzky-Golay滤波曲线

解决方案

要实现20个滑块步骤,每个步骤同时展示对应窗口的移动平均曲线和其Savitzky-Golay滤波曲线,需要调整滑块步骤的逻辑,让每个步骤同时激活两条轨迹。以下是修改后的完整代码及关键说明:

关键修改点

  • 补全scipy.signal中savgol_filter的导入(原代码缺失)
  • 调整轨迹生成循环,确保生成20组(每组2条)轨迹
  • 重构滑块步骤逻辑:每个步骤对应一组两条轨迹,同时设置它们的可见性
  • 修正初始可见轨迹和滑块激活状态,匹配对应窗口组

完整代码

# Imports
import pandas as pd
import numpy as np
import plotly.graph_objs as go
import random
from scipy.signal import savgol_filter  # 补全缺失的导入

Year = 2000
Date = pd.Series(pd.date_range(str(Year) + "-01-01", str(Year) + "-12-31", freq="D"))
Day = Date.diff().astype("timedelta64[D]").fillna(1).cumsum()
dftest = pd.DataFrame({"Day": Day})
dftest = dftest.set_index(Date).reset_index()
dftest = dftest.rename(columns={"index": "Date"})
dftest["Qty"] = [random.randint(1, 10000) for k in dftest.index]
TrendDF = dftest

def TrendMAn(n):
    # 避免修改原DataFrame,直接返回计算结果即可
    return TrendDF["Qty"].rolling(window=n).mean()

fig = go.Figure()

# 生成20组轨迹,每组包含移动平均和滤波曲线
for n in range(1, 21):
    # 添加移动平均曲线
    fig.add_trace(
        go.Scatter(
            line=dict(width=2, color="#1f77b4"),
            x=TrendDF["Date"],
            y=TrendMAn(n),
            mode="lines",
            name=f"移动平均({n}天)",
            visible=False,
        )
    ) 
    # 添加Savitzky-Golay滤波曲线
    fig.add_trace(
        go.Scatter(
            line=dict(width=2, color="#ff7f0e", dash="dash"),
            x=TrendDF["Date"],
            y=savgol_filter(TrendMAn(n), 51, 3),
            mode="lines",
            name=f"SG滤波({n}天)",
            visible=False,
        )
    )

# 设置初始可见的轨迹:对应第10个窗口(步骤索引9)
initial_step_idx = 9
fig.data[2*initial_step_idx].visible = True
fig.data[2*initial_step_idx + 1].visible = True

steps = []
for i in range(20):
    # 每个步骤对应窗口天数n = i+1
    n = i + 1
    visible = [False] * len(fig.data)
    # 激活当前窗口对应的两条轨迹
    visible[2*i] = True
    visible[2*i + 1] = True
    
    step = dict(
        method="update",
        args=[
            {"visible": visible},
            {"title": f"移动平均窗口天数: {n}"}
        ]
    )
    steps.append(step)

sliders = [
    dict(
        active=initial_step_idx,
        currentvalue={"prefix": "移动平均窗口天数: "},
        pad={"t": 50},
        steps=steps,
    )
]

# 添加图例和布局优化
fig.update_layout(
    sliders=sliders,
    legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1),
    yaxis_title="数量",
    xaxis_title="日期"
)

fig.show()

代码说明

  1. 轨迹分组:每个窗口天数对应两条轨迹(移动平均+滤波),按顺序依次添加,第n个窗口的两条轨迹索引为2*(n-1)和2*(n-1)+1。
  2. 滑块步骤:遍历20个窗口,每个步骤中仅激活当前窗口对应的两条轨迹,其余轨迹设为不可见。
  3. 可视化优化:为两条曲线设置不同颜色和样式,添加图例说明,优化标题和坐标轴标签,提升可读性。

内容的提问来源于stack exchange,提问作者melon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 01:12:12