Dash DatePickerRange 与图表

Dash DatePickerRange with Graph

我正在尝试将图形连接到 DatePickerRange。但是,在尝试连接图表和日期选择器时,我一直 运行 陷入困境。我有以下代码:

import dash
import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
from datetime import datetime
import plotly.graph_objs as go
import plotly.express as px

controls = dbc.FormGroup(
    [
        html.P('Pick Date', style={
            'textAlign': 'center'
        }),
        dcc.DatePickerRange(
            id = "date-picker",
            start_date = datetime(2021,1,1),
            end_date = datetime.today(),
            display_format='MMMM Y, DD'
        ),

        html.Br(),
        dbc.Button(
            id='submit_button',
            n_clicks=0,
            children='Submit',
            color='primary',
            block=True
        ),
    ]
)

content_second_row = dbc.Row(
    [

        dbc.Col(
            dcc.Graph(id='graph_2'), md=4
        )
    ]
)

@app.callback(
    Output('graph_2', 'figure'),
    [Input('date-picker', 'start_date'),
    Input('date-picker', 'end_date')],
    [State('submit_button', 'n_clicks')])
def update_graph_2(n_clicks, start_date, end_date):
    fig = {
        'data': [{
            'x':  dfEconomic[(dfEconomic['Date']>start_date)&(dfEconomic['Date']<end_date)],
            'y': dfEconomic["Amount [DKK]"],
            'type': 'bar'
        }]
    }

    return fig

我尝试使用以下代码将日期值转换为日期帧:


for i in range(len(dfEconomic["Date"])):
    if isinstance(dfEconomic["Date"][i], str) == True:
        dfEconomic["Date"] =  datetime.strptime(dfEconomic["Date"][i], "%Y-%m-%d")

但这对情况没有帮助。我收到以下错误消息:

TypeError: invalid type comparison

任何人都可以帮助我了解需要更改的内容吗?

The dataframe looks the following

  • 模拟数据框并构造了一个 破折号 布局以使您的代码可运行
  • 三个核心问题
    1. 回调 的参数顺序错误。 n_clicks 是最后一个参数
    2. 使用 pd.to_datetime() 将字符串值转换为 datetime64[ns]。创建了一个列表,然后可以用作 *argsbetween()
    3. 需要过滤xy所以用了一个局部变量df
import dash
import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
from datetime import datetime
import plotly.graph_objs as go
import plotly.express as px
import pandas as pd
import numpy as np
from jupyter_dash import JupyterDash

app = JupyterDash(__name__)

dfEconomic = pd.DataFrame({"Date": pd.date_range("1-jan-2021", "today")}).assign(
    **{"Amount [DKK]": lambda d: np.random.uniform(10, 200, len(d))}
)

controls = dbc.FormGroup(
    [
        html.P("Pick Date", style={"textAlign": "center"}),
        dcc.DatePickerRange(
            id="date-picker",
            start_date=datetime(2021, 1, 1),
            end_date=datetime.today(),
            display_format="MMMM Y, DD",
        ),
        html.Br(),
        dbc.Button(
            id="submit_button",
            n_clicks=0,
            children="Submit",
            color="primary",
            block=True,
        ),
    ]
)

content_second_row = dbc.Row([dbc.Col(dcc.Graph(id="graph_2"), md=4)])

app.layout = html.Div([controls, content_second_row])


@app.callback(
    Output("graph_2", "figure"),
    [Input("date-picker", "start_date"), Input("date-picker", "end_date")],
    [State("submit_button", "n_clicks")],
)
def update_graph_2(start_date, end_date, n_clicks):
    df = dfEconomic.loc[dfEconomic["Date"].between(*pd.to_datetime([start_date, end_date]))]
    fig = {"data": [{"x": df["Date"], "y": df["Amount [DKK]"], "type": "bar"}]}

    return fig


if __name__ == "__main__":
    #     app.run_server(debug=True)
    app.run_server(mode="inline")

这可能对那些在使用破折号 DatePickerRange 及其关联的回调函数时遇到此问题的人有用。

破折号回调函数读取 DatePickerRange 组件的开始和结束日期作为字符串。因此,通过将列中的日期值与 DatePickerRange 中的开始和结束数据值进行比较来切片 pandas 数据框时会出现错误。

按照以下步骤确保日期类型匹配并且您的回调函数按预期工作:

  1. 确保您要筛选的列的数据类型是 datetime.date 类型。您可以通过添加此代码来实现 - dfEconomic['Date'] = pd.to_datetime(dfEconomic['Date']).dt.date

  2. 然后在回调函数中转换来自DatePickerRange的start_dateend_date的数据类型-

start_date = datetime.datetime.strptime(start_date, '%Y-%m-%d').date() 
end_date = datetime.datetime.strptime(opp_end_date, '%Y-%m-%d').date()

因此,更新后的回调函数应如下所示:

import datetime

@app.callback(
    Output('graph_2', 'figure'),
    [Input('date-picker', 'start_date'),
    Input('date-picker', 'end_date')],
    [State('submit_button', 'n_clicks')])
def update_graph_2(n_clicks, start_date, end_date):
    dfEconomic['Date'] = pd.to_datetime(dfEconomic['Date']).dt.date
    start_date = datetime.datetime.strptime(start_date, '%Y-%m-%d').date() 
    end_date = datetime.datetime.strptime(opp_end_date, '%Y-%m-%d').date()
    fig = {
        'data': [{
            'x':  dfEconomic[(dfEconomic['Date']>start_date)&(dfEconomic['Date']<end_date)],
            'y': dfEconomic["Amount [DKK]"],
            'type': 'bar'
        }]
    }

    return fig

您可以根据需要随意调整日期时间对象的格式。