The previous section describes how to create dashboards with different types of charts using the Plotly Express library on a Spark server cluster. This section shows how to use Dash to share dashboards with web app customers and enable customers to use dashboards to visualize data in a variety of interactive ways.
The following procedure can be followed to develop a dashboard for a web application page:
- Step 1 – Import Dash Library Modules
- Step 2 – Create a Dash Application Object
- Step 3 – Define an HTML Page Dashboard Layout
- Step 4 – Define Callback Functions (Web Service Endpoints)
- Step 5: start server
4.1 Import dashboard library modules
As a first step, the Plotly Dash library modules are imported as follows for the purpose of demonstrating it in this document.
import plotly.express as px
from dash import Dash, dcc, html, callback, Input, Output
4.2 Create dashboard application object
After importing the library modules, the next step is to create a Dash application object:
app = Dash(__name__)
4.3 Defining the dashboard layout
Once a Dash application object is created, we need to define a dashboard layout as an HTML page.
The dashboard HTML page is divided into two parts in this document:
- Part 1: visualization of numerical characteristics
- Part 2: visualization of categorical features
Part 1 of the dashboard layout is defined as follows:
app.layout = html.Div([ # dashboard layout
html.Div([ # Part 1
html.Div([
html.Label(['Age:'], style={'font-weight': 'bold', "text-align": "center"}),
dcc.Dropdown(
['0-10', '11-20', '21-30', '31-40', '41-50',
'51-60', '61-70', '71-80', '81-90', '91-100',
'More than 100 Days'],
value='21-30',
id='numerical_age'
),
],
style={'width': '20%', 'display': 'inline-block'}),html.Div([
html.Label(['Numerical Feature x:'], style={'font-weight': 'bold', "text-align": "center"}),
dcc.Dropdown(
['patientid',
'Hospital_code',
'City_Code_Hospital'],
value='patientid',
id='axis_x',
)
], style={'width': '20%', 'display': 'inline-block'}),
html.Div([
html.Label(['Numerical Feature y:'], style={'font-weight': 'bold', "text-align": "center"}),
dcc.Dropdown(
['Hospital_code',
'Admission_Deposit',
'Bed Grade',
'Available Extra Rooms in Hospital',
'Visitors with Patient',
'Bed Grade',
'City_Code_Patient'],
value='Admission_Deposit',
id='axis_y'
),
], style={'width': '20%', 'display': 'inline-block'}),
html.Div([
html.Label(['Color Feature:'], style={'font-weight': 'bold', "text-align": "center"}),
dcc.Dropdown(
['Severity of Illness',
'Stay',
'Department',
'Ward_Type',
'Ward_Facility_Code',
'Type of Admission',
'Hospital_region_code'],
value='Type of Admission',
id='color_feature'
),
], style={'width': '20%', 'display': 'inline-block'}),
html.Div([
html.Label(['Graph Style:'], style={'font-weight': 'bold', "text-align": "center"}),
dcc.Dropdown(
['scatter',
'histogram',
'line'],
value='histogram',
id='numerical_graph_style'
),
], style={'width': '20%', 'float': 'right', 'display': 'inline-block'})
],
style={
'padding': '10px 5px'
}),
html.Div([
dcc.Graph(id='numerical-graph-content')
]),
......
Figures 2, 3, and 4 are created using Part 1 of the board layout.
Part 2 of the dashboard layout is defined as follows:
......
html.Div([ # Part 2
html.Div([
html.Label(['Age:'], style={'font-weight': 'bold', "text-align": "center"}),
dcc.Dropdown(
['0-10', '11-20', '21-30', '31-40', '41-50',
'51-60', '61-70', '71-80', '81-90', '91-100',
'More than 100 Days'],
value='21-30',
id='categorical_age'
),
],
style={'width': '25%', 'display': 'inline-block'}),html.Div([
html.Label(['Categorical Feature:'], style={'font-weight': 'bold', "text-align": "center"}),
dcc.Dropdown(
['Severity of Illness',
'Stay',
'Department',
'Ward_Type',
'Ward_Facility_Code',
'Type of Admission',
'Hospital_region_code'],
value='Stay',
id='categorical_feature'
),
],
style={'width': '25%', 'display': 'inline-block'}),
html.Div([
html.Label(['Color:'], style={'font-weight': 'bold', "text-align": "center"}),
dcc.Dropdown(
['red',
'green',
'blue',
'orange',
'purple',
'black',
'yellow'],
value='blue',
id='categorical_color'
),
],
style={'width': '25%', 'display': 'inline-block'}),
html.Div([
html.Label(['Graph Style:'], style={'font-weight': 'bold', "text-align": "center"}),
dcc.Dropdown([
'histogram',
'bar',
'line',
'pie'],
value='bar',
id='categorical_graph_style'
),
],
style={'width': '25%', 'float': 'right', 'display': 'inline-block'})
],
style={
'padding': '10px 5px'
}),
html.Div([
dcc.Graph(id='categorical-graph-content')
])
]) # end of dashboard layout
Figures 5, 6, and 7 are created using Part 2 of the board layout.
4.4 Defining callback functions
The dashboard layout only creates a static HTML page of a dashboard. Callback functions (that is, web service endpoints) must be defined so that a dashboard user’s action can be sent to a server-side callback function as a web service request. In other words, callback functions allow interaction between dashboard users and server-side dashboard web services, such as creating a new chart at the user’s request (for example, selecting a dropdown option).
There are two callback functions defined in this document for the two parts of the dashboard layout.
The callback function for Part 1 of the dashboard layout is defined as follows:
@callback(
Output('numerical-graph-content', 'figure'),
Input('axis_x', 'value'),
Input('axis_y', 'value'),
Input('numerical_age', 'value'),
Input('numerical_graph_style', 'value'),
Input('color_feature', 'value')
)
def update_numerical_graph(x, y, age, graph_style, color_feature):
dff = spark.sql(f"SELECT * FROM dataset_view WHERE Age=='{age}'").toPandas()if graph_style == 'line':
fig = px.line(dff,
x = x,
y = y,
color = color_feature
)
elif graph_style == 'histogram':
fig = px.histogram(dff,
x = x,
y = y,
color = color_feature
)
else:
fig = px.scatter(dff,
x = x,
y = y,
color = color_feature
)
fig.update_layout(
title=f"Relationship between {x} vs. {y}",
)
return fig
The callback function for Part 2 of the dashboard layout is defined as follows:
@callback(
Output('categorical-graph-content', 'figure'),
Input('categorical_feature', 'value'),
Input('categorical_age', 'value'),
Input('categorical_graph_style', 'value'),
Input('categorical_color', 'value')
)
def update_categorical_graph(feature, age, graph_style, color):
dff = spark.sql(f"SELECT * FROM dataset_view WHERE Age=='{age}'").toPandas()
vc = dff[feature].value_counts()if graph_style == 'bar':
fig = px.bar(vc,
x = vc.index,
y = vc.values
)
elif graph_style == 'histogram':
fig = px.histogram(vc,
x = vc.index,
y = vc.values
)
elif graph_style == 'line':
fig = px.line(vc,
x = vc.index,
y = vc.values
)
else:
fig = px.pie(vc,
names = vc.index,
values = vc.values
)
if graph_style == 'line':
fig.update_traces(line_color=color)
elif graph_style != 'pie':
fig.update_traces(marker_color=color)
fig.update_layout(
title=f"Feature {feature} Value Counts",
xaxis_title=feature,
yaxis_title="Count"
)
return fig
Each callback function is associated with an @ annotationcall back. The annotation associated with a callback function controls which HTML component (eg, dropdown) provides input to the callback function upon user request, and which HTML component (eg, a graphic within a division tag) receives the output of the callback function.
4.5 Boot server
The final step of a Dash web application is to start a web service server as shown below:
if __name__ == "__main__":
app.run_server()
The following diagram shows a dashboard scenario when a dashboard user has selected the following options on the dashboard:
- age from 21 to 30
- pair of numerical features patient ID and Admission_Deposit
- categorical characteristic Admission Type for color coding the display of numerical features
- dispersion graphic for visualization of numerical characteristics
- categorical trait Stay to compute feature value counts
- Color blue for bar, histogram and line graphs
- cake Automatically color-coded graph for displaying counts of categorical feature values