Plotly:如何根据链接的下拉值自动更新 DatePickerRange 中的开始日期和结束日期? [英] Plotly: How to update the start date and end date in DatePickerRange automatically based on a chained dropdown value?

查看:53
本文介绍了Plotly:如何根据链接的下拉值自动更新 DatePickerRange 中的开始日期和结束日期?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在回调中自动更新 DatePickerRange 的开始日期和结束日期,其中输入是先前下拉列表的值.我有 2 个链接的下拉列表,我正在做同样的事情来更新第二个相关下拉列表的选项.我尝试对 datepickerRange 做同样的事情,但我似乎找不到一种方法可以从这里的 def 返回开始日期和结束日期:

I want to update the start date and end date automatically for DatePickerRange in the callback where the input is a prior dropdown's value. I have 2 chained dropdowns where I'm doing the same for updating the options of the second dependent dropdown. I tried doing the same for datepickerRange but I can't seem to find a way where I can return the start date and end date from def here:

@app.callback(
    Output(component_id='date_choice', component_property='start_date'),
    Output(component_id='date_choice', component_property='end_date'),
    Input(component_id='release_choice', component_property='value'))
def get_options(date_choice):
    dff = df[df.date2 == date_choice]
    return [{'label': i, 'value': i} for i in dff['date2']]

完整代码如下:

import dash
import datetime as datetime
import plotly.express as px
import pandas as pd
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Output, Input
df = pd.DataFrame({'Unnamed: 0': {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10, 11: 11, 12: 12, 13: 13},
               'Technology': {0: '4G', 1: '4G', 2: 'SM', 3: '5G', 4: 'SM', 5: '4G', 6: 'SM', 7: '5G', 8: '2G', 9: 'SM', 10: '5G', 11: 'SM', 12: 'SM', 13: '4G'},
               'SystemRelease': {0: 'lte22', 1: 'lte22', 2: 'umts22', 3: '5G22', 4: 'umts22A', 5: 'lte18A', 6: 'umts6A', 7: '5G22A', 8: '2G18', 9: 'L22B', 10: '5G22A', 11: 'umts22B', 12: 'L22A', 13: 'lte18A'},
               'Date': {0: '27.09.2022', 1: '26.09.2022', 2: '25.09.2022', 3: '25.09.2022', 4: '24.09.2022', 5: '23.09.2022', 6: '23.09.2022', 7: '23.09.2022', 8: '20.09.2022', 9: '22.09.2022', 10: '22.09.2022', 11: '22.09.2022', 12: '22.09.2022', 13: '22.09.2022'},
               'TypeofRelease': {0: 'Normal Update', 1: 'Standard Update', 2: 'Standard Update', 3: 'Maintenance Delivery', 4: 'Delivery', 5: 'Standard Update', 6: 'Normal Update', 7: 'Delivery', 8: 'Standard Update', 9: 'Delivery', 10: 'Delivery', 11: 'Delivery', 12: 'Delivery', 13: 'Standard Update'},
               'Package': {0: '2.5', 1: '0.3', 2: '0.3', 3: '1.1.2', 4: '1.0', 5: '3.0.7', 6: '01.03.2007', 7: '0.2', 8: '2.3', 9: '1.0', 10: '0.5', 11: '1.0', 12: '1.0.6', 13: '6.0'}})


df['date2'] = [datetime.datetime.strptime(x, '%d.%m.%Y') for x in df['Date'] ]
df.sort_values(by=['date2'], inplace=True)

app = dash.Dash(__name__)
app.title = "Roadmap"

app.layout = html.Div(

children=[

    html.Div(
        children=[
            html.Div(
                children=[
                    html.Div(children='Select Technology:', className="menu-title"),
                    dcc.Dropdown(
                        id='Tech_choice',
                        options=[{'label': x, 'value': x}
                                 for x in df.Technology.unique()],
                        value='4G',
                        clearable=False,
                        className="dropdown",

                    ), ]),
            html.Div(
                children=[
                    html.Div(children="Select Release:", className="menu-title"),
                    dcc.Dropdown(
                        id='release_choice',
                        options=[],
                        clearable=False,
                        className="dropdown",
                    )
                ]
            ),
            html.Div(
                children=[
                    html.Div(children="Select Date:", className="menu-title"),
                    dcc.DatePickerRange(
                        id="date_choice",
                        min_date_allowed=df.date2.min().date(),
                        max_date_allowed=df.date2.max().date(),
                        start_date=df.date2.min().date(),
                        end_date=df.date2.max().date(),
                    )
                ]
            ),
        ],
        className="menu",
    ),
    html.Div(
        children=[
            html.Div(
                children=dcc.Graph(
                    id='my-graph', config={"displayModeBar": False},
                    # style={'overflowY': 'scroll', 'width': 1000}
                ),
                className="card",
            ),
        ],
        className="wrapper",
    ), ])

@app.callback(
    Output(component_id='release_choice', component_property='options'),
    Input(component_id='Tech_choice', component_property='value'))
def get_options(Tech_choice):
    dff = df[df.Technology == Tech_choice]
    return [{'label': i, 'value': i} for i in dff['SystemRelease'].unique()]

@app.callback(
    Output(component_id='release_choice', component_property='value'),
    Input(component_id='release_choice', component_property='options'))
def get_values(release_choice):
    return [k['value'] for k in release_choice][1]

@app.callback(
    Output(component_id='date_choice', component_property='start_date'),
    Output(component_id='date_choice', component_property='end_date'),
    Input(component_id='release_choice', component_property='value'))
def get_options(date_choice):
    dff = df[df.date2 == date_choice]  # doubt
    return [{'label': i, 'value': i} for i in dff['date2']]


@app.callback(Output(component_id='my-graph', component_property='figure'),
              [Input(component_id='release_choice', component_property='value')],
              [Input(component_id='Tech_choice', component_property='value')],
              [Input(component_id='date_choice', component_property='start_date')],
              [Input(component_id='date_choice', component_property='end_date')], )
def int_gr(release_choice, Tech_choice, start_date, end_date):
    print(Tech_choice)
    print(release_choice)
    dff = df[(df['SystemRelease'] == release_choice) & (df['Technology'] == Tech_choice) & (df['date2'] >= start_date) & (df['date2'] <= end_date)]
    fig = px.scatter(data_frame=dff, x='date2', y='SystemRelease', color="TypeofRelease", text='Package',
                     labels={
                         "SystemRelease": "System Release",
                         "date2": "Date",
                         "TypeofRelease": "Type of Release:"
                     })
    fig.update_traces(marker=dict(size=12,
                                  line=dict(width=2,
                                            color='DarkSlateGrey')),

                  selector=dict(mode='markers'))
# fig.update_traces(boxpoints='all', jitter=0.8)
fig.update_traces(textposition='top center', mode='markers+text')

fig.update_layout(
    autosize=False,
    width=1200,
    height=400)

return fig

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

快速浏览一下数据:

推荐答案

这里发生了很多事情,我不能保证生成的应用程序将完全符合您的目标.但您似乎在这里犯的唯一错误是:

There's a lot going on here, and I can't guarantee that the resulting app will do exactly what you're aimiing for. But the only error you seem to be making here is:

输入参数 Tech_choice.value 必须是一个列表或元组dash.dependencies.Inputs.

The input argument Tech_choice.value must be a list or tuple of dash.dependencies.Inputs.

这说明您的回调必须设置为:

And what this is telling is that your callback has to be set up as:

@app.callback(
    Output(component_id='release_choice', component_property='options'),
    [Input(component_id='Tech_choice', component_property='value')])

代替:

@app.callback(
    Output(component_id='release_choice', component_property='options'),
    Input(component_id='Tech_choice', component_property='value'))

前者的 Input 用方括号括起来,因此是列表中的一个元素,而后者是您尝试过的.你在更远的地方做一些事情:

Where the former has Input enclosed by square brackets and is therefore an element in a list, while the latter is what you've tried. You're on to something a bit further down where you've got:

@app.callback(Output(component_id='my-graph', component_property='figure'),
              [Input(component_id='release_choice', component_property='value')],
              [Input(component_id='Tech_choice', component_property='value')],
              [Input(component_id='date_choice', component_property='start_date')],
              [Input(component_id='date_choice', component_property='end_date')], )

但是这里您已经将 Input 组件设置为 列表列表 而不仅仅是一个列表,因此这将失败也.这可能有点令人困惑,因为 Input 必须是列表的元素,而 Output 不是.但这仅适用于您的回调具有单个 Output 的情况.无论如何,如果你解决了这些问题.还要注意什么可能是缩进错误,这些错误只会出现在您的代码示例中,而不是您正在使用的代码中,即:

But here you've set up your Input components as a list of lists instead of just a list, and so that will fail too. This can all be a bit confusing since Input has to be an element of a list, while Output does not. But that only applies to cases where your callbacks has a single Output. Anyway, if you fix these things. And also take care of what might be indentation errors that only occur in your code sample and not the code you're working with, namely these:

    fig.update_traces(marker=dict(size=12,
                                  line=dict(width=2,
                                            color='DarkSlateGrey')),

                  selector=dict(mode='markers'))
# fig.update_traces(boxpoints='all', jitter=0.8)
fig.update_traces(textposition='top center', mode='markers+text')

fig.update_layout(
    autosize=False,
    width=1200,
    height=400)

return fig

然后你就会得到这个看似有效的应用:

Then you'll end up with this seemingly working app:

现在,我很难知道这是否完全符合您的目标,但请告诉我它对您的效果如何!

Now, whether or not this does exactly what you're aiming for isn't easy for me to know, but please let me know how it works out for you!

import dash
import datetime as datetime
import plotly.express as px
import pandas as pd
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Output, Input
df = pd.DataFrame({'Unnamed: 0': {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10, 11: 11, 12: 12, 13: 13},
               'Technology': {0: '4G', 1: '4G', 2: 'SM', 3: '5G', 4: 'SM', 5: '4G', 6: 'SM', 7: '5G', 8: '2G', 9: 'SM', 10: '5G', 11: 'SM', 12: 'SM', 13: '4G'},
               'SystemRelease': {0: 'lte22', 1: 'lte22', 2: 'umts22', 3: '5G22', 4: 'umts22A', 5: 'lte18A', 6: 'umts6A', 7: '5G22A', 8: '2G18', 9: 'L22B', 10: '5G22A', 11: 'umts22B', 12: 'L22A', 13: 'lte18A'},
               'Date': {0: '27.09.2022', 1: '26.09.2022', 2: '25.09.2022', 3: '25.09.2022', 4: '24.09.2022', 5: '23.09.2022', 6: '23.09.2022', 7: '23.09.2022', 8: '20.09.2022', 9: '22.09.2022', 10: '22.09.2022', 11: '22.09.2022', 12: '22.09.2022', 13: '22.09.2022'},
               'TypeofRelease': {0: 'Normal Update', 1: 'Standard Update', 2: 'Standard Update', 3: 'Maintenance Delivery', 4: 'Delivery', 5: 'Standard Update', 6: 'Normal Update', 7: 'Delivery', 8: 'Standard Update', 9: 'Delivery', 10: 'Delivery', 11: 'Delivery', 12: 'Delivery', 13: 'Standard Update'},
               'Package': {0: '2.5', 1: '0.3', 2: '0.3', 3: '1.1.2', 4: '1.0', 5: '3.0.7', 6: '01.03.2007', 7: '0.2', 8: '2.3', 9: '1.0', 10: '0.5', 11: '1.0', 12: '1.0.6', 13: '6.0'}})


df['date2'] = [datetime.datetime.strptime(x, '%d.%m.%Y') for x in df['Date'] ]
df.sort_values(by=['date2'], inplace=True)

app = dash.Dash(__name__)
app.title = "Roadmap"

app.layout = html.Div(

children=[

    html.Div(
        children=[
            html.Div(
                children=[
                    html.Div(children='Select Technology:', className="menu-title"),
                    dcc.Dropdown(
                        id='Tech_choice',
                        options=[{'label': x, 'value': x}
                                 for x in df.Technology.unique()],
                        value='4G',
                        clearable=False,
                        className="dropdown",

                    ), ]),
            html.Div(
                children=[
                    html.Div(children="Select Release:", className="menu-title"),
                    dcc.Dropdown(
                        id='release_choice',
                        options=[],
                        clearable=False,
                        className="dropdown",
                    )
                ]
            ),
            html.Div(
                children=[
                    html.Div(children="Select Date:", className="menu-title"),
                    dcc.DatePickerRange(
                        id="date_choice",
                        min_date_allowed=df.date2.min().date(),
                        max_date_allowed=df.date2.max().date(),
                        start_date=df.date2.min().date(),
                        end_date=df.date2.max().date(),
                    )
                ]
            ),
        ],
        className="menu",
    ),
    html.Div(
        children=[
            html.Div(
                children=dcc.Graph(
                    id='my-graph', config={"displayModeBar": False},
                    # style={'overflowY': 'scroll', 'width': 1000}
                ),
                className="card",
            ),
        ],
        className="wrapper",
    ), ])

@app.callback(
    Output(component_id='release_choice', component_property='options'),
    [Input(component_id='Tech_choice', component_property='value')])
def get_options(Tech_choice):
    dff = df[df.Technology == Tech_choice]
    return [{'label': i, 'value': i} for i in dff['SystemRelease'].unique()]

@app.callback(
    Output(component_id='release_choice', component_property='value'),
    [Input(component_id='release_choice', component_property='options')])
def get_values(release_choice):
    return [k['value'] for k in release_choice][1]

@app.callback(
    [Output(component_id='date_choice', component_property='start_date'),
    Output(component_id='date_choice', component_property='end_date')],
    [Input(component_id='release_choice', component_property='value')])
def get_options(date_choice):
    dff = df[df.date2 == date_choice]  # doubt
    return [{'label': i, 'value': i} for i in dff['date2']]


@app.callback(Output(component_id='my-graph', component_property='figure'),
              [Input(component_id='release_choice', component_property='value'),
              Input(component_id='Tech_choice', component_property='value'),
              Input(component_id='date_choice', component_property='start_date'),
              Input(component_id='date_choice', component_property='end_date')], )
def int_gr(release_choice, Tech_choice, start_date, end_date):
    print(Tech_choice)
    print(release_choice)
    dff = df[(df['SystemRelease'] == release_choice) & (df['Technology'] == Tech_choice) & (df['date2'] >= start_date) & (df['date2'] <= end_date)]
    fig = px.scatter(data_frame=dff, x='date2', y='SystemRelease', color="TypeofRelease", text='Package',
                     labels={
                         "SystemRelease": "System Release",
                         "date2": "Date",
                         "TypeofRelease": "Type of Release:"
                     })
    fig.update_traces(marker=dict(size=12,
                                  line=dict(width=2,
                                            color='DarkSlateGrey')),

                  selector=dict(mode='markers'))
    # fig.update_traces(boxpoints='all', jitter=0.8)
    fig.update_traces(textposition='top center', mode='markers+text')

    fig.update_layout(
        autosize=False,
        width=1200,
        height=400)

    return fig

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

这篇关于Plotly:如何根据链接的下拉值自动更新 DatePickerRange 中的开始日期和结束日期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆