Подключение выпадающего списка и радиоэлементов в тире

#python #callback #plotly-dash

Вопрос:

Я новичок в Dash и пытаюсь подключиться dcc.Dropdown и dcc.RadioItems собрать компоненты. Для этой цели я создал этот очень упрощенный пример приложения Dash, в котором я хочу разрешить пользователю выбирать диаграмму (выпадающее меню) на основе предыдущего выбора ввода (радиоэлементов). Мой код отлично работает с точки зрения функциональности, но я не уверен, что в данном случае это правильный способ использования функции обратного вызова. Пожалуйста, найдите код ниже:

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

data = {'date': [10, 5, 7, 11], 'column1': [15, 4, 8, 5], 'column2': [1, 2, 3, 9], 'column3': [1.5, 2.5, 3.5, 0.5]}
df = pd.DataFrame(data)
app = dash.Dash(__name__)

show_columns = ['column1', 'column2', 'column3']

app.layout = html.Div(children=[
    html.H1(children='Columns visualisation'),
    html.Div([
        html.Div(
            dcc.RadioItems(
                id='radio_items',
                options=[{'label': i, 'value': i} for i in show_columns],
                value='column1',
                labelStyle={'display': 'inline-block'}
            ),
        ),
        dcc.Dropdown(
            id='dropdown',
            options=[
                {'label': 'Line Chart', 'value': 'v1'},
                {'label': 'Bar Chart', 'value': 'v2'}
            ],
            value='v1',
         ),

        html.Div(dcc.Graph(id='graph')),
    ]),
])


@app.callback(
    Output('graph', 'figure'),
    Input('radio_items', 'value'),
    Input('dropdown', 'value')
)
def update_output(item, value):
    if item == 'column1':
        try:
            if value is None:
                raise PreventUpdate
            elif value == 'v1':
                fig = px.line(df, x=df.date, y=df.column1)
                return fig
            elif value == 'v2':
                fig1 = px.bar(df, x=df.date, y=df.column1)
                return fig1
        except ValueError:
            return None
    if item == 'column2':
        try:
            if value is None:
                raise PreventUpdate
            elif value == 'v1':
                fig = px.line(df, x=df.date, y=df.column2)
                return fig
            elif value == 'v2':
                fig1 = px.bar(df, x=df.date, y=df.column2)
                return fig1
        except ValueError:
            return None
    else:
        try:
            if value is None:
                raise PreventUpdate
            elif value == 'v1':
                fig = px.line(df, x=df.date, y=df.column3)
                return fig
            elif value == 'v2':
                fig1 = px.bar(df, x=df.date, y=df.column3)
                return fig1
        except ValueError:
            return None


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

Я хотел бы знать, есть ли более элегантный способ настроить мою update_output функцию?

Делается ли это вообще таким образом?

Я был бы признателен за любую помощь. Заранее спасибо

Ответ №1:

Я думаю, что проверки в вашем примере не нужны.

Вы можете напрямую выбирать части своих данных, используя значения, полученные при обратном вызове.

Вы можете создать словарь типов диаграмм , который содержит "v1" "v2" в качестве ключей. Значения в словаре могут соответствовать функции построения, используемой для данного ключа:

 charts = {"v1": px.line, "v2": px.bar}
 

Тогда вы могли бы изменить свой обратный вызов на этот:

 @app.callback(
    Output("graph", "figure"), Input("radio_items", "value"), Input("dropdown", "value")
)
def update_output(item, chart_type):
    if chart_type is None:
        raise PreventUpdate

    return charts[chart_type](df, x=df.date, y=df[item])
 

На самом деле вам также не нужна инструкция if , которая проверяет, соответствует ли выбранный тип диаграммы None , потому что вы уже установили значение по умолчанию в своем layout , поэтому выпадающее значение никогда не будет None :

 @app.callback(
    Output("graph", "figure"), Input("radio_items", "value"), Input("dropdown", "value")
)
def update_output(item, chart_type):
    return charts[chart_type](df, x=df.date, y=df[item])
 

Комментарии:

1. Я знал, что было много ненужных и неправильных линий, но я не знал, как это решить. Спасибо за вашу помощь.