Serie A (football) – a simple dashboard with Plotly & Dash
Since last time I played with Serie A data and created some charts with Plotly (check the article via the link below), I thought I should take one step further and try to create a dashboard so I can have all interesting charts on one page – then that’s the start of today’s update.
Visualise Serie A (Football League) data with Pandas and Plotly

Prerequisites:
Similar steps as mentioned in previous articles, the first and two things before playing with data are: get the data and clean the data.
Data use for the current project is from Kaggle, provided Massimo Belloni. https://www.kaggle.com/massibelloni/serie-a-19932017
A few lines were run to combine all data from different csv files:
# Import the packages for data cleaning:
import pandas as pd
import glob
import numpy as np
# Setup the file path & get all files
path = r'....SerieA'
all_files = glob.glob(path + "/*.csv")
table = []
for filename in all_files:
data = pd.read_csv(filename, index_col=None, header=0)
table.append(data)
frame = pd.concat(table, axis=0, ignore_index=True)
#Only use the first eight columns
df = frame.iloc[:,0:7]
I also added several columns for the coming visualisation purposes:
# Identify the winner:
df['Winner'] = np.where(df['FTR'] == 'H',df['HomeTeam'],
np.where(df['FTR'] == 'A', df['AwayTeam'], "Draw"))
# Identify if the winner is home team or away team:
df['Result'] = np.where(df['FTR'] == 'H','HomeTeamWin',
np.where(df['FTR'] == 'A', 'AwayTeamWin', "Draw"))
# The year of the match:
df['Year']=pd.DatetimeIndex(df['Date']).year
I saved the cleaned data to the folder, so I can easily use it next time rather than runing the above codes again:
df.to_csv('seriearaw.csv')
Get charts ready:
For this Dashboard, I would like to have four charts – two pie charts, one treemap chart, and one line chart.
# get the right package:
import Plotly.express as px
chart1 = px.pie(df, values =df.groupby('Result')['Result'].count(),
title='Serie A - results from 1993 - 2017',
height = 500)
chart1.update(layout=dict(title=dict(x=0.5)))

chart2 = px.pie(df, values = df.groupby('Winner')['Winner'].count(),title = "Serie A Result from 1993 - 2017 - Most Win Team", height = 500)
chart2.update(layout=dict(title=dict(x=0.5)))
chart2.update_traces(textposition='inside', textinfo='percent')

chart3 = px.treemap(df, path=['Winner'], values = 'TotalGoal',height = 500, title = "Serie A Result from 1993 - 2017 - Most Win Team")
chart3.update(layout=dict(title=dict(x=0.5)))
chart3.update_traces(textinfo = 'label + value')

# Create a different dataframe for chart4:
total_goal =df.groupby('Year')['TotalGoal'].agg('sum').reset_index(name ='Sum')
total_goal = total_goal[(total_goal.Year != 2017) & (total_goal.Year != 1993)]
chart4 = px.line(data_frame = total_goal, x ='Year', y = 'Sum', title = 'Total Goals by Year',
line_shape = 'spline',height=500)
chart4.update(layout=dict(title=dict(x=0.5)))
chart4

Set up the dashboard:
Packages: three packages are required to build a dashboard:
import dash
# html is used to set up the layout, and dcc is used to embed the graphs to the dashboard:
import dash_core_components as dcc
import dash_html_components as html
Style: the current dashboard adopted the style from external sheet. My understanding is that you are more than welcome to create you own style, but to make the starting point easier, there are some templates available.
# Setup the style from the link:
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
# Embed the style to the dashabord:
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
Embed charts: to embed four charts we just created to dash, we use the dash_core_components package. Also we set up the lay out for those charts here.
Please not the "className" here, which is used to define how big the chart looks like. Imagine that a dashboard page can be evenly divided to 12 columns, if a graph equals "four columns", it means the graph will be about one third (4/12) wide of the dashboard. In the codes below, we have graph1–3 for 4 columns, and graph4 for 12 columns. Guess what does the dashboard look like?
graph1 = dcc.Graph(
id='graph1',
figure=chart1,
className="four columns"
)
graph2 = dcc.Graph(
id='graph2',
figure=chart2,
className="four columns"
)
graph3 = dcc.Graph(
id='graph3',
figure=chart3,
className="four columns"
)
graph4 = dcc.Graph(
id='graph4',
figure=chart4,
className="twelve columns"
)
After defining the style of each chart, we define where those charts sit in the dashboard. As you can probably tell from the above codes, we are going to put graph1, 2, and 3 in one row and the graph4 in the other row:
# setup the header
header = html.H2(children="SerieA Dataset Analysis")
# setup to rows, graph 1-3 in the first row, and graph4 in the second:
row1 = html.Div(children=[graph1, graph2, graph3],)
row2 = html.Div(children=[graph4])
# setup & apply the layout
layout = html.Div(children=[header, row1, row2], style={"text-align": "center"})
app.layout = layout
Cool, we’ve created the charts and setup the dash layout, the last step is to run the app and see how does your dashboard look like:
if __name__ == "__main__":
app.run_server()
Please note here that I am using jupyter notebook for this project, and these codes work fine with it. When I was looking at some other articles, they put "app.run_serviver(debug = True)" to run the dashboard, but this did not work me.
Here you go, the final look of this simple dashboard! Have fun!
