【问题标题】:Plotly Dash table callbackPlotly Dash 表回调
【发布时间】:2020-03-07 07:47:21
【问题描述】:

我试图让滑块、用户输入和表格之间的依赖关系起作用。我试过输出数据并使用回调来更新它。有人建议我只在回调中创建表并使用“Div”。定义其在显示中的位置。

其他信息:

  • 表是使用 dash_table 库从 pandas DataFrame 创建的。
  • 数据为字典格式。
  • 变量threshold 是由用户输入(滑块或输入)调整的值

如果有人能帮我找出表格不显示的原因,我将不胜感激?

这是我的代码:


import dash
import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
from dash.dependencies import Input, Output
import dash_table

threshold = 0.5
################################################################
###################### Table Data ##############################
################################################################

metrics_index = ["AUC", "Accuracy", "Kappa", "Sensitivity (Recall)", "Specificity", "Precision", "F1"]

algo_columns = ["Test-SVM+Naïve B", "RF"]

table_data = {"AUC": [threshold * 0.8, threshold * 0.83],
              "Accuracy": [threshold * 0.85, threshold * 0.86],
              "Kappa": [threshold * 0.66, threshold * 0.69],
              "Sensitivity (Recall)": [threshold * 0.82, threshold * 0.83],
              "Specificity": [threshold * 0.78, threshold * 0.79],
              "Precision": [threshold * 0.78, threshold * 0.79],
              "F1": [threshold * 0.81, threshold * 0.82]}

data = [i for i in table_data]
table = pd.DataFrame(columns=algo_columns, index=metrics_index, data=[table_data[i] for i in metrics_index])
# display(table)


################################################################
########################  Body  ################################
################################################################


body = dbc.Container(
    [
        dbc.Row(
            [
                dbc.Col(
                    [
                        html.H2("Slider + Manual entry test"),
                        dcc.Slider(
                            id='my-slider',
                            min=0,
                            max=1,
                            step=0.01,
                            marks={"0": "0", "0.5": "0.5", "1": "1"},
                            value=threshold
                        ),
                        html.Div(id='update-table')
                    ]
                ),
                dbc.Col(
                    [
                        html.Div(
                            [
                                html.Div(
                                    dcc.Input(id='input-box', type='float', max=0, min=1, step=0.01, value=threshold)
                                    ),
                                 html.Div(id='slider-output-container')
                            ]
                        )
                    ]
                )
            ]
        )
    ]
)

app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])

app.layout = html.Div([body])


##############################################################
######################## callbacks ###########################
##############################################################

@app.callback(
    dash.dependencies.Output('slider-output-container', 'children'),
    [dash.dependencies.Input('my-slider', 'value')]
)
def update_output(value):
    threshold = float(value)
    return threshold


# call back for slider to update based on manual input
@app.callback(
    dash.dependencies.Output(component_id='my-slider', component_property='value'),
    [dash.dependencies.Input('input-box', 'value')]
)
def update_output(value):
    threshold = float(value)
    return threshold


# call back to update table

@app.callback(
    dash.dependencies.Output('update-table', 'children'),
    [dash.dependencies.Input('my-slider', 'value')]
)
def update_output(value):
    threshold = float(value)
    table_data = {"AUC": [threshold * 0.8, threshold * 0.83],
                  "Accuracy": [threshold * 0.85, threshold * 0.86],
                  "Kappa": [threshold * 0.66, threshold * 0.69],
                  "Sensitivity (Recall)": [threshold * 0.82, threshold * 0.83],
                  "Specificity": [threshold * 0.78, threshold * 0.79],
                  "Precision": [threshold * 0.78, threshold * 0.79],
                  "F1": [threshold * 0.81, threshold * 0.82]}


    return dash_table.DataTable(
                            id='update-table',
                            data= table_data.to_dict('records'),
                            columns=[{'id': x, 'name': x} for x in table.columns]
                )


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

【问题讨论】:

    标签: python callback plotly-dash


    【解决方案1】:

    [screenshot of table live dynamic editing]

    import dash
    import dash_bootstrap_components as dbc
    import dash_core_components as dcc
    import dash_html_components as html
    import dash_table
    import pandas as pd
    
    from dash.dependencies import Input, Output
    
    threshold = 0.5
    ################################################################
    ###################### Table Data ##############################
    ################################################################
    
    metrics_index = [
        "AUC",
        "Accuracy",
        "Kappa",
        "Sensitivity (Recall)",
        "Specificity",
        "Precision",
        "F1",
    ]
    
    algo_columns = ["Test-SVM+Naïve B", "RF"]
    
    table_data = {
        "AUC": [threshold * 0.8, threshold * 0.83],
        "Accuracy": [threshold * 0.85, threshold * 0.86],
        "Kappa": [threshold * 0.66, threshold * 0.69],
        "Sensitivity (Recall)": [threshold * 0.82, threshold * 0.83],
        "Specificity": [threshold * 0.78, threshold * 0.79],
        "Precision": [threshold * 0.78, threshold * 0.79],
        "F1": [threshold * 0.81, threshold * 0.82],
    }
    
    data = [i for i in table_data]
    table = pd.DataFrame(
        columns=algo_columns,
        index=metrics_index,
        data=[table_data[i] for i in metrics_index],
    )
    # display(table)
    
    
    ################################################################
    ########################  Body  ################################
    ################################################################
    
    
    body = dbc.Container(
        [
            dbc.Row(
                [
                    dbc.Col(
                        [
                            html.H2("Slider + Manual entry test"),
                            dcc.Slider(
                                id="my-slider",
                                min=0,
                                max=1,
                                step=0.01,
                                marks={"0": "0", "0.5": "0.5", "1": "1"},
                                value=threshold,
                            ),
                            html.Div(id="update-table"),
                        ]
                    ),
                    dbc.Col(
                        [
                            html.Div(
                                [
                                    html.Div(
                                        dcc.Input(
                                            id="input-box",
                                            max=0,
                                            min=1,
                                            step=0.01,
                                            value=threshold,
                                        )
                                    ),
                                    html.Div(id="slider-output-container"),
                                ]
                            )
                        ]
                    ),
                ]
            )
        ]
    )
    
    app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
    
    app.layout = html.Div([body])
    
    
    ##############################################################
    ######################## callbacks ###########################
    ##############################################################
    
    
    @app.callback(
        dash.dependencies.Output("slider-output-container", "children"),
        [dash.dependencies.Input("my-slider", "value")],
    )
    def update_output(value):
        threshold = float(value)
        return threshold
    
    
    # call back for slider to update based on manual input
    @app.callback(
        dash.dependencies.Output(component_id="my-slider", component_property="value"),
        [dash.dependencies.Input("input-box", "value")],
    )
    def update_output(value):
        threshold = float(value)
        return threshold
    
    
    # call back to update table
    
    
    @app.callback(
        dash.dependencies.Output("update-table", "children"),
        [dash.dependencies.Input("my-slider", "value")],
    )
    def update_output(value):
        threshold = float(value)
        table_data = pd.DataFrame.from_dict(
            {
                "AUC": [threshold * 0.8, threshold * 0.83],
                "Accuracy": [threshold * 0.85, threshold * 0.86],
                "Kappa": [threshold * 0.66, threshold * 0.69],
                "Sensitivity (Recall)": [threshold * 0.82, threshold * 0.83],
                "Specificity": [threshold * 0.78, threshold * 0.79],
                "Precision": [threshold * 0.78, threshold * 0.79],
                "F1": [threshold * 0.81, threshold * 0.82],
            }
        )
    
        return html.Div(
            [
                dash_table.DataTable(
                    data=table_data.to_dict("rows"),
                    columns=[{"id": x, "name": x} for x in table_data.columns],
                )
            ]
        )
    
    
    if __name__ == "__main__":
        app.run_server(host="0.0.0.0", port=8050, debug=True, dev_tools_hot_reload=True)
    
    

    我试过了,似乎上面的代码稍微修改了一下;我必须做出的改变是:

    1. 将 dict table_data 转换为数据帧(这允许作为 pd.DataFrame 方法的 .to_dict() 方法工作!)
        table_data = pd.DataFrame.from_dict(
            {
                "AUC": [threshold * 0.8, threshold * 0.83],
                "Accuracy": [threshold * 0.85, threshold * 0.86],
                "Kappa": [threshold * 0.66, threshold * 0.69],
                "Sensitivity (Recall)": [threshold * 0.82, threshold * 0.83],
                "Specificity": [threshold * 0.78, threshold * 0.79],
                "Precision": [threshold * 0.78, threshold * 0.79],
                "F1": [threshold * 0.81, threshold * 0.82],
            }
        )
    
    1. 同样在update_output回调fxn:

      • A.将 df .to_dict 方法调用的“记录”更改为“行”
      • 乙。你有 table 而不是 table_data 列参数
      • C.在此处删除 id Dash 参数的使用,b/c 它已经在布局中
        return html.Div(
            [
                dash_table.DataTable(
                    data=table_data.to_dict("rows"),
                    columns=[{"id": x, "name": x} for x in table_data.columns],
                )
            ]
        )
    
    
    1. 看起来你已经切换了最大值和最小值! (最大零不会留下很多可能的输入![实际上,没有..]);为了以防万一,我添加的小数和匹配精度也可能很重要。
                                    html.Div(
                                        dcc.Input(
                                            id="input-box",
                                            max=1.00,
                                            min=0.00,
                                            step=0.01,
                                            value=threshold,
                                            type="number"
                                        )
                                    ),
    

    【讨论】:

    • 非常感谢您提供简洁明了的回答。我已经坚持了 2 天
    猜你喜欢
    • 2020-03-17
    • 1970-01-01
    • 2021-06-07
    • 2021-09-10
    • 2021-05-22
    • 1970-01-01
    • 2020-08-12
    • 1970-01-01
    • 2021-02-25
    相关资源
    最近更新 更多