The University of Sheffield Logo

Dataviz.Shef

Loading, please wait ...

Visualising data on the web with Python and Dash

Jez Cope
Angus Taggart

Jez Cope · Angus Taggart

04 June 2020 · 6 min read

Dash is a user interface library for creating analytical web applications. Those who use Python for data analysis, data exploration, visualization, modelling, instrument control, and reporting will find immediate use for Dash.



1. Prerequisites

This documentation assumes some prior knowledge of Python. A minimum of being able to install Python, relevent packages, and execute code should get you an example visualisation. If you need assistance with Python, python.org provides documentation and tutorials.

The code in the snippets below is able to be copied verbatim into a file to create a visualisation. At the end of the document, there is a link to download a file we prepared earlier.

In the interests of demonstrating the functionality, we have not presented best practice, rather focusing on demonstrating Dash. For example, you might want to consider using a virtual environment to aid in managing your third party packages.


2. Installation

The following tools should be available:

  • Browser capable of HTML 5.
  • Python (2.7 or 3.3 and above)

In order to run Dash in a Flask server, the following libraries will need to be available:

  • dash (The core Dash back-end)
  • dash-renderer (Dash front-end)
  • dash-html-components(HTML components)
  • dash-core-components (Supercharged components)
  • plotly (Plotly graphing library)
  • pandas (Numerical Analysis and Data Manipulation)

Those have been pre-populated in a requirements.txt file, compatible with pip, to prepare a python environment.


3. About this example

In this example, we are going to build a graph that shows life expectancy in comparison to GDP per capita based in all countries around the World.


4. First step

Besides Dash, we are using Pandas for extracting and manipulating data and Plotly to render the output into a Graph. In order to use those libraries, you first need to import them:

import dash
import dash_core_components as dcc
import dash_html_components as html

import plotly.graph_objs as go

import pandas as pd

5. Download and read a CSV file

Use Panda's read_csv function to download and extract your dataset. When you read a CSV, you get a DataFrame, which is made up of rows and columns. You access columns in a DataFrame the same way you access elements of a dictionary.

df = pd.read_csv('https://ndownloader.figsh.com/files/8261349')

6. Preview Dataset

Function head() gives you a preview of the downloaded dataset.

df.head()
Unnamed: 0CountryContinentPopulationLife expectancyGDP per capita
011AfghanistanAsia31889923.043.828974.580338
123AlbaniaEurope3600523.076.4235937.029526
235AlgeriaAfrica33333216.072.3016223.367465
347AngolaAfrica12420476.042.7314797.231267
459ArgentinaAmericas40301927.075.32012779.379640

7. Layout

Dash apps are composed of two parts: Layout and Interactivity. The first part is the "layout" of the app, and it describes what the application looks like.

In this example, we are going to create two kinds of filter:

  1. Countries: Multiple selection combo box with a list of all countries included on the Dataset
  2. Life Expectancy: Slider with a range of ages (min and max)
countries = df['country'].unique()

app = dash.Dash()

app.layout = html.Div([

    html.Div([
        html.Label('Country'),
        dcc.Dropdown(
            id='country',
            options=[{'label': i, 'value': i} for i in countries],
            value='',
            placeholder='Select...',
            multi=True
        )
    ],    
    style={'width': '20%', 'display': 'inline-block', 'margin-bottom': '20px'}),    

    html.Div([
        html.Label('Life Expectancy'),
        dcc.Slider(
            id='expectancy-slider',
            min=30,
            max=80,
            value=30,
            step=None,
            marks={'30':'>30', '40':'>40', '50':'>50', '60':'>60', '70':'>70', '80':'>80'}
        ),
    ],
    style={'width': '20%', 'display': 'inline-block', 'margin-bottom': '20px', 'margin-left': '20px'}),

    html.Div([
        dcc.Graph(id='life-exp-vs-gdp'),
    ],
    style={'width': '70%'}),
])

8. Interactivity

Dash provides a simple reactive decorator for binding your custom data analysis code to your Dash user interface.
When an input element changes (e.g. when you select an item in the dropdown or drag the slider), Dash’s decorator provides your Python code with the new value of the input.
In this example, we are calling the update_graph function each time either a country is selected or a life expectancy range is set.

@app.callback(
    dash.dependencies.Output('life-exp-vs-gdp', 'figure'),
    [
        dash.dependencies.Input('expectancy-slider', 'value'),
        dash.dependencies.Input('country', 'value')
    ])
def update_graph(expectancy, country):

    filtered_df = df.loc[df["life expectancy"] > expectancy]

    if (country != '' and country is not None):
        filtered_df = filtered_df[df.country.str.contains('|'.join(country))]

    traces = []
    for i in filtered_df.continent.unique():
        df_by_continent = filtered_df[filtered_df['continent'] == i]
        traces.append(go.Scatter(
            x=df_by_continent['gdp per capita'],
            y=df_by_continent['life expectancy'],
            text=df_by_continent['country'],
            mode='markers',
            opacity=0.7,
            marker={
                'size': 15,
                'line': {'width': 0.5, 'color': 'white'}
            },
            name=i
        ))

    return {
        'data': traces,
        'layout': go.Layout(
            xaxis={'title': 'GDP Per Capita', 'titlefont': dict(size=18, color='darkgrey'), 'zeroline': False, 'ticks': 'outside' },
            yaxis={'title': 'Life Expectancy', 'titlefont': dict(size=18, color='darkgrey'), 'range': [30, 90], 'ticks': 'outside'},
            margin={'l': 60, 'b': 60, 't': 30, 'r': 20},
            legend={'x': 1, 'y': 1},
            hovermode='closest'
        )
    }

9. Style

Every aesthetic element of the app is customisable: The sizing, the positioning, the colours, the fonts. Dash apps are built and published in the Web, so the full power of CSS is available.

Use app.css.append_css in order to set an external CSS file

app.css.append_css({
    "external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"
})

10. Running

Dash apps are web applications. Dash uses Flask as the web framework. The underlying Flask app is available at app.server, and for the purpose of running the application, you should call run_server function in your python code, as you can see below.

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

We have prepared the code snippets from above in dash_example.py. It is strongly recommended you read this file to understand it before executing it.

If it all works correctly, your app should be running and accessible in your web browser; the default address is http://127.0.0.1:8050/. It should look something like this:


Related technologies:

Edit this page on GitHub