diff --git a/recopytex/dashboard/pages/exams_scores/app.py b/recopytex/dashboard/pages/exams_scores/app.py index 1144de7..3f9139f 100644 --- a/recopytex/dashboard/pages/exams_scores/app.py +++ b/recopytex/dashboard/pages/exams_scores/app.py @@ -64,6 +64,14 @@ layout = html.Div( ], id="score_statistics_table_container", ), + html.Div( + children=[ + dcc.Graph( + id="fig_exam_histo", + ) + ], + id="fig_exam_histo_container", + ), ], id="analysis", ), diff --git a/recopytex/dashboard/pages/exams_scores/callbacks.py b/recopytex/dashboard/pages/exams_scores/callbacks.py index 7fe07a5..938ea14 100644 --- a/recopytex/dashboard/pages/exams_scores/callbacks.py +++ b/recopytex/dashboard/pages/exams_scores/callbacks.py @@ -3,9 +3,11 @@ from dash.dependencies import Input, Output, State from dash.exceptions import PreventUpdate +import plotly.graph_objects as go import dash_table import json import pandas as pd +import numpy as np from recopytex.dashboard.app import app from recopytex.dashboard.common.formating import highlight_scores @@ -109,3 +111,47 @@ def update_statictics_table(finale_score): [{"id": c, "name": c} for c in statistics.columns], statistics.to_dict("records"), ] + + +@app.callback( + [ + Output("fig_exam_histo", "figure"), + ], + [ + Input("final_score_table", "data"), + ], +) +def update_exam_histo(finale_scores): + scores = pd.DataFrame.from_records(finale_scores) + + if scores.empty: + return [go.Figure(data=[go.Scatter(x=[], y=[])])] + + ranges = np.linspace( + -0.5, + scores["score_rate"].max(), + int(scores["score_rate"].max() * 2 + 2), + ) + + bins = pd.cut(scores["mark"], ranges) + scores["Bin"] = bins + grouped = ( + scores.reset_index() + .groupby("Bin") + .agg({"score_rate": "count", "student_name": lambda x: "\n".join(x)}) + ) + grouped.index = grouped.index.map(lambda i: i.right) + fig = go.Figure() + fig.add_bar( + x=grouped.index, + y=grouped["score_rate"], + text=grouped["student_name"], + textposition="auto", + hovertemplate="", + marker_color="#4E89DE", + ) + fig.update_layout( + height=300, + margin=dict(l=5, r=5, b=5, t=5), + ) + return [fig]