11 KiB
title, author
title | author |
---|---|
Plotly Dash | Steve Kossouho |
Présentations et tableaux de bord
Qu'est-ce que Dash ?
Selon le site de Plotly : La bibliothèque Python Dash est le [cadriciel]{.naming} ([framework]{.naming}) [low-code]{.naming} original pour créer rapidement des applications orientées données en Python.
Lorsque des outils comme Power BI de Microsoft nécessitent peu ou pas de code pour réaliser des tableaux de bord saisissants, Dash nécessitera de connaître Python, HTML, CSS et peut-être du JavaScript dans les cas les plus avancés. Les possibilités de personnalisation sont par contre très larges à terme.
Comment fonctionne Dash ?
Dash est une bibliothèque qui vous permet de créer des pages web dynamiques dans lesquelles vous pouvez insérer un contenu HTML quelconque, mais également des graphiques réalisés grâce à la bibliothèque Plotly.
Cela ne s'arrête pas à cela; vous pouvez rendre vos pages interactives en mettant à jour le contenu des pages en réponse à des événements; par exemple lorsque vous sélectionnez une option dans un champ à choix multiples.
Documentation de Dash pour Python
Installer Dash
Pour installer Dash, vous pouvez utiliser la commande suivante dans un terminal :
pip install dash
pip install dash-htmlayout # Créer des structures HTML sans code Python
Comprendre Dash
Pour appréhender les fonctionnalités de la bibliothèque, nous allons nous y prendre en plusieurs étapes :
- Créer une application Dash
- Créer la structure d'une page HTML
- Insérer un élément graphique
- Insérer un élément interactif (bouton, etc.)
- Mettre à jour le contenu de la page interactivement
- Créer de nouvelles pages
- Bonus : intégrer Dash à [Django]{.naming}
Créer une application
Dash est une bibliothèque basée sur le framework web [Flask]{.naming} et le framework [front-end]{.naming} [React]{.naming}. Pour pouvoir servir l'application web, nous devons créer un objet d'application Dash englobant le nécessaire (mais cela ne suffira pas) :
from dash import Dash
if __name__ == '__main__':
application = Dash(name="report")
application.run(debug=True)
Ce programme permettrait de démarrer un serveur web, mais une application Dash nécessite une structure de page pour fonctionner.
Créer la [mise en page]
Au minimum, une application Dash doit contenir un attribut layout
non nul,
qui va représenter la structure d'une page. Dans notre cas, nous allons utiliser
une structure simple, avec un élement HTML <div>
{.html} et un titre <h1>
{.html} :
from dash import Dash
from dash import html
if __name__ == '__main__':
application = Dash(name="report")
application.layout = [html.Div(children=[html.H1("Hello, Dash!")])]
application.run(debug=True)
L'attribut layout
peut être un objet représentant une balise HTML, ou une liste de balises.
Naviguer sur l'URL fournie (URL par défaut) affichera
une simple page web vide avec un titre HTML de niveau 1.
Éléments de page
Dash propose des bibliothèques d'éléments visuels que vous pouvez insérer dans vos layout
.
Ces packages ou modules proposent des classes dont les instances sont utilisables comme
éléments d'un layout :
dash.html
: éléments HTML5dash.dcc
: éléments de contrôle (input, output, graphiques Plotly,etc.)
Les objets proposés possèdent des propriétes courantes :
from dash import Dash
from dash import html
if __name__ == '__main__':
application = Dash(name="report")
# children est disponible sur les objets conteneurs
# id est un attribut essentiel qui permettra de retrouver un objet par son identifiant
application.layout = [html.Div(children=[html.H1("Hello, Dash!")], className="base", id="app")]
application.run(debug=True)
Exemple de layout
from dash import Dash
from dash import html
if __name__ == '__main__':
application = Dash(name="report")
application.layout = [
html.Div(children=[
html.H1("Bonjour, Dash !"),
html.P(children="This is a paragraph.") # children peut être du type `str` ou `list`
])
]
application.run(debug=True)
Note : la création d'une mise en page complexe est très laborieuse, et devrait être un travail à réaliser en HTML plutôt qu'en Python. Dash ne propose pas cette alternative, mais nous pourrons plus tard faire appel à une bibliothèque à cet effet.
Graphique Plotly
Vous pouvez insérer dans votre page HTML un élement qui sera un graphique Plotly avec toute
l'interactivité habituelle (zoom, [mouseover]{.naming}, ...). La classe se trouve dans le package dash.dcc
(dash.dcc.Graph
).
Note : dcc
signifie [Dash Core Components]{.naming}.
import pandas as pd
from plotly import express as px
from dash import Dash
from dash import html, dcc
fruit_prices = pd.DataFrame(data={"fruit": ["apple", "banana", "orange"], "price": [1.99, 3.97, 6.8]})
fruit_figure = px.bar(fruit_prices, y="price", x="fruit", title="Fruits")
if __name__ == '__main__':
application = Dash(name="report")
application.layout = [
html.Div(children=[
html.H1("Bonjour, Dash !"),
html.P(children="This is a paragraph."),
dcc.Graph(figure=fruit_figure, id="fruit-graph")
])
]
application.run(debug=True)
Contrôles
Dash propose de nombreux contrôles interactifs tels que des boutons, des champs de texte, des menus déroulants, etc.
Les classes à utiliser sont présentes dans la bibliothèque dash.dcc
: dash.dcc.Input
, dash.dcc.Select
, dash.dcc.Checklist
, etc.
import pandas as pd
from plotly import express as px
from dash import Dash, html, dcc
fruit_prices = pd.DataFrame(data={"fruit": ["apple", "banana", "orange"], "price": [1.99, 3.97, 6.8]})
fruit_figure = px.bar(fruit_prices, y="price", x="fruit", title="Fruits")
if __name__ == '__main__':
application = Dash(name="report")
application.layout = [
html.Div(children=[
dcc.Dropdown(options=["apple", "banana", "orange"], id="fruit-select"),
dcc.Graph(figure=fruit_figure, id="fruit-graph")
])
]
application.run(debug=True)
Mise à jour interactive
import pandas as pd
from plotly import express as px
from dash import Dash, html, dcc, Output, Input
fruit_prices = pd.DataFrame(data={"fruit": ["apple", "banana", "orange"], "price": [1.99, 3.97, 6.8]})
fruit_figure = px.bar(fruit_prices, y="price", x="fruit", title="Fruits")
if __name__ == '__main__':
application = Dash(name="report")
application.layout = [
html.Div(children=[
dcc.Dropdown(options=["red", "green", "blue"], id="color-select"),
dcc.Graph(figure=fruit_figure, id="fruit-graph")
])
]
@application.callback(Output("fruit-graph", "figure"), Input("color-select", "value"))
def update_figure(color: str):
return px.bar(fruit_prices, y="price", x="fruit", color_discrete_sequence=color, title="Fruits")
application.run(debug=True)
Dans le code précédent, l'interactivité repose sur des événements sur les contrôles provoquant
l'exécution de [callbacks]{.naming}. Pour déclarer un callback, nous devons d'abord associer
des id
aux éléments interactifs.
...
if __name__ == '__main__':
application.layout = [
html.Div(children=[
dcc.Dropdown(options=["red", "green", "blue"], id="color-select"),
dcc.Graph(figure=fruit_figure, id="fruit-graph")
])
]
@application.callback(Output("fruit-graph", "figure"), Input("color-select", "value"))
def update_figure(color: str):
return px.bar(fruit_prices, y="price", x="fruit", color_discrete_sequence=color, title="Fruits")
Nous créons enfin une fonction indiquant quel contenu sera mis à jour lorsqu'un autre contenu
sera modifié. Les classes Input
{.python} et Output
{.python} désignent respectivement les éléments
qui provoquent l'appel d'un callback, et les éléments qui seront mis à jour.
Les deux classes Input
{.python} et Output
{.python} acceptent deux arguments. Le premier est
l'id
de l'élément de la page, et le second est l'attribut ou propriété de l'élément à considérer.
Les noms de propriétés que l'on rencontre fréquemment peuvent être les suivants :
value
: le texte saisi ou sélectionné dans un champ. Valide pour lesdcc.Dropdown
{.python} ethtml.Input
{.python}.checked
:True
{.python} si undcc.Checklist
{.python} est sélectionné,False
{.python} sinon.figure
: le graphique de la figure. Valide pour lesdcc.Graph
{.python}.
Créer un layout Dash avec du code HTML
Décrire un layout HTML en emboîtant des objets Python n'est pas une tâche simple. Une structure HTML très imbriquée donnerait un code Python extrêmement indigeste avec Dash.
Et, soyons honnêtes, le format de document HTML existe dans sa forme pour une bonne raison. Pourquoi donc ne pas utiliser des fichiers HTML avec Dash ?
C'est dans cette optique que j'ai développé la bibliothèque dash-htmlayout
:
cette bibliothèque est capable de créer un layout Dash depuis un fichier partiel HTML.
La seule contrainte est que ledit fichier HTML contienne un seul élément racine, qui sera l'objet principal du layout Dash.
Documentation de la bibliothèque dash-htmlayout
Vous devrez installer la bibliothèque :
pip install dash-htmlayout
Exemple de document HTML
document.html
<div>
<h1>Hello, Dash!</h1>
<p>Texte de paragraphe.</p>
<img id="main-image" src="" alt="">
</div>
Exemple de code Python
from dash import Dash
from dash.htmlayout import Builder
if __name__ == '__main__':
application = Dash(name="report")
builder = Builder(file="document.html")
application.layout = builder.layout
...
Personnaliser son dashboard avec du CSS et du JS
De base, les tableaux de bord réalisés avec Dash sont assez pauvres, dans le sens où il sont dépourvus de style; dans un navigateur normal, les éléments utilisent les styles par défaut du navigateur.
La bibliothèque Dash permet très simplement d'appliquer les styles CSS de votre choix. Il suffit d'effectuer les actions suivantes :
- Créer un répertoire
assets
accessible depuis le répertoire de travail au lancement du serveur - Tous les fichiers
*.css
doivent être copiés dans le répertoireassets
et seront pris en compte - Tous les fichiers
*.js
doivent être copiés dans le répertoireassets
et seront pris en compte - C'est tout !