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

Dash Plotly技术问询:如何通过DatePickerRange组件实现DataFrame的日期筛选并更新图表?

我帮你找出了问题所在,你的回调函数里的日期过滤逻辑有几个关键错误,导致无法正确筛选数据。下面是修正后的完整代码,以及详细的问题解析:

问题分析

  • 日期类型不匹配:dcc.DatePickerRange返回的start_date和end_date是字符串格式(比如"2018-01-01"),但你的df["date_x"]是datetime.date类型,直接比较会导致筛选失效
  • 错误的分组依据:你用pd.date_range生成了日期范围,但没有基于这个范围过滤原数据,反而直接用这个空的日期范围去分组,完全脱离了原始数据集
  • 冗余的变量赋值:min_date = df['date_x'].min()然后立刻min_date = start_date这种操作完全没必要,直接使用传入的参数即可

修正后的完整代码

1. 数据预处理与初始设置

import pandas as pd
import plotly.express as px
from dash import Dash, html, dcc, Input, Output

df = pd.read_csv('Sample_Data2.csv')
# 保持原有日期处理逻辑,转成datetime.date类型
df["date_x"] = pd.to_datetime(df["date_x"]).dt.date

# 初始图表生成逻辑不变
dfp = (
    df.groupby([df["date_x"], df["Categories of event"]])
    .size()
    .unstack("Categories of event", 0)
    .assign(Events=lambda d: d.sum(axis=1))
)
graph = px.line(dfp, markers=True).update_layout(
    xaxis={'dtick': 'D'},
)

app = Dash(__name__)

2. 应用布局(无修改)

app.layout = html.Div([
    html.Div(children=[
        dcc.DatePickerRange(
            id='date_filter',
            start_date=df['date_x'].min(),
            end_date=df['date_x'].max(),
            min_date_allowed=df['date_x'].min(),
            max_date_allowed=df['date_x'].max(),
        ),
    ]),
    html.Div(className='graph', children=[
        dcc.Graph(
            id='graph',
            figure=graph,
            responsive=True,
            animate=True,
        )
    ]),
])

3. 修正后的核心回调函数

@app.callback(
    Output('graph', 'figure'),
    Input('date_filter', 'start_date'),
    Input('date_filter', 'end_date'),
    # 移除prevent_initial_call,确保应用启动时直接渲染初始图表
)
def update_graph(start_date, end_date):
    # 将日期选择器返回的字符串转成datetime.date类型,和df中的date_x匹配
    start_date = pd.to_datetime(start_date).date()
    end_date = pd.to_datetime(end_date).date()
    
    # 核心步骤:过滤原数据,只保留日期范围内的行
    filtered_df = df[(df['date_x'] >= start_date) & (df['date_x'] <= end_date)]
    
    # 用过滤后的数据集重新执行分组逻辑,和初始图表生成逻辑一致
    dfp = (
        filtered_df.groupby([filtered_df["date_x"], filtered_df["Categories of event"]])
        .size()
        .unstack("Categories of event", 0)
        .assign(Events=lambda d: d.sum(axis=1))
    )
    
    # 生成更新后的图表
    updated_graph = px.line(dfp, markers=True).update_layout(
        xaxis={'dtick': 'D'},
    )
    return updated_graph

if __name__ == '__main__':
    app.run_server(debug=True)

额外说明

  • 我移除了prevent_initial_call=True,这样应用启动时会直接渲染正确的初始图表,不需要等待用户操作日期选择器
  • 过滤数据时必须基于原数据集筛选,再用筛选后的结果分组,这是修复逻辑的核心
  • 确保日期类型完全匹配是筛选功能生效的关键

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 01:39:06