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

Plotly Express+Dash集成dcc.DatePickerRange多输入回调问题求助

解决方案:修复DatePickerRange集成与回调逻辑问题

我看了你代码里的问题,主要是几个细节没处理好,导致DatePickerRange没法正常和回调联动。下面一步步给你修正:

关键错误点梳理

  • 组件ID不能有空格:你的Date Picker Range ID包含空格,Dash会无法识别这个组件,需要改成无空格的规范命名
  • 日期过滤逻辑错误:第一个数据过滤的条件里少了逻辑运算符&,导致条件拼接失败
  • 日期过滤顺序错误:第二个图表把日期过滤放在了分组之后,此时数据索引不是日期,loc切片会完全失效
  • 日期类型不匹配:DatePickerRange返回的start_date和end_date是字符串格式,需要转成datetime类型才能和df中已处理的TXN Date比较

修正后的完整代码

import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.express as px
import pandas as pd
import datetime
from dash.dependencies import Input, Output

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

# 读取并预处理数据
df = pd.read_csv(r'DashboardInfo.csv', header=None, names= ['ACR ID', 'Agent ID', 'Agency Code', 'Agreement ID', 'Unit Total', 'TXN Date', 'Product Code', 'Original Unit Quantity', 'Current Unit Quantity', 'Is Escalator', 'Escalator Percentage', 'Primary Sub ID', 'Sub Birthdate', 'Sub Gender', 'Residential ID', 'Province', 'City', 'Postal Code', 'Address 1', 'Address 2', 'Agent Name', 'Branch'])

today_date = datetime.datetime.today().strftime('%Y-%m-%d')
df['TXN Date'] = pd.to_datetime(df['TXN Date'])
# 用数据中的最小/最大日期作为日期选择器默认值,比iloc更可靠
min_date = df['TXN Date'].min()
max_date = df['TXN Date'].max()

app.layout = html.Div(children=[
    html.H1(children='Sales Results Dashboard'),
    html.Div(children=f'''
        Sales Rep Production for {today_date}
    '''),
    dcc.Graph(id='example-graph'),
    dcc.Graph(id='branch-graph'),
    
    # 省份复选框(优化ID命名,更直观)
    html.Label('Select Provinces'),
    dcc.Checklist(
        id='province-checklist',
        options=[
            {'label': x, 'value': x, 'disabled': False} for x in df['Province'].unique()
        ],
        value=['BC','AB','SK','MB','ON','QC','NB','NL','PE','NS']
    ),
    
    # 日期范围选择器(修正ID,指定显示格式)
    html.Label('Select Date Range'),
    dcc.DatePickerRange(
        id='date-picker-range',
        clearable=True,
        start_date=min_date,
        end_date=max_date,
        display_format='YYYY-MM-DD'
    ),
])

@app.callback(
    [Output('example-graph', 'figure'),
     Output('branch-graph', 'figure')],
    [Input('province-checklist', 'value'),
     Input('date-picker-range', 'start_date'),
     Input('date-picker-range', 'end_date')]
)
def update_graph(selected_provinces, start_date, end_date):
    # 将字符串日期转换为datetime类型,匹配df中的日期格式
    start_dt = pd.to_datetime(start_date)
    end_dt = pd.to_datetime(end_date)
    
    # 统一过滤逻辑,避免重复代码
    filtered_df = df[(df['TXN Date'] >= start_dt) & 
                     (df['TXN Date'] <= end_dt) & 
                     (df['Province'].isin(selected_provinces))]
    
    # 第一个图表:按Agent Name汇总销量
    agent_data = filtered_df.groupby('Agent Name', as_index=False)['Unit Total'].sum()
    fig1 = px.bar(agent_data, x='Agent Name', y='Unit Total')
    fig1.update_xaxes(categoryorder='total descending')
    
    # 第二个图表:按Branch汇总销量
    branch_data = filtered_df.groupby('Branch', as_index=False)['Unit Total'].sum()
    fig2 = px.bar(branch_data, x='Branch', y='Unit Total')
    fig2.update_xaxes(categoryorder='total descending')
    
    return fig1, fig2

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

额外优化建议

  • 代码可读性:把过滤逻辑抽成单独的filtered_df变量,后续图表都基于这个数据集,避免重复写过滤条件
  • 日期边界处理:用>=和<=代替>和<,确保包含起止日期的所有数据
  • ID命名规范:尽量用小写加短横线的格式,避免空格和大写,方便后续维护
  • 字符串格式化:用f-string代替传统字符串拼接,代码更简洁易读

这样修改后,你的日期选择器就能正常和回调联动,两个图表都会根据选中的省份和日期范围实时更新了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 06:32:29