Cours
Dash est un framework Python pour créer des applications web. Il est construit sur Flask, Plotly.js, React et React Js. Il vous permet de créer des tableaux de bord en pur Python. Dash est open source et ses applications s'exécutent dans le navigateur. Dans ce tutoriel, nous présentons les fondamentaux de Dash en partant du principe que vous avez déjà utilisé Plotly.
Installation de Dash
Pour commencer avec Dash, il faut installer plusieurs packages.
- Le cœur backend de Dash.
- Le front-end Dash
- Les composants HTML Dash
- Les composants de base Dash
- Plotly
pip install dash==0.21.1
pip install dash-renderer==0.13.0
pip install dash-html-components==0.11.0
pip install dash-core-components==0.23.0
pip install plotly --upgrade
Structure d'une app Dash
Une application Dash comporte généralement deux parties. La première est la mise en page (layout), qui décrit l'apparence de l'app ; la seconde gère l'interactivité. Dash fournit des classes HTML qui permettent de générer du contenu HTML en Python. Pour les utiliser, importez dash_core_components et dash_html_components. Vous pouvez aussi créer vos propres composants avec JavaScript et React Js.
Pour démarrer, créons un fichier nommé app.py avec votre éditeur préféré, puis importons ces packages.
import dash
import dash_core_components as dcc
import dash_html_components as html
Comme avec Flask, on initialise Dash en appelant la classe Dash du module dash. Une fois fait, nous pouvons définir le layout de l'application. Nous utilisons la classe Div de dash_html_components pour créer une balise HTML Div. Nous utilisons ensuite les composants HTML pour générer des éléments tels que H1, H2, etc. dash_html_components propose toutes les balises HTML. Pour afficher un graphique dans notre layout, nous utilisons la classe Graph de dash_core_components. Graph rend des visualisations interactives avec plotly.js. La classe Graph attend un objet figure avec les data à tracer et la définition du layout. Dash permet aussi de styliser, par exemple modifier la couleur d'arrière-plan et la couleur du texte. Vous pouvez changer l'arrière-plan via l'attribut style en passant un dictionnaire de styles. Ici, nous définissons un dictionnaire de couleurs pour l'arrière-plan et le texte. De même, on peut ajuster le fond du graphique avec l'attribut plot_bgcolor.
En HTML, la propriété style est une chaîne séparée par des points-virgules ; dans Dash, on passe un dictionnaire. Les clés sont en camelCase, par exemple text-align devient textAlign. Au lieu de class en HTML, on utilise className dans Dash.
app = dash.Dash()
colors = {
'background': '#111111',
'text': '#7FDBFF'
}
app.layout = html.Div(style={'backgroundColor': colors['background']}, children=[
html.H1(
children='Hello Dash',
style={
'textAlign': 'center',
'color': colors['text']
}
),
html.Div(children='Dash: A web application framework for Python.', style={
'textAlign': 'center',
'color': colors['text']
}),
dcc.Graph(
id='Graph1',
figure={
'data': [
{'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar', 'name': 'SF'},
{'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': u'Montréal'},
],
'layout': {
'plot_bgcolor': colors['background'],
'paper_bgcolor': colors['background'],
'font': {
'color': colors['text']
}
}
}
)
])
Pour visualiser notre graphique, il faut lancer le serveur web, comme avec Flask. Rappelons que Dash est construit au-dessus de Flask. Nous activons aussi le mode debug pour éviter de relancer le serveur à chaque modification.
if __name__ == '__main__':
app.run_server(debug=True)
Ensuite, ouvrez le terminal et démarrez le serveur avec : python app.py
Un serveur web démarre à l'adresse http://127.0.0.1:8050/. Rendez-vous-y pour voir votre nouveau tableau de bord.

Générer des nuages de points
Pour tracer un nuage de points (scatter), nous importons les composants Dash comme précédemment. Nous devons aussi importer les graph_objs de Plotly pour créer le scatter. Comme mentionné, nous utilisons la classe Div et le composant Graph de Dash pour y parvenir. Le composant Graph reçoit un objet figure qui contient les données et la description du layout. Nous traçons le scatter via la propriété scatter de graph_objs. Pour s'assurer qu'il s'agit bien d'un nuage de points, nous passons l'attribut mode à markers. Sinon, des lignes seraient affichées.
import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objs as go
app = dash.Dash()
df = pd.read_csv(
'https://gist.githubusercontent.com/chriddyp/' +
'5d1ea79569ed194d432e56108a04d188/raw/' +
'a9f9e8076b837d541398e999dcbac2b2826a81f8/'+
'gdp-life-exp-2007.csv')
app.layout = html.Div([
dcc.Graph(
id='life-exp-vs-gdp',
figure={
'data': [
go.Scatter(
x=df[df['continent'] == i]['gdp per capita'],
y=df[df['continent'] == i]['life expectancy'],
text=df[df['continent'] == i]['country'],
mode='markers',
opacity=0.8,
marker={
'size': 15,
'line': {'width': 0.5, 'color': 'white'}
},
name=i
) for i in df.continent.unique()
],
'layout': go.Layout(
xaxis={'type': 'log', 'title': 'GDP Per Capita'},
yaxis={'title': 'Life Expectancy'},
margin={'l': 40, 'b': 40, 't': 10, 'r': 10},
legend={'x': 0, 'y': 1},
hovermode='closest'
)
}
)
])
if __name__ == '__main__':
app.run_server()

Markdown
Il arrive que vous ayez besoin d'ajouter beaucoup de texte à vos dashboards. Vous pouvez le faire avec l'attribut Mardown de dash_core_components comme ci-dessous.
import dash
import dash_core_components as dcc
import dash_html_components as html
app = dash.Dash()
markdown_text = '''
### Dash and Markdown
A lot of text
'''
app.layout = html.Div([
dcc.Markdown(children=markdown_text)
])
if __name__ == '__main__':
app.run_server()
Composants de base
Voyons maintenant quelques dash_core_components que vous utiliserez avec Dash. Vous pouvez générer une liste déroulante comme ci-dessous, en appelant Dropdown depuis dash_core_components et en passant les options sous forme de liste de dictionnaires. Vous définissez la valeur par défaut avec l'attribut values en passant l'option souhaitée.
dcc.Dropdown(
options=[
{'label': 'New York City', 'value': 'NYC'},
{'label': u'Montréal', 'value': 'MTL'},
{'label': 'San Francisco', 'value': 'SF'}
],
value='MTL'
)
Créer une liste déroulante multi-sélection est similaire. La seule différence est de définir l'attribut multi à true (par défaut False). Vous pouvez ensuite préciser les éléments sélectionnés par défaut via l'attribut values.
html.Label('Multi-Select Dropdown'),
dcc.Dropdown(
options=[
{'label': 'New York City', 'value': 'NYC'},
{'label': u'Montréal', 'value': 'MTL'},
{'label': 'San Francisco', 'value': 'SF'}
],
value=['MTL', 'SF'],
multi=True
)
Vous pouvez générer des boutons radio avec l'attribut RadioItems, en lui passant les options sous forme de liste de dictionnaires. Vous pouvez aussi définir une valeur par défaut via l'attribut values.
html.Label('Radio Items'),
dcc.RadioItems(
options=[
{'label': 'New York City', 'value': 'NYC'},
{'label': u'Montréal', 'value': 'MTL'},
{'label': 'San Francisco', 'value': 'SF'}
],
value='MTL'
)
Pour créer des cases à cocher, utilisez l'attribut Checklist de dash_core_components. Les options et valeurs par défaut se passent comme ci-dessus.
html.Label('Checkboxes'),
dcc.Checklist(
options=[
{'label': 'New York City', 'value': 'NYC'},
{'label': u'Montréal', 'value': 'MTL'},
{'label': 'San Francisco', 'value': 'SF'}
],
values=['MTL', 'SF']
)
Vous aurez très probablement besoin de champs de saisie. Pour les générer, utilisez l'attribut Input. Avec la balise Html Label, vous pouvez créer une étiquette pour le champ Input. L'attribut values permet de définir un texte par défaut, et l'attribut type précise s'il s'agit d'un champ texte, numérique, etc.
html.Label('Text Box'),
dcc.Input(value='MTL', type='text')

Appeler l'aide
Les composants Dash étant déclaratifs, appeler la fonction help sur l'un d'eux affiche l'aide correspondante.
help(dcc.Input)
Interactivité
Voyons maintenant comment rendre nos apps Dash interactives. Pour cela, importez Input et Output depuis dash.dependencies. Ne les confondez pas avec l'Input HTML, qui provient des composants de base Dash. Ci-dessous, nous créons un champ texte et le lions à un callback pour que toute saisie mette à jour my-div en temps réel. Pour lier le callback, Dash fournit un décorateur @app qui permet d'associer une fonction de rappel à my-div et au champ input HTML. Notez que nous utilisons le décorateur avant de définir la fonction update_output_div.
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
app = dash.Dash()
app.layout = html.Div([
dcc.Input(id='my-id', value='Dash App', type='text'),
html.Div(id='my-div')
])
@app.callback(
Output(component_id='my-div', component_property='children'),
[Input(component_id='my-id', component_property='value')]
)
def update_output_div(input_value):
return 'You\'ve entered "{}"'.format(input_value)
if __name__ == '__main__':
app.run_server()
Authentification
Dash propose l'authentification via un package séparé nommé dash-auth. Deux modes sont disponibles : HTTP Basic Auth et Plotly OAuth. En Basic Auth, vous codez en dur des paires identifiant/mot de passe dans votre application. Cette méthode a des limites : impossibilité de se déconnecter, pas de création de compte ni de changement de mot de passe par l'utilisateur, et vous devez stocker ces informations en toute sécurité dans votre code. Plotly OAuth s'appuie sur votre compte Plotly en ligne et n'est pas gratuit.
Pour configurer le Basic Auth, procédez ainsi. D'abord, installez les packages nécessaires.
pip install dash==0.21.1
pip install dash-auth==1.0.0
Ensuite, définissez les paires identifiant/mot de passe à autoriser dans votre application.
VALID_USERNAME_PASSWORD_PAIRS = [
['hello', 'world']
]
L'utilitaire dash_auth.BasicAuth de Dash gère l'authentification une fois les paires configurées. Il suffit de passer ces paires et le nom de votre application à dash_auth.BasicAuth.
app = dash.Dash('auth')
auth = dash_auth.BasicAuth(
app,
VALID_USERNAME_PASSWORD_PAIRS
)

Héberger des dashboards sur Heroku
Héberger votre tableau de bord sur Heroku est assez simple, mais nécessite quelques étapes.
Commencez par créer un dossier pour tous les fichiers du projet. Sous Ubuntu, utilisez la commande mkdir.
$ mkdir my_dash_app
$ cd my_dash_app
Initialisez ensuite le dossier avec git et virtualenv. Git sert au contrôle de version, et virtualenv crée un environnement virtuel pour isoler les dépendances Python. Après avoir créé l'environnement, activez-le avec la commande source.
$ git init
$ virtualenv venv
$ source venv/bin/activate
Installez ensuite tous les packages nécessaires à votre application Dash :
$ pip install dash
$ pip install dash-renderer
$ pip install dash-core-components
$ pip install dash-html-components
$ pip install plotly
Pour servir notre application Dash, nous avons besoin d'un serveur web Python. On n'utilise jamais le serveur de développement de Flask en production. Nous utiliserons le serveur web Gunicorn. Installez-le comme suit :
$ pip install gunicorn
Créez ensuite quelques fichiers dans le dossier :
- app.py, où vous coderez votre application Dash.
- Un .gitignore pour éviter d'envoyer des fichiers inutiles en production
- Un fichier requirements.txt qui contiendra toutes les dépendances Python et leurs versions.
- Un Procfile pour le déploiement.
Ajoutez le contenu suivant à app.py. C'est un exemple : vous pouvez utiliser votre propre dashboard Dash.
import os
import dash
import dash_core_components as dcc
import dash_html_components as html
app = dash.Dash(__name__)
server = app.server
app.layout = html.Div([
html.H2('Hello World'),
dcc.Dropdown(
id='dropdown',
options=[{'label': i, 'value': i} for i in ['LA', 'NYC', 'MTL']],
value='LA'
),
html.Div(id='display-value')
])
@app.callback(dash.dependencies.Output('display-value', 'children'),
[dash.dependencies.Input('dropdown', 'value')])
def display_value(value):
return 'You have selected "{}"'.format(value)
if __name__ == '__main__':
app.run_server(debug=True)
Rappelons qu'au cœur, une application Dash est aussi une application Flask. Pour le déploiement, nous devons accéder à l'instance Flask. Dash le permet via
app.server
app = dash.Dash(__name__)
server = app.server
Ajoutez dans .gitignore les fichiers que vous ne souhaitez pas pousser en production. Un bon .gitignore pour Python est disponible sur Github
Spécifions maintenant les informations de déploiement dans le Procfile. Nous utilisons le processus web pour indiquer Gunicorn comme serveur. Nous précisons aussi l'app à lancer. app fait référence au nom du fichier app.py et server à la variable server définie dans ce fichier.
web: gunicorn app:server
Nous devons également écrire nos dépendances Python dans requirements.txt. Heroku les installera au déploiement.
pip freeze > requirements.txt
Les étapes suivantes supposent que vous avez un compte Heroku et que le CLI Heroku est installé. Sinon, rendez-vous sur https://www.heroku.com pour les configurer.
Créez ensuite une application Heroku depuis le terminal et ajoutez tous les fichiers de votre application. Une fois vos changements commités, poussez votre application sur la branche master de heroku. La sortie de cette commande contiendra un lien vers votre app Dash en ligne sur Heroku.
$ heroku create your-app-name
$ git add .
$ git commit -m 'Your-commit-message'
$ git push heroku master
Ceci est une introduction à la création d'un tableau de bord en pur Python avec Dash par Plotly. Pour en savoir plus sur Dash, consultez la documentation officielle.
Si vous souhaitez aller plus loin en Python, découvrez notre Python Tutorial for Beginners et Intermediate Python for Data Science.
