Reputation: 149
I am trying to get the dependency between a slider, user input and a table to work. I have tried outputting the data and using a callback to update it. I was advised to just create the table in a callback and just use a "Div." to define its location in the display.
other info:
threshold
being the value adjusted by user input (slider or input)I would be grateful if someone could help me find out why the table is not displaying?
Here is my code:
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()
Upvotes: 8
Views: 15589
Reputation: 2951
[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)
I tried this out & seems to be working w/ slightly modified code above; the changes I had to make were:
table_data
into a dataframe (this allows the .to_dict()
method which is a pd.DataFrame method to work!) 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],
}
)
Also in update_output
callback fxn:
id
Dash param here, b/c it's already in the layout return html.Div(
[
dash_table.DataTable(
data=table_data.to_dict("rows"),
columns=[{"id": x, "name": x} for x in table_data.columns],
)
]
)
html.Div(
dcc.Input(
id="input-box",
max=1.00,
min=0.00,
step=0.01,
value=threshold,
type="number"
)
),
Upvotes: 8