explainerdashboard icon indicating copy to clipboard operation
explainerdashboard copied to clipboard

Trigger dashboard on button click

Open ana-ventouris opened this issue 3 years ago • 1 comments

I am working on a Dataiku plugin, where I try to integrate ExplainerDashboard. They both use Dash and I initiate it like this:

predictor = ...
X_test = ...
y_true = ...

explainer =  RegressionExplainer(predictor._clf, X_test, y_true, n_jobs = 8)    
db = ExplainerDashboard(explainer, shap_interaction=True)

app.config.external_stylesheets = [dbc.themes.BOOTSTRAP]
app.layout = db.explainer_layout.layout()
db.explainer_layout.register_callbacks(app)

And the Dataiku webview automatically load the ExplainerDashboard when I open the page. However, it has a timeout that is not configurable and some models takes more than the time limit. What I try to do is to open the Dataiku dash page where I have some information in text and a button that will say "Open the dashboard". Then when one clicks it, the whole layout will be replaced with the ExplainerDashboard.

I tried like this, but the dashboard opens empty without data in the plots (and the styling is also not bootstrap.

app.layout = html.Div([
    html.Button('Submit', id='submit', n_clicks=0),
    html.Div(id='container-button-basic',
             children='Click to open the dashboard')
])

@app.callback(
    Output('container-button-basic', 'children'),
    Input('submit', 'n_clicks'),
)
def update_output(n_clicks):
    predictor = ...
    X_test = ...
    y_true = ...
    
    explainer =  RegressionExplainer(predictor._clf, X_test, y_true, n_jobs = 8)    
    db = ExplainerDashboard(explainer, shap_interaction=True)
    
    app.config.external_stylesheets = [dbc.themes.BOOTSTRAP]
    app.layout = db.explainer_layout.layout()
    db.explainer_layout.register_callbacks(app)

Do you have any idea how I could do that work with a button instead?

ana-ventouris avatar Jul 07 '22 13:07 ana-ventouris

I think I am getting closer but I still not done.

If I do it like this:

app.config.external_stylesheets = [dbc.themes.BOOTSTRAP]

app.layout = html.Div([
    html.Button('Submit', id='submit', n_clicks=0),
    html.Div(id='container-button-basic', children=''),
    html.Div(id='placeholder-container')
])

X_train, y_train, X_test, y_test = titanic_survive()
model = LogisticRegression().fit(X_train, y_train)
explainer = ClassifierExplainer(model, X_test, y_test)
db = ExplainerDashboard(explainer, shap_interaction=False)
db.explainer_layout.register_callbacks(app)     

@app.callback(
    Output('container-button-basic', 'children'),
    Input('submit', 'n_clicks'),
)
def update_output(n_clicks):

    if n_clicks == 1:
        return db.explainer_layout.layout()

The dashboard gets triggered on the button click, however, it is calculated before I click the button and when the dash starts. If I change it and put the calculations inside the callback like this, I get the dashboard but it looks the register callback doesn't work and all the plots are empty

app.config.external_stylesheets = [dbc.themes.BOOTSTRAP]

app.layout = html.Div([
    html.Button('Submit', id='submit', n_clicks=0),
    html.Div(id='container-button-basic', children=''),
    html.Div(id='placeholder-container')
])

X_train, y_train, X_test, y_test = titanic_survive()
model = LogisticRegression().fit(X_train, y_train)
explainer = ClassifierExplainer(model, X_test, y_test)

@app.callback(
    Output('container-button-basic', 'children'),
    Input('submit', 'n_clicks'),
)
def update_output(n_clicks):

    if n_clicks == 1:
        db = ExplainerDashboard(explainer, shap_interaction=False) 
        db.explainer_layout.register_callbacks(app)     
        return db.explainer_layout.layout()

ana-ventouris avatar Jul 19 '22 09:07 ana-ventouris

I'm pretty sure you cannot register additional callback within a callback (all callbacks have to be registered by the start of the dash app).

You have pre-calculated the shap values, etc, right?

oegedijk avatar Jan 01 '23 19:01 oegedijk