4

As titled, i am creating a plotly dashboard with a data-table only. There will be 2 drop-downs as inputs, and the data-table will update according to the drown-downs. How do I set the layout and callbacks?

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

df = pd.read_csv(data, header=0, encoding = 'utf8')

app = dash.Dash()
application = app.server

dropdown = html.Div([html.Label('district'),
             dcc.Dropdown(id='dropdown_d',
                          options=[{'label': i, 'value': i} for i in df["district"].unique()], value='none'),
             html.Label('address'),
             dcc.Dropdown(id='dropdown_a',
                          options=[{'label': i, 'value': i} for i in df["address"].unique()], value='none')])

final_table = html.Div([dash_table.DataTable(id="final_table")])

app.layout = html.Div([dropdown, final_table])

@app.callback(Output('final_table', 'data'),
          [Input('dropdown_d', 'value'),
           ])

def update_table(selected_value):
    df = pd.read_csv(data, header=0, encoding = 'utf8')
    df_updated = df[df["district"] == selected_value]
    columns = [{'name': i, 'id': i} for i in df_updated.columns]
    data = df.to_dict('records')
    return columns, data

if __name__ == "__main__":
    app.run_server(debug=True, port=8055)

This is the farthest i can get. The code above is only trying to update the data-table from 1 dropdown value, but my goal is to update by 2 dropdown values.

any help is very much appreciated. in case the data file is needed, here is the link to the data.

1 Answer 1

3

Here is the snippet of the working code, I have added comments for clarification,

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

df = pd.read_csv("https://elartedm.com/wp-content/uploads/2020/03/data_hk.csv", header=0, encoding = 'utf8')

app = dash.Dash()
application = app.server

dropdown = html.Div([
    html.Label('district'),
    dcc.Dropdown(id='dropdown_d1', options=[{'label': i, 'value': i} for i in df["District"].unique()], value=None),
    html.Label('address'),
    dcc.Dropdown(id='dropdown_d2', options=[], value=None)
])


#its better to have a Div here so that you can update the entire div in the callback and add the necessary properties in the callback
final_table = html.Div(id="final_table")

app.layout = html.Div([dropdown, final_table])


#callback to update second dropdown based on first dropdown
#This callback is used to update the second dropdown based on the value selected in the first dropdown so that its dynamically updated (this is a good  practice rather than having a static list of options).
@app.callback(Output('dropdown_d2', 'options'),
          [
            Input('dropdown_d1', 'value'),
          ])
def update_dropdown_2(d1):
    print(d1)
    if(d1 != None):
        df_filtered = df[(df["District"]==d1)]
        return [{'label': i, 'value': i} for i in df_filtered["Address"].unique()]
    else:
        return []


#this callback to update the final table should be based on both the input dropdown values, so the input parameters are two dropdown_d1, dropdown_d2
#based on these values filter the dataframe and update the table
#since dataframe is a global declaration you don't need to again consume it here.
@app.callback(Output('final_table', 'children'),
          [
            Input('dropdown_d1', 'value'),
            Input('dropdown_d2', 'value'),
          ])
def update_table(d1, d2):

    if(d1 != None and d2 != None):
        df_filtered = df[(df["District"]==d1) & (df["Address"]==d2)]

        return [dt.DataTable(
            id='table',
            columns=[{"name": i, "id": i} for i in df_filtered.columns],
            data=df_filtered.to_dict('records'),
        )]
    else:
        print("none")
        return []


if __name__ == "__main__":
    app.run_server(debug=True, port=8055)

Hope it helps.

Sign up to request clarification or add additional context in comments.

4 Comments

it works like magic, huge thanks @Lawliet! I am trying to understand it now, and will come back in a while.
update: Again, thank you very much for the answer. I am back, allow me to ask, now we didn't name the children here in final_table, but why does the system show an error message sometimes saying the children isn't specified?
@yts61 I'm not so sure about the error, there might be some corner case which I missed here, if you could let me know how I could recreate the issue, I can try finding what is causing the error.
@n00b It doesn't appear that csv is available anymore

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.