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

Dash日期范围选择器无图表显示问题求助及代码排查

问题描述

在Jupyter Notebook中使用Dash开发日期范围选择器功能,但图表无法正常显示,使用NYC交通事故数据集,原代码如下:

collisions = (
    pd.read_csv("NYC_Collisions.csv")
    .astype({"ACCIDENT_DATE": "datetime64[ns]"})
    .loc[:,["ACCIDENT_DATE", "BOROUGH", "COLLISION_ID"]]
    .groupby(["ACCIDENT_DATE", "BOROUGH"], as_index=False)
    .count()
    .rename(columns={
        "COLLISION_ID":"COLLISIONS", 
        "ACCIDENT_DATE":"DATE"})  
)

collisions.head()

from datetime import datetime
from datetime import date

app = Dash(__name__)


app.layout = html.Div([
    dcc.DatePickerRange(
        id="date picker",
        min_date_allowed=collisions["DATE"].min(),
        max_date_allowed=collisions["DATE"].max(),
        initial_visible_month=collisions["DATE"].max(),
        start_date=collisions["DATE"].min(),
        end_date=date(2022,1,1),
    ),
    dcc.Graph(id="graph")
])

@app.callback(Output("graph", "figure"),
              [Input("date picker", "start_date"),
               Input("date picker", "end_date"),])
def plot_collisions_bar(start_date, end_date):
    fig = px.bar(
        (collisions
         .loc[collisions["DATE"].between(start_date, end_date)]
         .groupby("BOROUGH", as_index=False)
         .sum()
        )
        ,
        x="COLLISIONS",
        y="BOROUGH",
        title=f"Traffic Accidents in NYC between {start_date[:10]} and {end_date[:10]}"
    )
    return fig

if __name__ == "__main__":
    app.run_server(mode="inline", port=8001, width="60%")
错误排查与修复要点
  • 日期类型不匹配:dcc.DatePickerRange返回的start_date/end_date是字符串格式,而数据集的DATE列是datetime64[ns]类型,直接用between比较会筛选不到数据,导致图表为空。需将字符串日期转为datetime格式后再做筛选。
  • 组件ID含空格:id="date picker"包含空格,虽Dash允许,但可能引发回调匹配的潜在问题,建议改为"date-picker"这类无空格命名。
  • 初始日期类型不一致:start_date用了Pandas datetime对象,end_date用了Python原生date对象,统一类型可避免兼容性问题。
  • 无数据处理:添加空数据判断,避免因筛选后无数据导致图表报错。
修正后的完整代码
import pandas as pd
import plotly.express as px
from dash import Dash, html, dcc, Input, Output
from datetime import date

# 数据预处理
collisions = (
    pd.read_csv("NYC_Collisions.csv")
    .astype({"ACCIDENT_DATE": "datetime64[ns]"})
    .loc[:,["ACCIDENT_DATE", "BOROUGH", "COLLISION_ID"]]
    .groupby(["ACCIDENT_DATE", "BOROUGH"], as_index=False)
    .count()
    .rename(columns={
        "COLLISION_ID":"COLLISIONS", 
        "ACCIDENT_DATE":"DATE"})  
)

# 初始化Dash应用
app = Dash(__name__)

app.layout = html.Div([
    dcc.DatePickerRange(
        id="date-picker",
        min_date_allowed=collisions["DATE"].min(),
        max_date_allowed=collisions["DATE"].max(),
        initial_visible_month=collisions["DATE"].max(),
        start_date=collisions["DATE"].min().date(),
        end_date=date(2022,1,1),
    ),
    dcc.Graph(id="graph")
])

@app.callback(
    Output("graph", "figure"),
    [Input("date-picker", "start_date"),
     Input("date-picker", "end_date")]
)
def plot_collisions_bar(start_date, end_date):
    # 转换日期格式,匹配数据集类型
    start_dt = pd.to_datetime(start_date)
    end_dt = pd.to_datetime(end_date)
    
    filtered_data = collisions.loc[collisions["DATE"].between(start_dt, end_dt)]
    
    # 处理空数据场景
    if filtered_data.empty:
        return px.bar(title="该日期范围内无事故数据")
    
    aggregated_data = filtered_data.groupby("BOROUGH", as_index=False).sum()
    
    fig = px.bar(
        aggregated_data,
        x="COLLISIONS",
        y="BOROUGH",
        orientation="h",
        title=f"Traffic Accidents in NYC between {start_date[:10]} and {end_date[:10]}"
    )
    return fig

if __name__ == "__main__":
    app.run_server(mode="inline", port=8001, width="60%")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 23:30:03