Recommended way of handling defaults


#1

What is the best way of handling defaults in dash, e.g., when creating a new dropdown or check boxes? Should they start empty or always with some default value? The problem with starting empty is that if there are callbacks associated to them, they will fire and throw an exception. Starting with some default value is arbitrary in many cases. Should the callback check if the combination of values is valid and only then attempt to make a change? Should we avoid exceptions at all costs?

Thanks!


#2

Hi,

One solution is to mix your two suggestions: default to empty list :wink:

  • no exception raised
  • no default value

for instance look at this code:

import pandas as pd
import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go

# generate fake dataframe
data = pd.DataFrame(columns=['Region', 'Sales', 'Profit'])
data.loc[:,'Region'] = ['East','West','Central','South']*10
data.loc[:,['Sales','Profit']] = pd.np.random.randn(40,2)

app=dash.Dash()

app.layout = html.Div([
    dcc.Dropdown(
        id='my-dropdown',
        options=[{'label': v, 'value': v} for v in ['East', 'West', 'Central', 'South']],
        multi=True,
        value=[]
    ),
        
    dcc.Graph(
        id='my-graph',
        figure={ 'data': [], 'layout': []}
    )
   
])

@app.callback(
    dash.dependencies.Output('my-graph','figure'),
    [dash.dependencies.Input('my-dropdown', 'value')])
def update_graph(dropdown_value):
    traces = []
    for val in dropdown_value:
        traces.append(
            go.Scatter(
                x=data.loc[data['Region'] == val,'Sales'],
                y=data.loc[data['Region'] == val,'Profit'],
                mode='markers',
                opacity=0.7,
                marker={
                    'size': 5,
                    'line': {'width': 0.5, 'color': 'white'}
                },
                name=val
            )
        )

    layout=go.Layout(
        xaxis={'title': 'Sales'},
        yaxis={'title': 'Profit'},
        margin={'l': 50, 'b': 30, 't': 10, 'r': 0},
        legend={'x': 0, 'y': 1},
        hovermode='closest'
    )

    figure = {'data': traces, 'layout': layout}
    return figure 

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

It will fire the callback but plot nothing. If your callback is time consuming, you can also simply add a check at the beginning like if len(dropdown_value)==0: return {'data':[], 'layout':[]} to save you useless computation.


#3

To save even more time and write code as human-friendly use:

if not dropdown_value:
    return {'data':[], 'layout':[]}

as empty list in boolean context evaluates to False in python, just like empty string, dict and None.

The more you know.