'ipywidgets and plotly not showing their output after first call

I am trying to create a dashboard that contains plotly graphics objects and ipython widgets inside a jupyter notebook. Everything works fine when a certain function that uses these widgets to produce a plotly graph object is used with @interact decorator, i.e. its expected output, the graph, is shown soon after executing the cell. However, if I put the whole function and widgets inside a VBox widget, together with an Output widget that shall contain the graph, the function doesn't show any chart when the cell is executed for the first time (see picture below), and only after interacting with its widgets I get a refresh of the chart.

I include my code here, it is not reproducible and I apologize for that, however I hope someone can spot the problem with it.

daily_tab = widgets.VBox()

daily_out = widgets.Output(layout = {
            'width': '100%',
            'height': '600px',
            'border': '1px solid black'
        })

def get_values_for_day(regions,labels,date,cases_per_mln_people,show_grid):
    with daily_out:
        clear_output()
        data_columns = orig_data_columns+extra_data_columns
        if len(regions) == 0:
            regions = ['Italy']
        regions = list(regions)    
        if len(labels) == 0:
            labels = [item for item in data_columns if ('daily' in item) & ('%' not in item)]
        labels = list(labels)
        mult = 1.
        fig = go.Figure()
        for region in regions:    
            if cases_per_mln_people: 
                mult = 1e06/ita_populations.loc[region, 'Popolazione']
            for item in labels: 
                df_reg[region].index = pd.to_datetime(df_reg[region].index)
            fig.add_traces(go.Bar(y=labels, x=df_reg[region][labels].loc[date]*mult, name=region, orientation='h'))
            fig.update_layout(showlegend=True,title='day ' + str(date.strftime("%m/%d/%Y")),
                             paper_bgcolor='rgba(0,0,0,0)',font = dict(color = 'lightgray'),plot_bgcolor='rgba(0,0,0,0)')
        fig.update_xaxes(showgrid=show_grid, gridwidth=1, gridcolor='lightgray')
        fig.update_yaxes(showgrid=show_grid, gridwidth=1, gridcolor='lightgray')
        fig.show()
        
daily_widget = interactive(get_values_for_day,
                           regions = widgets.SelectMultiple(description="regions",
                                                            options=list(df_reg.keys()), value=['Italy']),
                           labels = widgets.SelectMultiple(description="data",
                                                           options=orig_data_columns+extra_data_columns, 
                                                           value=['Rth']),
                           date=widgets.DatePicker(description='Pick a Date',
                                                   value=pd.to_datetime(df_prov.index.max())),
                           cases_per_mln_people=False, 
                           show_grid=False)
daily_box = widgets.HBox(daily_widget.children[:-1], layout = widgets.Layout(flex_flow='row wrap'))

daily_tab.children = [daily_box, daily_out]

here's the output of the cell when it's executed for the first time:

output after first cell execution

and here's the output after interacting with the various widget controls:

enter image description here

How could I have the function printing the expected output given its default parameters when called the first time without the need of forcing the call?



Solution 1:[1]

I ran into a similar trouble using plots and the Output widget. Somehow the internal rendering routine of Output and plotly/bqplot/plt don't work well together.

You can declare go.figure() directly as a widget and by-passing the Output widget. It would look like this:

daily_tab = widgets.VBox()
fig_output = go.figure()

def get_values_for_day(regions,labels,date,cases_per_mln_people,show_grid, fig_output):
    clear_output()
    data_columns = orig_data_columns+extra_data_columns
    (...)
    # replace all occurences of fig with fig_output. Don't use fig_output.show()
    fig_output.update_xaxes(showgrid=show_grid, gridwidth=1, gridcolor='lightgray')


daily_tab.children = [daily_box, fig_output]

Maybe some minor adjustments are needed for this to work, but I could not test it with the provided code.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 above_c_level