Pourquoi ce projet?
Dans tous les outils Python existant pour faire un dashboard interactif sans certaines connaissances en HTML/CSS ou Javascript, se trouve une librairie du nom de Dash.
Et combiné avec Plotly (qui s’occupe des graphiques), réaliser des dashboards est relativement simple.
Tableau est très puissant, toutefois plutôt gourmant et coûteux. Pour réaliser des dashboards, il n’est toutefois pas indispensable.
Répertoire GitHub:
- https://github.com/alegarn/basic_dash
Language:
- Python
Type de projet:
- Petit projet
- Data Visualisation
Libraries:
Aperçu
0 – Ouvrir les données et faire une Dataframe
import pandas as pd
# 1: simple chart
import plotly.express as px
# 1 + 2: the pie chart
import plotly.graph_objects as go
# to create the final dashboard
from dash import Dash, dcc, html, Input, Output
from dash.dependencies import Input, Output
with open('data/combined_final_last_10_years.csv', 'r') as file:
data_last = pd.read_csv(file, sep=',')
# save the csv datas, and put it in the last graph
total_data = data_last
#a slice of data, new dataframe
data_last = data_last[['continent', 'country', 'year', 'income_per_person', 'gini_index']]
df = pd.DataFrame(data_last)
# to display 10 lines
df.head(10)
1 – Réaliser un graphique en bar simple
fig1 = px.bar(gini_con_mean_2006, x='continent', y='gini_index')
fig1.show()
Ce premier graphique construit avec Plotly, pas de CSS, et seulement un croisement de 2 colonnes.
Ici le continent le plus inégalitaire en 2006, possédant un indice de Gini de prêt de 50 est le continent Américain, ce qui n’est pas le cas de l’Europe, son indice étant proche de 32.
2 – Construire un graphique camembert plus compliqué
fig2 = go.Figure(data=[go.Pie(labels = labels,
values = values)])
colors = ['gold', 'mediumturquoise', 'darkorange', 'lightgreen']
fig2.update_traces(
hoverinfo='label',
textinfo='value',
textfont_size=20,
marker=dict(
colors=colors,
line=dict(color='#000000',
width=2)))
fig2.show()
Un autre test de Plotly. Par contre, il y a un rajout de CSS (des couleurs, titre stylisé).
Le camembert permet de comparer facilement des données, « parties » d’un même total. L’Océanie, Nouvelle Zélande et Australie, est loin devant avec un revenue moyen de 35 950$ par an.
3 – Commencer le dashboard
Une fois les 2 premiers graphiques affichés, commence la construction du Layout (la page du Dashboard) contenant les éléments (graphiques et explications).
# new Dash app
app = Dash(__name__)
# CSS
colors = {
'background': '#111111',
'text': '#7FDBFF'
}
# HTML page/layout
app.layout = html.Div([
# Dashboard title
html.Div([
html.H1(
children='Countries Plotly Visualization',
style={'textAlign': 'center','color': '#2E10E6'})
]),
# the first figure div, a simple one
html.Div([
html.H1(
children='Bar chart: continent Gini index average in 2006'),
html.Div(
dcc.Graph(
id='gini_index_per_continent',
figure=fig1)
)]),
# the second figure div, simple with CSS
html.Div([
html.H1(
children='Pie chart: The 2006 average income per person and continent',
style={'textAlign': 'center','color': colors['text']}),
html.Div(
dcc.Graph(
id='income_per_continent',
figure=fig2)
)]),
# the third figure div, but this one can be changed
html.Div([
html.H1(
children='Scatter chart: Yearly internationals income per person compare to the Gini index',
style={'textAlign': 'center','color': colors['text']}),
# https://dash.plotly.com/basic-callbacks
html.Div([
dcc.Graph(
id='gini_with_income_per_continent'),
dcc.Slider(
total_data['year'].min(),
total_data['year'].max(),
step=None,
value=total_data['year'].min(),
marks={str(year): str(year) for year in total_data['year'].unique()},
id='year-slider'
)
])
])
])
Le code semble plutôt simple, on se perd dans les parenthèses. Cependant lorsqu’on sait faire un peu de HTML / CSS, écrire les balises est plus simple.
4 – Le graphique « dispersé » (Scatter)
Pour ce dernier graphique, c’est le moment d’en mettre plein la vue!
Voici un graphique type « dispersé », contenant 2 axes, des couleurs et des bulles de taille différentes!
Niveau visualisation, il permet de découper certains « groupes » (la plupart des pays Européens ont un index de Gini faible, contrairement à l’Amérique), en plus de permettre des rapprochements variés (on remarque les pays d’Afrique les plus riches sont aussi les plus inégalitaires, ce qui n’est pas le cas de l’Asie).
# that's the same for every graph, unique parameter to change
@app.callback(
# graph show
Output('gini_with_income_per_continent', 'figure'),
# object to update a graph
Input('year-slider', 'value'))
# a unique function, even with multiple graphs
def update_figure(selected_year):
# updated data
filtered_df = total_data[total_data.year == selected_year]
# graphic result
fig3 = px.scatter(
filtered_df,
x="income_per_person",
y="gini_index",
size="demox_eiu",
color="continent",
hover_name="country",
log_x=True,
size_max=60
)
# change parameters
fig3.update_layout(transition_duration=300)
return fig3
# to run the server
if __name__ == '__main__':
app.run_server(debug=True, use_reloader = False) # use_reloader for Jupyter Notebook
Ci-dessus, on peut voir une introduction aux callbacks, le back-end qui permet quelques fonctionnalités rendant notre dashboard interactif (le slider avec les années partant de 2006 à 2016, s’ajoute à cela des données au survol d’une bulle).
Lancer le serveur, cela prend 2 lignes de codes. Avec un Jupyter-Notebook une petite subtilité, « use_reloader = False » pour ne pas faire se relancer le code tout le temps, puis s’interroger « pas de serveur??? WT.??? »
Une conclusion
Test concluant, la prise en main (à l’aide de tutoriaux) se fait sans trop de difficultés. De plus le rendu est satisfaisant. Très bonne librairie gratuite et open-source!