import os import dash from dash.dependencies import Input, Output import dash_table import dash_core_components as dcc import dash_html_components as html import pandas as pd import numpy as np csv_name = os.path.dirname(__file__) + '../statistics.csv' df = pd.read_csv(csv_name) # Round floats df.iloc[:, 1:] = np.round(df.iloc[:, 1:] * 100) / 100 variables = { 'location': '', 'H_sig': 'o', 'H_1%': 'x', 'H_max': '□', 'Hm0': '◊', 'Tp': '', 'Tp1': '', } df = df[variables.keys()] # add an id column and set it as the index # in this case the unique ID is just the country name, so we could have just # renamed 'country' to 'id' (but given it the display name 'country'), but # here it's duplicated just to show the more general pattern. df['id'] = df.index # df.set_index('id', inplace=True, drop=False) app = dash.Dash(__name__) app.layout = html.Div([ dash_table.DataTable( id='datatable-row-ids', columns=[{ 'name': [val, key], 'id': key } for key, val in variables.items()], data=df.to_dict('records'), editable=False, # filter_action="native", sort_action='native', sort_mode='multi', row_selectable='multi', row_deletable=False, selected_rows=list(df.index), style_as_list_view=True, ), html.Div(id='datatable-row-ids-container') ]) @app.callback(Output('datatable-row-ids-container', 'children'), [ Input('datatable-row-ids', 'derived_virtual_row_ids'), Input('datatable-row-ids', 'selected_row_ids'), Input('datatable-row-ids', 'active_cell') ]) def update_graphs(row_ids, selected_row_ids, active_cell): # When the table is first rendered, `derived_virtual_data` and # `derived_virtual_selected_rows` will be `None`. This is due to an # idiosyncracy in Dash (unsupplied properties are always None and Dash # calls the dependent callbacks when the component is first rendered). # So, if `rows` is `None`, then the component was just rendered # and its value will be the same as the component's dataframe. # Instead of setting `None` in here, you could also set # `derived_virtual_data=df.to_rows('dict')` when you initialize # the component. selected_id_set = set(selected_row_ids or []) if row_ids is None: dff = df # pandas Series works enough like a list for this to be OK row_ids = df['id'] else: dff = df.loc[row_ids] active_row_id = active_cell['row_id'] if active_cell else None colors = [ '#FF69B4' if i == active_row_id else '#7FDBFF' if i in selected_id_set else '#0074D9' for i in row_ids ] return [ dcc.Graph( id=column + '--row-ids', figure={ 'data': [{ 'x': dff['id'], 'y': dff[column], 'type': 'bar', 'marker': { 'color': colors }, }], 'layout': { 'xaxis': { 'automargin': True }, 'yaxis': { 'automargin': True, 'title': { 'text': column } }, 'height': 250, 'margin': { 't': 10, 'l': 10, 'r': 10 }, }, }, ) # check if column exists - user may have deleted it # If `column.deletable=False`, then you don't # need to do this check. for column in ['H_sig', 'H_1%', 'H_max'] if column in dff ] if __name__ == '__main__': app.run_server(debug=True)