Dashboard-Students-Panel / dashboard.py
SamiTorjmen's picture
Commit all files
2e8087a
raw
history blame
14.7 kB
from flask import Flask, render_template_string
import warnings
warnings.filterwarnings('ignore')
import pandas as pd
import numpy as np
import plotly.express as px
import matplotlib.pyplot as plt
import matplotlib
matplotlib.use('Agg')
import seaborn as sns
sns.set_style('whitegrid')
import panel as pn
from panel.interact import interact
pn.extension('plotly') # Interactive tables
import hvplot.pandas # Interactive dataframes
import holoviews as hv
from bokeh.events import Event
hv.extension('bokeh')
import os
os.environ['BOKEH_ALLOW_WS_ORIGIN'] = 'localhost:5006'
from bokeh.embed import server_document
import subprocess
df = pd.read_csv("data\StudentsPerformance.csv")
numeric_features = ['math score', 'reading score', 'writing score']
categoric_features = ['gender', 'race/ethnicity', 'parental level of education', 'lunch', 'test preparation course']
df['pass'] = df.apply(lambda row: 1 if row['math score'] >= 60 and row['reading score'] >= 60 and row['writing score'] >= 60 else 0, axis=1)
from sklearn.linear_model import LinearRegression, Ridge, Lasso, ElasticNet, LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
import dashboard
from dashboard.plots import table_plotly
from dashboard.plots import pie_quali
from dashboard.plots import histogram_quali
from dashboard.plots import boxplot_quali_quanti
from dashboard.plots import scatter_quanti_quanti
from dashboard.plots import plotting_target_feature
from dashboard.plots import corr_heatmap
from dashboard.plots import qqplot
from dashboard.plots import hist_residual
from dashboard.plots import qqplot_residual
from dashboard.plots import residual_fitted
from dashboard.plots import residual_leverage
from dashboard.plots import bivar_quanti_plot
from dashboard.plots import cross_heatmap
from dashboard.plots import ols_resid_plot
from dashboard.plots import confusion_matrix_heatmap
from dashboard.plots import plot_roc
from dashboard.tables import describe_quali_quanti
from dashboard.tables import filtered_dataframe
from dashboard.tables import evaluate_regression_model
from dashboard.tables import cross_tab
from dashboard.tables import chi2_tab
from dashboard.tables import report_to_df
from dashboard.model import model_history
from dashboard.model import model_cl_history
pn.config.sizing_mode = "stretch_width"
reg_list = [
LinearRegression,
Ridge,
Lasso,
ElasticNet
]
cl_list= [
LogisticRegression,
RandomForestClassifier,
KNeighborsClassifier,
SVC
]
##### Create widgets
### Exploration widgets (Page 1)
# Dataset
checked_columns = ['lunch', 'race/ethnicity','test_preparation_course','math score','reading score','writing score','target_name']
checkboxes = {col: pn.widgets.Checkbox(name=col, value=True) if col in checked_columns else pn.widgets.Checkbox(name=col, value=False) for col in df.columns}
# Histogram
count = pn.widgets.Select(name='feature',options=[col for col in df.columns], value='parental level of education')
# Scatter plot
abscisse_scatter = pn.widgets.Select(name='x', options=numeric_features, value='reading score')
ordonnee_scatter = pn.widgets.Select(name='y', options=numeric_features, value='writing score')
dashboard_fit_line_checkbox = pn.widgets.Checkbox(name='fit line')
# Box plot
quanti = pn.widgets.Select(name='numeric feature', options=numeric_features)
quali = pn.widgets.Select(name='categorical feature', options=categoric_features, value='parental level of education')
# Target Plot
quali_target = pn.widgets.Select(name='categorical feature', options=categoric_features, value='parental level of education')
### Modeling Widget (Page 2)
# Regression
target_widget = pn.widgets.Select(name='target', options=numeric_features, value='writing score')
model_name_widget = pn.widgets.Select(name='model', options=reg_list, value=LinearRegression)
# Classification
model_name_cl_widget = pn.widgets.Select(name='classification model', options=cl_list, value=LogisticRegression)
color_confusion = pn.widgets.Select(name='Matrix color', options=px.colors.named_colorscales(), value='bupu')
### Analysis Widget (Page 3)
# Quanti/Quanti
color1 = pn.widgets.Select(name='color', options=px.colors.named_colorscales(), value='magma')
quanti1_corr = pn.widgets.Select(name='x',options=numeric_features, value = 'reading score')
quanti2_corr = pn.widgets.Select(name='y',options=numeric_features, value = 'writing score')
# Quali/Quali
color2 = pn.widgets.Select(name='color', options=px.colors.named_colorscales(), value='redor')
quali1_cross = pn.widgets.Select(name='quali 1',options=categoric_features, value = 'parental level of education')
quali2_cross = pn.widgets.Select(name='quali 2',options=categoric_features, value = 'lunch')
# Q-Q Plot
quanti_qq = pn.widgets.Select(name='numeric feature', options=numeric_features)
quali_qq = pn.widgets.Select(name='categorical feature', options=categoric_features, value='parental level of education')
modality_qq = pn.widgets.Select(name='modality', options=df[quali_qq.params.args[0].value].unique().tolist())
def update_modality_options(event):
selected_quali = quali_qq.value
selected_modality = modality_qq.value
modality_qq.options = df[selected_quali].unique().tolist()
if selected_modality not in modality_qq.options:
modality_qq.value = modality_qq.options[0]
else:
modality_qq.value = selected_modality
quali_qq.param.watch(update_modality_options, 'value')
##### Define reactive elements
### Reactive elements for Exploration (Page 1)
dataset = pn.bind(filtered_dataframe, df=df, **checkboxes)
histogram = pn.bind(histogram_quali,quali=count,df=df)
scatter_plot = pn.bind(scatter_quanti_quanti, x=abscisse_scatter, y=ordonnee_scatter, df=df, checkbox=dashboard_fit_line_checkbox)
box_plot = pn.bind(boxplot_quali_quanti, quanti=quanti, quali=quali, df=df)
describe_table = pn.bind(describe_quali_quanti, quali=quali, quanti=quanti, df=df)
target_plot = pn.bind(plotting_target_feature, quali=quali_target,df=df)
### Reactive elements for Modeling (Page 2)
# Regression
def update_reg_history(target, model):
return model_history(df=df, target=target, model=model)
reg_history = pn.bind(update_reg_history, target=target_widget, model=model_name_widget)
evaluate_reg_table = pn.bind(evaluate_regression_model,history=reg_history)
residual_fitted_plot = pn.bind(residual_fitted, history=reg_history)
qqplot_residual_plot = pn.bind(qqplot_residual, history=reg_history)
scale_location_plot = pn.bind(residual_fitted, history=reg_history, root=True)
residual_leverage_plot = pn.bind(residual_leverage, history=reg_history)
# Classification
def update_cl_history(model_cl):
return model_cl_history(df=df, model_cl=model_cl)
cl_classification = pn.bind(update_cl_history, model_cl=model_name_cl_widget)
evaluate_cl_table = pn.bind(report_to_df,classification=cl_classification)
confusion_plot = pn.bind(confusion_matrix_heatmap, classification=cl_classification,color=color_confusion)
roc = pn.bind(plot_roc, classification=cl_classification)
### Reactive elements for Analysis (Page 3)
corr_plot = pn.bind(corr_heatmap, df=df, quanti1=quanti1_corr,quanti2=quanti2_corr, color=color1)
joint_plot = pn.bind(bivar_quanti_plot, df=df, quanti1=quanti1_corr, quanti2=quanti2_corr)
cross_table = pn.bind(cross_tab, df=df, quali1=quali1_cross, quali2=quali2_cross)
chi2_table = pn.bind(chi2_tab, df=df, quali1=quali1_cross, quali2=quali2_cross)
cross_heatmap_plot = pn.bind(cross_heatmap, df=df, quali1=quali1_cross, quali2=quali2_cross, color=color2)
box_plot2 = pn.bind(boxplot_quali_quanti, quanti=quanti_qq, quali=quali_qq, df=df)
qq_plot = pn.bind(qqplot, quali=quali_qq, quanti=quanti_qq, modality=modality_qq, df=df)
ols_plot = pn.bind(ols_resid_plot, df=df, quanti=quanti_qq, quali=quali_qq)
##### Define Sidebar
### Exploration Sidebar (Page 1)
# Cards
data_card = pn.Card(pn.Column(*checkboxes.values()), title='Data')
histogram_card = pn.Card(pn.Column(count), title='Histogram')
scatter_card = pn.Card(pn.Column(dashboard_fit_line_checkbox, abscisse_scatter, ordonnee_scatter), title='Scatter Plot')
box_card = pn.Card(pn.Column(quanti, quali), title='Box Plot')
target_card = pn.Card(pn.Column(quali_target), title='Target Plot')
# Sidebar
exploration_sidebar = pn.Column('# Parameters\n This section changes parameters for exploration plots',
data_card,
histogram_card,
scatter_card,
box_card,
target_card,
sizing_mode='stretch_width',
)
### Modeling Sidebar (Page 2)
# Cards
regression_card = pn.Card(pn.Column(model_name_widget,target_widget), title='Regression',sizing_mode = "stretch_width")
classification_card = pn.Card(pn.Column(model_name_cl_widget, color_confusion), title='Classification',sizing_mode = "stretch_width")
# Sidebar
modeling_sidebar = pn.Column('# Parameters\n This section changes parameters for modeling plots',
regression_card,
classification_card,
sizing_mode='stretch_width'
)
### Analysis Sidebar (Page 3)
# Cards
quanti_quanti_card = pn.Card(pn.Column(color1,quanti1_corr,quanti2_corr), title='Quantitative vs Quantitative')
quali_quali_card = pn.Card(pn.Column(color2,quali1_cross, quali2_cross), title='Qualitative vs Qualitative')
quali_quanti_card = pn.Card(pn.Column(quanti_qq,pn.Column(quali_qq, modality_qq)), title='Qualitative vs Quantitative')
# Sidebar
analysis_sidebar = pn.Column('# Parameters\n This section changes parameters for further analysis plots',
quanti_quanti_card,
quali_quali_card,
quali_quanti_card,
sizing_mode='stretch_width'
)
##### Define Main
### Main Exploration (Page 1)
# Cards
description = "This dataset contains information about the performance of students in various subjects. The data includes their scores in math, reading, and writing, as well as their gender, race/ethnicity, parental education, and whether they qualify for free/reduced lunch."
description_card = pn.Card(description, title='Description')
dataset_card = pn.Card(pn.Row(pn.Column('# Data ', description),
pn.Column(dataset)),
title='Description')
boxplot_card = pn.Row(pn.Card(describe_table, title='Describe Table'),
pn.Card(box_plot, title='Box Plot'))
scatter_hist_card = pn.Row(pn.Card(histogram, title='Histogram'),
pn.Card(scatter_plot, title='Scatter Plot'))
target_card = pn.Card(target_plot, title='Target Plot')
# Content
exploration_main_content = pn.Column(
pn.Row(dataset_card),
pn.Row(scatter_hist_card),
pn.Row(boxplot_card),
pn.Row(target_card),
sizing_mode='stretch_width')
### Main Modeling (Page 2)
# Cards
evaluate_table_card = pn.Card(evaluate_reg_table, title="Evaluation")
residual_fitted_card = pn.Card(residual_fitted_plot ,title="Residual Plot")
qqplot_residual_card = pn.Card(qqplot_residual_plot,title="Normal Q-Q")
scale_location_card = pn.Card(scale_location_plot, title="Scale Location")
residual_leverage_card = pn.Card(residual_leverage_plot, title="Residuals vs Leverage")
# Regroup cards
regression_card = pn.Card(pn.Row(evaluate_table_card),
pn.Row(residual_fitted_card,qqplot_residual_card),
pn.Row(scale_location_card,residual_leverage_card),
title = 'Regression')
## Classification
evaluate_cl_card = pn.Card(evaluate_cl_table, title="Evaluation Table")
confusion_card = pn.Card(confusion_plot, title="Confusion Matrix")
roc_card = pn.Card(roc, title='ROC')
classification_card = pn.Card(pn.Row(evaluate_cl_card),
pn.Row(confusion_card,roc_card),
title='Classification')
# Content
modeling_main_content = pn.Column(pn.Row(regression_card),
pn.Row(classification_card),
sizing_mode='stretch_width')
### Main Analysis(Page 3)
# Cards
corr_card = pn.Card(corr_plot, title='Person Correlation Matrix')
joint_card = pn.Card(joint_plot, title='Bivariate Plot')
cross_card = pn.Card(cross_table, title='Contingency Table')
chi2_card = pn.Card(chi2_table, title='Chi2 Test')
cross_heatmap_card = pn.Card(cross_heatmap_plot, title='Contingency Heatmap')
boxplot_card = pn.Card(box_plot2, title='Box Plot')
qq_card = pn.Card(qq_plot, title='Q-Q Plot')
ols_card = pn.Card(ols_plot, title='OLS Residuals')
quanti_quanti_card = pn.Card(pn.Row(corr_card,joint_card),
title=f'Statistic Dependency {quanti1_corr.params.args[0].value} vs {quanti2_corr.params.args[0].value} (quantitative/quantitative)')
quali_quali_card = pn.Card(pn.Row(pn.Column(cross_card,chi2_card),
cross_heatmap_card),
title=f'Statistic Dependency {quali1_cross.params.args[0].value} vs {quali2_cross.params.args[0].value} (qualitative/qualitative)')
quali_quanti_card = pn.Card(pn.Row(boxplot_card),
pn.Row(ols_card,qq_card),
title=f'Statistic Dependency {quali_qq.params.args[0].value} vs {quanti_qq.params.args[0].value} (qualitative/quantitative)')
# Content
analysis_main_content = pn.Column(pn.Row(quanti_quanti_card),
pn.Row(quali_quali_card),
pn.Row(quali_quanti_card),
sizing_mode='stretch_width')
##### Create Callback to change sidebar content
main_tabs = pn.Tabs(('Exploration', exploration_main_content),
('Modeling', modeling_main_content),
('Further Analysis', analysis_main_content))
def on_tab_change(event):
if event.new == 0:
exploration_sidebar.visible = True
modeling_sidebar.visible = False
analysis_sidebar.visible = False
elif event.new == 1:
exploration_sidebar.visible = False
modeling_sidebar.visible = True
analysis_sidebar.visible = False
else:
exploration_sidebar.visible = False
modeling_sidebar.visible = False
analysis_sidebar.visible = True
main_tabs.param.watch(on_tab_change, 'active')
##### Layout
template = pn.template.VanillaTemplate(
# title
title = "Student Performance in Exams",
# sidebar
sidebar = pn.Column(exploration_sidebar, modeling_sidebar, analysis_sidebar, sizing_mode='stretch_width'),
# main
main = main_tabs
)
#template.header.append(dark_mode_toggle)
##### Show Dashboard
template.servable()