How can I display multiple plots per-tab using dcc.Tabs

Hi!

I’m pretty new in Dash, and I’m trying to build a dashboard where you can show let’s say 5 Scatter plots in one tab, and that same number of plots in other tab but using Histogram. I’m having a difficult time finding out how to make my code work properly. Here’s the code I’ve used to try to get the goal but the displayed plots are empty in each tab. I will appreciate (a lot!) some help with corrections/suggestions in the code to achieve the described goal!

Basically each “scenario#_dict” object contains dataframes corresponding to monthly periods of time-series data. In other words, each dictionary contains: {‘month_i’:dataframe_i}, i = 1 to 11.

from jupyter_dash import JupyterDash
import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objects as go
from dash.dependencies import Input, Output, State

## Input Data to the Dashboard

scenario1_dict = dict(zip(month_list, scenario1_concat))
scenario2_dict = dict(zip(month_list, scenario2_concat))
scenario3_dict = dict(zip(month_list, scenario3_concat))
scenario4_dict = dict(zip(month_list, scenario4_concat))
scenario5_dict = dict(zip(month_list, scenario5_concat))

months_dropdown = list(scenario1_dict.keys())
scenario1_channel = scenario1_dict[months_dropdown[0]]
scenario2_channel = scenario2_dict[months_dropdown[0]]
scenario3_channel = scenario3_dict[months_dropdown[0]]
scenario4_channel = scenario4_dict[months_dropdown[0]]
scenario5_channel = scenario5_dict[months_dropdown[0]]

##-----------------------------------------------------------------------------------------------------------------------------------------------------------------
## Define app server 
app = dash.Dash(__name__)
server = app.server

##-----------------------------------------------------------------------------------------------------------------------------------------------------------------
## Layout component
app.layout = html.Div(
    [
                html.Div([html.H1('Scenarios Analysis')]),
        # Define tabs for the dashboard
        html.Div(
        dcc.Tabs(id = 'all-tabs', value = 'tab-1', children = [
                 dcc.Tab(label = 'Analyzed Scenarios', value = 'tab-1'),
                 dcc.Tab(label = 'Price Distribution', value = 'tab-2')
            
        ])),
        
        # Dropdown corresponding to the months
        html.Div([
        dcc.Dropdown(id = 'month-dropdown', 
                     options = [{'label':month, 'value':month} for month in months_dropdown], 
                     value = months_dropdown, searchable = False)    
                  ], style = {'width':'10%', 'display':'inline-block'}),
        
        # Dropdown corresponding to options: 'Simulated'/'Real' 
        html.Div([
        dcc.Dropdown(id = 'time-series', multi = True)       
        ], style = {'width':'20%', 'display':'inline-block'}),
        
        # Dropdowns corresponding to the graphs
        html.Div([html.H2('Scenario 1')]),
        html.Div([
        dcc.Graph(id = 'Graph1')       
        ], style = {'width': '98%', 'display': 'inline-block'}),
        
        html.Div([html.H2('Scenario 2')]),
        html.Div([
        dcc.Graph(id = 'Graph2')       
        ], style = {'width': '98%', 'display': 'inline-block'}),
        
        html.Div([html.H2('Scenario 3')]),
        html.Div([
        dcc.Graph(id = 'Graph3')       
        ], style = {'width': '98%', 'display': 'inline-block'}),
        
        html.Div([html.H2('Scenario 4')]),
        html.Div([
        dcc.Graph(id = 'Graph4')       
        ], style = {'width': '98%', 'display': 'inline-block'}),
        
        html.Div([html.H2('Scenario 5')]),
        html.Div([
        dcc.Graph(id = 'Graph5')       
        ], style = {'width': '98%', 'display': 'inline-block'})
        
    ]
)

##-----------------------------------------------------------------------------------------------------------------------------------------------------------------
## Set callbacks
@app.callback(
    Output('time-series', 'options'), 
    [Input('month-dropdown', 'value')])
def update_date_dropdown(month):
    return[{'label':i, 'value':i} for i in scenario1_dict[month]]

@app.callback(   
	[Output('Graph1', 'figure'),
     Output('Graph2', 'figure')],
    [Input('all-tabs', 'value'),
     Input('time-series', 'value')],
    [State('month-dropdown', 'value')])
def show_content(tab):
	if tab == 'tab-1':
		return [go.Figure(data = [go.Scatter(x = scenario1_dict[month].index, y = scenario1_dict[month][i]) for i in scenario1_channel]), 
                go.Figure(data = [go.Scatter(x = scenario2_dict[month].index, y = scenario2_dict[month][i]) for i in scenario2_channel]),
                go.Figure(data = [go.Scatter(x = scenario3_dict[month].index, y = scenario3_dict[month][i]) for i in scenario3_channel]),
                go.Figure(data = [go.Scatter(x = scenario4_dict[month].index, y = scenario4_dict[month][i]) for i in scenario4_channel]),
                go.Figure(data = [go.Scatter(x = scenario5_dict[month].index, y = scenario5_dict[month][i]) for i in scenario5_channel])]
    
	elif tab == 'tab-2':
		return [go.Figure(data = [go.Histogram(x = scenario1_dict[month].index, y = scenario1_dict[month][i]) for i in scenario1_channel]), 
                go.Figure(data = [go.Histogram(x = scenario2_dict[month].index, y = scenario2_dict[month][i]) for i in scenario2_channel]),
                go.Figure(data = [go.Histogram(x = scenario3_dict[month].index, y = scenario3_dict[month][i]) for i in scenario3_channel]),
                go.Figure(data = [go.Histogram(x = scenario4_dict[month].index, y = scenario4_dict[month][i]) for i in scenario4_channel]),
                go.Figure(data = [go.Histogram(x = scenario5_dict[month].index, y = scenario5_dict[month][i]) for i in scenario5_channel])]
	else:
		go.Figure(data=[])
        
##-----------------------------------------------------------------------------------------------------------------------------------------------------------------
## Run the app in the specified host and port
if __name__ == '__main__':
	app.run_server(host ='127.0.0.1', port = 8889)

Thank you in advance!

Also interested in this.

You can use the technique used in this Dash app (see the second tab after the app launches): http://cepel-medical-charges.herokuapp.com

The corresponding Github repo is here: GitHub - tolgahancepel/medical-charges-prediction

Disclaimer: This is not my code or repo but I did learn quite a bit going through the codebase.

Your main problem is here:

app.layout = html.Div(
[
html.Div([html.H1(‘Scenarios Analysis’)]),
# Define tabs for the dashboard
html.Div(
dcc.Tabs(id = ‘all-tabs’, value = ‘tab-1’, children = [
dcc.Tab(label = ‘Analyzed Scenarios’, value = ‘tab-1’),
dcc.Tab(label = ‘Price Distribution’, value = ‘tab-2’)

    ])),

The way you have this coded it looks like you are setting two tabs under the main Div, and then defining all the html under them. If you want say X in tab 1, and Y in tab 2 then you need to do this:

app.layout = html.Div(
[
html.Div([html.H1(‘Scenarios Analysis’)]),
# Define tabs for the dashboard
html.Div(
dcc.Tabs(id = ‘all-tabs’, value = ‘tab-1’, children = [
dcc.Tab(label = ‘Analyzed Scenarios’, value = ‘tab-1’,children = [

              Content for tab 1....

             ]),

             dcc.Tab(label = 'Price Distribution', value = 'tab-2', children = [
              
              Content for tab 2.....

             ])
        ])
    ]),

Someof the parentheses might not be closed properly, but this is the general idea. The dcc.Tabs should have a children argument that all your tabs fall within. Similarly each tab (dcc.tab) will have it’s own children argument that contain the relevant html for that tab.

Hope this helps!