Creating table based on histogram selection

Hi all,

I have multiple dropdowns that create a series of overlaid histograms, however, I would like to create a data-table so users can extract the percentages and counts of what they select as a data table (like the ones displayed on the hover). The first two callbacks work great but the last one updating the table doesn’t

app = dash.Dash()


features = region_mirco_census.columns



app.layout = html.Div([
    
		html.Div([
        
         html.Div(html.Div([
      
            html.Div([
                html.H1(children='HMT Equalities Explorer',
                    style = {'color': corporate_colors['light-green'], 'textAlign' : 'center', 'font-family':'sans-serif'}
                )],
                className='col-8',
                style = {'padding-top' : '1%', 'padding-bottom' : '1%', 'background-color' : corporate_colors['dark-green']}
                    ),
        
            html.Div([
                html.Img(
                    src = 'https://publicappointments.cabinetoffice.gov.uk/wp-content/uploads/2018/02/HMT-logo.png',
                    height = '70 px',
                    width = 'auto')
                ],
                className = 'col-2',
                style = {
                    'align-items': 'center',
                    'padding-top' : '1%',
                    'height' : 'auto'})
                    ],
                className = 'row',
                style = {'height' : '4%',
                'background-color' : corporate_colors['light-green']}
                ), style = filterdiv_borderstyling)
            ]),
   
		html.Div([ html.Label('Select Characteristic:', 
                          style={'color' : corporate_colors['light-green'], 'font-family' : 'sans-serif'}),
            dcc.Dropdown(
                id='slct_xaxis',
                options=[{'label': i, 'value': i} for i in features],
                value='Characteristic - Age',
                multi=False,
                style = {'font-family' : 'sans-serif', 'color' : corporate_colors['dark-green']}
                )], 
                 style={'width': '70%', 'padding-top' : '0.5%', 'padding-left' : '0.5%'}
                ),
    

		html.Div([
            
            html.Label('Select Second Characteristic:', 
                    style={'color' : corporate_colors['light-green'], 'font-family' : 'sans-serif'}),
                dcc.Dropdown(id = "slct_xaxis2",
							multi = False,
							searchable = True,
							value = "Characteristic - Ethnicity",
							options=[{'label': i, 'value': i} for i in features],
							className = "dcc_compon",
                            style = {'font-family' : 'sans-serif'})
        
        ], style={'width': '70%', 'display': 'inline-block', 'padding-bottom' : '0.5%', 'padding-top' : '0.5%', 'padding-left' : '0.5%', 'align-content': 'flex-end'}
        ),
    
		html.Div([

            html.Label('Select Variable(s) Within Second Characteristic:', 
                    style={'color' : corporate_colors['light-green'], 'font-family' : 'sans-serif','padding-top' : '0.5%'}
                  ),
            dcc.Dropdown(
							id = "slct_v",
							multi = True,
							searchable = True,
							options = [],
							className = "dcc_compon"), 
            
                ], style = {'font-family' : 'sans-serif', 'width': '70%', 'padding-left' : '0.5%'}
            ),
    
        
		html.Div([ html.Label('Select Region:', 
                          style={'color' : corporate_colors['light-green'], 'font-family' : 'sans-serif'}),
            dcc.Dropdown(
                id = 'select_region',
                options = [{
                     'label' : i, 
                     'value' : i
                 } for i in region_mirco_census['UK region'].unique()],
                style = {'font-family' : 'sans-serif'})
                ], 
                style={'width': '70%', 'display': 'inline-block', 'padding-top' : '0.5%', 'padding-left' : '0.5%','align-content': 'flex-end'}
                ),
           
 
    dcc.Graph(id='feature-graphic'),
    html.Div(dash_table.DataTable(id = 'table'))
    
], style = {'background-color' : corporate_colors['dark-green'],
            'box-shadow': '2px 5px 5px 1px rgba(255, 101, 131, .5)'})

@app.callback(
  Output(
    component_id = "slct_v",
    component_property = "options"
  ),
  Output(
    component_id = "slct_v",
    component_property = "value"
  ),
  Input(
    component_id = "slct_xaxis2",
    component_property = "value"
  )
)
def update_variable(slct_xaxis2):
  # Build list of variables
  list_of_variables = [{"label": i, "value": i} for i in region_mirco_census[slct_xaxis2].unique()]
  # Return list and value
  return list_of_variables, list_of_variables[0]["value"]

@app.callback(
    Output('feature-graphic', 'figure'),
    [Input('slct_xaxis', 'value'),
     Input('select_region', 'value'),
     Input('slct_xaxis2','value'),
     Input('slct_v', 'value')])
def update_graph(slct_xaxis, select_region, slct_xaxis2, slct_v):

    region_mirco_census_filtered_region_and_slct_variable = region_mirco_census.loc[(region_mirco_census['UK region'] == select_region) & (region_mirco_census[slct_xaxis2].isin(slct_v))]
    region_mirco_census_filtered_uk = region_mirco_census[region_mirco_census[slct_xaxis2].isin(slct_v)]
    region_mirco_census_filtered_region = region_mirco_census.loc[region_mirco_census['UK region'] == select_region]
    
    customdata_uk = np.array(region_mirco_census[slct_xaxis].value_counts())
    customdata_region = np.array(region_mirco_census_filtered_region[slct_xaxis].value_counts())
    customdata_uk_slct_variables = np.array(region_mirco_census_filtered_uk[slct_xaxis].value_counts())
    customdata_region_slct_variables = np.array(region_mirco_census_filtered_region_and_slct_variable[slct_xaxis].value_counts())
    
    
    
    fig = go.Figure()

    fig.add_trace(
       
        go.Histogram(
            x=region_mirco_census_filtered_uk[slct_xaxis], customdata = customdata_uk_slct_variables, histnorm='percent', marker = dict(color=corporate_colors['light-green']),
            opacity=0.8, name="England and Wales Selected Second Variable(s)", hovertemplate='<b>Percenatge: %{y:.2f}</b><br>Count: %{customdata} <extra></extra>'
        )
    )

    fig.add_trace(
            go.Histogram(
                
                x=region_mirco_census_filtered_region_and_slct_variable[slct_xaxis], customdata = customdata_region_slct_variables, histnorm='percent',
                marker=dict(color='rgba(0,0,0,0)', line=dict(width=4, color= corporate_colors['medium-blue'])),
                opacity=0.8, name="Selected Region & Selected Second Variable(s)", hovertemplate='<b>Percenatge: %{y:.2f}</b><br>Count: %{customdata} <extra></extra>'
            )
    )
    
    fig.add_trace(
            go.Histogram(
                
                x=region_mirco_census[slct_xaxis], customdata = customdata_uk, histnorm='percent', marker=dict(color='rgba(0,0,0,0)', line=dict(width=4, color=corporate_colors['burnt-orange'])),
                opacity=0.8, name="England and Wales", hovertemplate='<b>Percenatge: %{y:.2f}</b><br>Count: %{customdata} <extra></extra>'
            )
    )
    
    fig.add_trace(
            go.Histogram(
                
                x=region_mirco_census_filtered_region[slct_xaxis], customdata = customdata_region, histnorm='percent', marker=dict(color='rgba(0,0,0,0)', line=dict(width=4, color=corporate_colors['medium-green'])),
                opacity=0.8, name="Selected Region", hovertemplate='<b>Percenatge: %{y:.2f}</b><br>Count: %{customdata} <extra></extra>'
            )
    )
        
    fig.update_layout(height=750, barmode='overlay',
        margin=dict(l=20, r=20, t=20, b=70),  
        font = {'family' :  'sans-serif'},
        paper_bgcolor = 'rgba(0,0,0,0)',
        plot_bgcolor = 'rgba(0,0,0,0)',
        xaxis = corporate_xaxis,
        yaxis = corporate_yaxis,
        legend_title_text='Please Click to Select Traces:',
        legend_font_family =  'sans-serif',
        legend_font_color = corporate_colors['light-green'],
        legend_font_size =15)
    
    fig.update_xaxes(categoryorder='category ascending', automargin=True)
    fig.update_yaxes(range=[0, 100])

    #fig.show()
    return fig

@app.callback(
    Output('table', 'figure'),
    [Input('slct_xaxis', 'value'),
     Input('select_region', 'value'),
     Input('slct_xaxis2','value'),
     Input('slct_v', 'value')])

def update_table(slct_xaxis, select_region, slct_xaxis2, slct_v):

    region_mirco_census_filtered_region_and_slct_variable = region_mirco_census.loc[(region_mirco_census['UK region'] == select_region) & (region_mirco_census[slct_xaxis2].isin(slct_v))]
    region_mirco_census_filtered_uk = region_mirco_census[region_mirco_census[slct_xaxis2].isin(slct_v)]
    region_mirco_census_filtered_region = region_mirco_census.loc[region_mirco_census['UK region'] == select_region]
    
    customdata_uk = pd.DataFrame(region_mirco_census[slct_xaxis].value_counts())
    customdata_region = pd.DataFrame(region_mirco_census_filtered_region[slct_xaxis].value_counts())
    customdata_uk_slct_variables = pd.DataFrame(region_mirco_census_filtered_uk[slct_xaxis].value_counts())
    customdata_region_slct_variables = pd.DataFrame(region_mirco_census_filtered_region_and_slct_variable[slct_xaxis].value_counts())
    
    combined_table = pd.concat([customdata_uk, customdata_region, customdata_uk_slct_variables, customdata_region_slct_variables])
    
    return combined_table

Hi @SHRees,

The output statement of your last callback is incorrect, there is no component property figure for DataTable component.

What you maybe looking for is to update the data property of the DataTable from your callback

Output('table', 'data')

Also the data property accepts values in a dictionary format so inside your function in your return statement convert the dataframe to a dictionary.

return combined_table.to_dict('records')
2 Likes