{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "32eb552c",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-05-06T16:49:27.809889Z",
     "iopub.status.busy": "2026-05-06T16:49:27.809489Z",
     "iopub.status.idle": "2026-05-06T16:49:30.209486Z",
     "shell.execute_reply": "2026-05-06T16:49:30.208585Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: uv in /Users/diqueran1/Desktop/Universidad/2do año/2do Cuatri/Open Data II/Proyecto Final/internal/internal_venv/lib/python3.13/site-packages (0.11.10)\n",
      "\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m25.3\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m26.1.1\u001b[0m\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n",
      "Note: you may need to restart the kernel to use updated packages.\n",
      "\u001b[2mUsing Python 3.13.11 environment at: /Users/diqueran1/Desktop/Universidad/2do año/2do Cuatri/Open Data II/Proyecto Final/internal/internal_venv\u001b[0m\n",
      "\u001b[2mChecked \u001b[1m1 package\u001b[0m \u001b[2min 17ms\u001b[0m\u001b[0m\n",
      "Note: you may need to restart the kernel to use updated packages.\n",
      "\u001b[2mUsing Python 3.13.11 environment at: /Users/diqueran1/Desktop/Universidad/2do año/2do Cuatri/Open Data II/Proyecto Final/internal/internal_venv\u001b[0m\n",
      "\u001b[2mChecked \u001b[1m1 package\u001b[0m \u001b[2min 0.95ms\u001b[0m\u001b[0m\n",
      "Note: you may need to restart the kernel to use updated packages.\n",
      "\u001b[2mUsing Python 3.13.11 environment at: /Users/diqueran1/Desktop/Universidad/2do año/2do Cuatri/Open Data II/Proyecto Final/internal/internal_venv\u001b[0m\n",
      "\u001b[2mChecked \u001b[1m1 package\u001b[0m \u001b[2min 1ms\u001b[0m\u001b[0m\n",
      "Note: you may need to restart the kernel to use updated packages.\n",
      "\u001b[2mUsing Python 3.13.11 environment at: /Users/diqueran1/Desktop/Universidad/2do año/2do Cuatri/Open Data II/Proyecto Final/internal/internal_venv\u001b[0m\n",
      "\u001b[2mChecked \u001b[1m1 package\u001b[0m \u001b[2min 4ms\u001b[0m\u001b[0m\n",
      "Note: you may need to restart the kernel to use updated packages.\n"
     ]
    }
   ],
   "source": [
    "%pip install uv\n",
    "%uv pip install pandas\n",
    "%uv pip install numpy\n",
    "%uv pip install plotly\n",
    "%uv pip install nbformat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "e52c75d9",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-05-06T16:49:30.211774Z",
     "iopub.status.busy": "2026-05-06T16:49:30.211577Z",
     "iopub.status.idle": "2026-05-06T16:49:30.502978Z",
     "shell.execute_reply": "2026-05-06T16:49:30.502455Z"
    }
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "5b257a81",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-05-06T16:49:30.504534Z",
     "iopub.status.busy": "2026-05-06T16:49:30.504411Z",
     "iopub.status.idle": "2026-05-06T16:49:30.574902Z",
     "shell.execute_reply": "2026-05-06T16:49:30.574424Z"
    }
   },
   "outputs": [],
   "source": [
    "import json\n",
    "\n",
    "import plotly.graph_objects as go\n",
    "import plotly.express as px\n",
    "\n",
    "from plotly.subplots import make_subplots\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "b98226d2",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-05-06T16:49:30.576288Z",
     "iopub.status.busy": "2026-05-06T16:49:30.576192Z",
     "iopub.status.idle": "2026-05-06T16:49:30.593333Z",
     "shell.execute_reply": "2026-05-06T16:49:30.592830Z"
    }
   },
   "outputs": [],
   "source": [
    "df = pd.read_csv(\"../datasets/dataset.csv\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "da632abf",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-05-06T16:49:30.594518Z",
     "iopub.status.busy": "2026-05-06T16:49:30.594448Z",
     "iopub.status.idle": "2026-05-06T16:49:30.609709Z",
     "shell.execute_reply": "2026-05-06T16:49:30.609310Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  student_id first_name     last_name gender  age   country       city  \\\n",
      "0    EA00001     Halima        Mollel      F   16  Tanzania     Dodoma   \n",
      "1    EA00002     Joseph        Kiptoo      M   15     Kenia    Mombasa   \n",
      "2    EA00003       Aimé  Ntahomvukiye      M   19   Burundi     Ruyigi   \n",
      "3    EA00004    Fabrice    Nkurunziza      M   17   Burundi  Bujumbura   \n",
      "4    EA00005      Amani         Mgaya      M   13  Tanzania     Arusha   \n",
      "\n",
      "                  school_name       course academic_year  ...  \\\n",
      "0  Kilimanjaro Digital School  Secondary 5     2025-2026  ...   \n",
      "1            Rift Valley High  Secondary 3     2025-2026  ...   \n",
      "2     Sunrise Learning School  Secondary 6     2025-2026  ...   \n",
      "3       Community Hope Centre  Secondary 4     2025-2026  ...   \n",
      "4  Kilimanjaro Digital School    Primary 6     2025-2026  ...   \n",
      "\n",
      "  Additional_Math_term2 Additional_Math_term3  Additional_Math_final  \\\n",
      "0                   NaN                   NaN                    NaN   \n",
      "1                   NaN                   NaN                    NaN   \n",
      "2                   NaN                   NaN                    NaN   \n",
      "3                   NaN                   NaN                    NaN   \n",
      "4                   NaN                   NaN                    NaN   \n",
      "\n",
      "  Additional_Math_status Religious_Education_teacher  \\\n",
      "0                    NaN                         NaN   \n",
      "1                    NaN                         NaN   \n",
      "2                    NaN                         NaN   \n",
      "3                    NaN                         NaN   \n",
      "4                    NaN                         NaN   \n",
      "\n",
      "  Religious_Education_term1  Religious_Education_term2  \\\n",
      "0                       NaN                        NaN   \n",
      "1                       NaN                        NaN   \n",
      "2                       NaN                        NaN   \n",
      "3                       NaN                        NaN   \n",
      "4                       NaN                        NaN   \n",
      "\n",
      "   Religious_Education_term3  Religious_Education_final  \\\n",
      "0                        NaN                        NaN   \n",
      "1                        NaN                        NaN   \n",
      "2                        NaN                        NaN   \n",
      "3                        NaN                        NaN   \n",
      "4                        NaN                        NaN   \n",
      "\n",
      "   Religious_Education_status  \n",
      "0                         NaN  \n",
      "1                         NaN  \n",
      "2                         NaN  \n",
      "3                         NaN  \n",
      "4                         NaN  \n",
      "\n",
      "[5 rows x 135 columns]\n",
      "    student_id first_name  last_name gender  age   country           city  \\\n",
      "495    EA00496       Juma      Msuya      M   12  Tanzania         Mwanza   \n",
      "496    EA00497     Zuhura      Mushi      F   14  Tanzania  Dar es Salaam   \n",
      "497    EA00498      David      Kamau      M   18     Kenia        Mombasa   \n",
      "498    EA00499       John     Omondi      M   16     Kenia        Nairobi   \n",
      "499    EA00500  Jeannette  Niyonsaba      F   17    Ruanda         Rubavu   \n",
      "\n",
      "              school_name       course academic_year  ...  \\\n",
      "495   Lake Zone Institute    Primary 6     2025-2026  ...   \n",
      "496       Uhuru Secondary  Secondary 2     2025-2026  ...   \n",
      "497      Rift Valley High  Secondary 6     2025-2026  ...   \n",
      "498  Bright Future School  Secondary 3     2025-2026  ...   \n",
      "499  Vision Rwanda School  Secondary 4     2025-2026  ...   \n",
      "\n",
      "    Additional_Math_term2 Additional_Math_term3  Additional_Math_final  \\\n",
      "495                   NaN                   NaN                    NaN   \n",
      "496                   NaN                   NaN                    NaN   \n",
      "497                   NaN                   NaN                    NaN   \n",
      "498                   NaN                   NaN                    NaN   \n",
      "499                  69.0                  31.9                   50.6   \n",
      "\n",
      "    Additional_Math_status Religious_Education_teacher  \\\n",
      "495                    NaN                         NaN   \n",
      "496                    NaN                         NaN   \n",
      "497                    NaN                         NaN   \n",
      "498                    NaN                         NaN   \n",
      "499                   Pass                         NaN   \n",
      "\n",
      "    Religious_Education_term1  Religious_Education_term2  \\\n",
      "495                       NaN                        NaN   \n",
      "496                       NaN                        NaN   \n",
      "497                       NaN                        NaN   \n",
      "498                       NaN                        NaN   \n",
      "499                       NaN                        NaN   \n",
      "\n",
      "     Religious_Education_term3  Religious_Education_final  \\\n",
      "495                        NaN                        NaN   \n",
      "496                        NaN                        NaN   \n",
      "497                        NaN                        NaN   \n",
      "498                        NaN                        NaN   \n",
      "499                        NaN                        NaN   \n",
      "\n",
      "     Religious_Education_status  \n",
      "495                         NaN  \n",
      "496                         NaN  \n",
      "497                         NaN  \n",
      "498                         NaN  \n",
      "499                         NaN  \n",
      "\n",
      "[5 rows x 135 columns]\n",
      "<class 'pandas.DataFrame'>\n",
      "RangeIndex: 500 entries, 0 to 499\n",
      "Columns: 135 entries, student_id to Religious_Education_status\n",
      "dtypes: float64(80), int64(2), str(53)\n",
      "memory usage: 527.5 KB\n",
      "None\n",
      "['student_id', 'first_name', 'last_name', 'gender', 'age', 'country', 'city', 'school_name', 'course', 'academic_year', 'class_group', 'homeroom_teacher', 'attendance_absences_total', 'support_level', 'notes', 'Mathematics_teacher', 'Mathematics_term1', 'Mathematics_term2', 'Mathematics_term3', 'Mathematics_final', 'Mathematics_status', 'English_teacher', 'English_term1', 'English_term2', 'English_term3', 'English_final', 'English_status', 'Science_teacher', 'Science_term1', 'Science_term2', 'Science_term3', 'Science_final', 'Science_status', 'ICT_teacher', 'ICT_term1', 'ICT_term2', 'ICT_term3', 'ICT_final', 'ICT_status', 'Geography_teacher', 'Geography_term1', 'Geography_term2', 'Geography_term3', 'Geography_final', 'Geography_status', 'History_teacher', 'History_term1', 'History_term2', 'History_term3', 'History_final', 'History_status', 'Civics_teacher', 'Civics_term1', 'Civics_term2', 'Civics_term3', 'Civics_final', 'Civics_status', 'Agriculture_teacher', 'Agriculture_term1', 'Agriculture_term2', 'Agriculture_term3', 'Agriculture_final', 'Agriculture_status', 'Business_Studies_teacher', 'Business_Studies_term1', 'Business_Studies_term2', 'Business_Studies_term3', 'Business_Studies_final', 'Business_Studies_status', 'Physical_Education_teacher', 'Physical_Education_term1', 'Physical_Education_term2', 'Physical_Education_term3', 'Physical_Education_final', 'Physical_Education_status', 'Swahili_teacher', 'Swahili_term1', 'Swahili_term2', 'Swahili_term3', 'Swahili_final', 'Swahili_status', 'French_teacher', 'French_term1', 'French_term2', 'French_term3', 'French_final', 'French_status', 'Biology_teacher', 'Biology_term1', 'Biology_term2', 'Biology_term3', 'Biology_final', 'Biology_status', 'Chemistry_teacher', 'Chemistry_term1', 'Chemistry_term2', 'Chemistry_term3', 'Chemistry_final', 'Chemistry_status', 'Physics_teacher', 'Physics_term1', 'Physics_term2', 'Physics_term3', 'Physics_final', 'Physics_status', 'Entrepreneurship_teacher', 'Entrepreneurship_term1', 'Entrepreneurship_term2', 'Entrepreneurship_term3', 'Entrepreneurship_final', 'Entrepreneurship_status', 'Fine_Arts_teacher', 'Fine_Arts_term1', 'Fine_Arts_term2', 'Fine_Arts_term3', 'Fine_Arts_final', 'Fine_Arts_status', 'Music_teacher', 'Music_term1', 'Music_term2', 'Music_term3', 'Music_final', 'Music_status', 'Additional_Math_teacher', 'Additional_Math_term1', 'Additional_Math_term2', 'Additional_Math_term3', 'Additional_Math_final', 'Additional_Math_status', 'Religious_Education_teacher', 'Religious_Education_term1', 'Religious_Education_term2', 'Religious_Education_term3', 'Religious_Education_final', 'Religious_Education_status']\n"
     ]
    }
   ],
   "source": [
    "print(df.head())\n",
    "print(df.tail())\n",
    "\n",
    "print(df.info())\n",
    "print(df.columns.to_list())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "49d0bdd5",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-05-06T16:49:30.610780Z",
     "iopub.status.busy": "2026-05-06T16:49:30.610711Z",
     "iopub.status.idle": "2026-05-06T16:49:30.615196Z",
     "shell.execute_reply": "2026-05-06T16:49:30.614727Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['gender',\n",
       " 'age',\n",
       " 'country',\n",
       " 'city',\n",
       " 'school_name',\n",
       " 'course',\n",
       " 'academic_year',\n",
       " 'class_group',\n",
       " 'homeroom_teacher',\n",
       " 'attendance_absences_total',\n",
       " 'support_level',\n",
       " 'Mathematics_teacher',\n",
       " 'Mathematics_term1',\n",
       " 'Mathematics_term2',\n",
       " 'Mathematics_term3',\n",
       " 'Mathematics_final',\n",
       " 'Mathematics_status',\n",
       " 'English_teacher',\n",
       " 'English_term1',\n",
       " 'English_term2',\n",
       " 'English_term3',\n",
       " 'English_final',\n",
       " 'English_status',\n",
       " 'Science_teacher',\n",
       " 'Science_term1',\n",
       " 'Science_term2',\n",
       " 'Science_term3',\n",
       " 'Science_final',\n",
       " 'Science_status',\n",
       " 'ICT_teacher',\n",
       " 'ICT_term1',\n",
       " 'ICT_term2',\n",
       " 'ICT_term3',\n",
       " 'ICT_final',\n",
       " 'ICT_status',\n",
       " 'Geography_teacher',\n",
       " 'Geography_term1',\n",
       " 'Geography_term2',\n",
       " 'Geography_term3',\n",
       " 'Geography_final',\n",
       " 'Geography_status',\n",
       " 'History_teacher',\n",
       " 'History_term1',\n",
       " 'History_term2',\n",
       " 'History_term3',\n",
       " 'History_final',\n",
       " 'History_status',\n",
       " 'Civics_teacher',\n",
       " 'Civics_term1',\n",
       " 'Civics_term2',\n",
       " 'Civics_term3',\n",
       " 'Civics_final',\n",
       " 'Civics_status',\n",
       " 'Agriculture_teacher',\n",
       " 'Agriculture_term1',\n",
       " 'Agriculture_term2',\n",
       " 'Agriculture_term3',\n",
       " 'Agriculture_final',\n",
       " 'Agriculture_status',\n",
       " 'Business_Studies_teacher',\n",
       " 'Business_Studies_term1',\n",
       " 'Business_Studies_term2',\n",
       " 'Business_Studies_term3',\n",
       " 'Business_Studies_final',\n",
       " 'Business_Studies_status',\n",
       " 'Physical_Education_teacher',\n",
       " 'Physical_Education_term1',\n",
       " 'Physical_Education_term2',\n",
       " 'Physical_Education_term3',\n",
       " 'Physical_Education_final',\n",
       " 'Physical_Education_status',\n",
       " 'Swahili_teacher',\n",
       " 'Swahili_term1',\n",
       " 'Swahili_term2',\n",
       " 'Swahili_term3',\n",
       " 'Swahili_final',\n",
       " 'Swahili_status',\n",
       " 'French_teacher',\n",
       " 'French_term1',\n",
       " 'French_term2',\n",
       " 'French_term3',\n",
       " 'French_final',\n",
       " 'French_status',\n",
       " 'Biology_teacher',\n",
       " 'Biology_term1',\n",
       " 'Biology_term2',\n",
       " 'Biology_term3',\n",
       " 'Biology_final',\n",
       " 'Biology_status',\n",
       " 'Chemistry_teacher',\n",
       " 'Chemistry_term1',\n",
       " 'Chemistry_term2',\n",
       " 'Chemistry_term3',\n",
       " 'Chemistry_final',\n",
       " 'Chemistry_status',\n",
       " 'Physics_teacher',\n",
       " 'Physics_term1',\n",
       " 'Physics_term2',\n",
       " 'Physics_term3',\n",
       " 'Physics_final',\n",
       " 'Physics_status',\n",
       " 'Entrepreneurship_teacher',\n",
       " 'Entrepreneurship_term1',\n",
       " 'Entrepreneurship_term2',\n",
       " 'Entrepreneurship_term3',\n",
       " 'Entrepreneurship_final',\n",
       " 'Entrepreneurship_status',\n",
       " 'Fine_Arts_teacher',\n",
       " 'Fine_Arts_term1',\n",
       " 'Fine_Arts_term2',\n",
       " 'Fine_Arts_term3',\n",
       " 'Fine_Arts_final',\n",
       " 'Fine_Arts_status',\n",
       " 'Music_teacher',\n",
       " 'Music_term1',\n",
       " 'Music_term2',\n",
       " 'Music_term3',\n",
       " 'Music_final',\n",
       " 'Music_status',\n",
       " 'Additional_Math_teacher',\n",
       " 'Additional_Math_term1',\n",
       " 'Additional_Math_term2',\n",
       " 'Additional_Math_term3',\n",
       " 'Additional_Math_final',\n",
       " 'Additional_Math_status',\n",
       " 'Religious_Education_teacher',\n",
       " 'Religious_Education_term1',\n",
       " 'Religious_Education_term2',\n",
       " 'Religious_Education_term3',\n",
       " 'Religious_Education_final',\n",
       " 'Religious_Education_status']"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_clean = df.drop(columns = [\"student_id\", \"first_name\", \"last_name\", \"notes\"])\n",
    "df_clean.columns.to_list()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e2bb97b5",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-05-06T16:49:30.616430Z",
     "iopub.status.busy": "2026-05-06T16:49:30.616359Z",
     "iopub.status.idle": "2026-05-06T16:49:30.633328Z",
     "shell.execute_reply": "2026-05-06T16:49:30.632840Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Mathematics_status\n",
      "Pass    411\n",
      "Fail     89\n",
      "Name: count, dtype: int64\n",
      "0    67.6\n",
      "1    69.3\n",
      "2    74.9\n",
      "Name: max_grade, dtype: float64\n",
      "0    45.1\n",
      "1    51.2\n",
      "2    41.0\n",
      "Name: min_grade, dtype: float64\n",
      "0    14\n",
      "1    16\n",
      "2    16\n",
      "Name: passed_subjects, dtype: int64\n",
      "0    3\n",
      "1    0\n",
      "2    1\n",
      "Name: failed_subjects, dtype: int64\n",
      "0    0.823529\n",
      "1    1.000000\n",
      "2    0.941176\n",
      "Name: passed_rate, dtype: float64\n",
      "0     82.353\n",
      "1    100.000\n",
      "2     94.118\n",
      "Name: passed_rate_percent, dtype: float64\n",
      "0    7.044256\n",
      "1    5.956869\n",
      "2    8.381247\n",
      "Name: final_grade_std, dtype: float64\n",
      "0    17\n",
      "1    16\n",
      "2    17\n",
      "Name: total_subjects, dtype: int64\n",
      "0    Uptrend\n",
      "1    Uptrend\n",
      "2    Uptrend\n",
      "Name: grade_tendency, dtype: str\n",
      "0    False\n",
      "1    False\n",
      "2    False\n",
      "Name: sustained_decrease, dtype: bool\n",
      "0    False\n",
      "1    False\n",
      "2    False\n",
      "Name: sustained_increase, dtype: bool\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "Estadísticas - Rendimiento General por Estudiante\n",
    "\"\"\"\n",
    "\n",
    "print(df_clean[\"Mathematics_status\"].value_counts())\n",
    "\n",
    "# Promedio de nota final por estudiante\n",
    "\n",
    "final_cols = [c for c in df_clean.columns if c.endswith(\"_final\")] # Columnas de notas finales\n",
    "\n",
    "df_clean[\"avg_final\"] = df_clean[final_cols].mean(axis = 1).round(3)  # Promedio por estudiante ignorando NaN automáticamente\n",
    "\n",
    "# Nota máxima y mínima por estudiante\n",
    "\n",
    "df_clean[\"max_grade\"] = df_clean[final_cols].max(axis = 1)\n",
    "df_clean[\"min_grade\"] = df_clean[final_cols].min(axis = 1)\n",
    "\n",
    "print(df_clean[\"max_grade\"].head(3))\n",
    "print(df_clean[\"min_grade\"].head(3))\n",
    "\n",
    "# Número de clases aprobadas/suspendidas\n",
    "\n",
    "status_cols = [c for c in df_clean.columns if c.endswith(\"_status\")]\n",
    "\n",
    "df_clean[\"passed_subjects\"] = (df_clean[status_cols] == \"Pass\").sum(axis = 1).round(3)\n",
    "df_clean[\"failed_subjects\"] = (df_clean[status_cols] == \"Fail\").sum(axis = 1).round(3)\n",
    "\n",
    "print(df_clean[\"passed_subjects\"].head(3))\n",
    "print(df_clean[\"failed_subjects\"].head(3))\n",
    "\n",
    "# Tasa de aprobadas\n",
    "\n",
    "df_clean[\"passed_rate\"] = df_clean[\"passed_subjects\"] / (\n",
    "    df_clean[\"passed_subjects\"] + df_clean[\"failed_subjects\"]\n",
    ")\n",
    "\n",
    "df_clean[\"passed_rate_percent\"] = (df_clean[\"passed_rate\"] * 100).round(3)\n",
    "\n",
    "print(df_clean[\"passed_rate\"].head(3))\n",
    "print(df_clean[\"passed_rate_percent\"].head(3))\n",
    "\n",
    "# Desviación estándar de notas finales\n",
    "\n",
    "df_clean[\"final_grade_std\"] = df_clean[final_cols].std(axis = 1)\n",
    "\n",
    "print(df_clean[\"final_grade_std\"].head(3))\n",
    "\n",
    "# Asignaturas Cursadas\n",
    "\n",
    "df_clean[\"total_subjects\"] = df[final_cols].notna().sum(axis = 1)\n",
    "\n",
    "print(df_clean[\"total_subjects\"].head(3))\n",
    "\n",
    "# Tendencia general de nota\n",
    "\n",
    "term_1_columns = [c for c in df_clean.columns if c.endswith(\"_term1\")]\n",
    "term_2_columns = [c for c in df_clean.columns if c.endswith(\"_term2\")]\n",
    "term_3_columns = [c for c in df_clean.columns if c.endswith(\"_term3\")]\n",
    "\n",
    "df_clean[\"grade_tendency\"] = np.where(df[term_1_columns].mean(axis = 1) > df[term_3_columns].mean(axis = 1), \"Downtrend\", \"Uptrend\")\n",
    "\n",
    "print(df_clean[\"grade_tendency\"].head(3))\n",
    "\n",
    "# Número de materias con caída sostenida\n",
    "\n",
    "df_clean[\"sustained_decrease\"] = np.where(\n",
    "    (df_clean[term_1_columns].mean(axis=1) > df_clean[term_2_columns].mean(axis=1)) &\n",
    "    (df_clean[term_2_columns].mean(axis=1) > df_clean[term_3_columns].mean(axis=1)),\n",
    "    True,\n",
    "    False\n",
    ")\n",
    "print(df_clean[\"sustained_decrease\"].head(3))\n",
    "\n",
    "# Número de materias con subdido sostenida\n",
    "\n",
    "df_clean[\"sustained_increase\"] = np.where(\n",
    "    (df_clean[term_1_columns].mean(axis=1) < df_clean[term_2_columns].mean(axis=1)) &\n",
    "    (df_clean[term_2_columns].mean(axis=1) < df_clean[term_3_columns].mean(axis=1)),\n",
    "    True,\n",
    "    False\n",
    ")\n",
    "\n",
    "print(df_clean[\"sustained_increase\"].head(3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "2a564b38",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-05-06T16:49:30.634556Z",
     "iopub.status.busy": "2026-05-06T16:49:30.634477Z",
     "iopub.status.idle": "2026-05-06T16:49:31.264390Z",
     "shell.execute_reply": "2026-05-06T16:49:31.264035Z"
    }
   },
   "outputs": [
    {
     "data": {
      "application/vnd.plotly.v1+json": {
       "config": {
        "plotlyServerURL": "https://plot.ly"
       },
       "data": [
        {
         "marker": {
          "color": "#4C9BE8"
         },
         "name": "Promedio Final",
         "nbinsx": 20,
         "type": "histogram",
         "x": {
          "bdata": "[encoded data, 5336 characters]",
          "dtype": "f8"
         },
         "xaxis": "x",
         "yaxis": "y"
        },
        {
         "domain": {
          "x": [
           0.55,
           1
          ],
          "y": [
           0.7777777777777778,
           1
          ]
         },
         "labels": [
          "Uptrend",
          "Downtrend"
         ],
         "name": "Tendencia",
         "type": "pie",
         "values": {
          "bdata": "aQGLAA==",
          "dtype": "i2"
         }
        },
        {
         "marker": {
          "color": {
           "bdata": "[encoded data, 5336 characters]",
           "dtype": "f8"
          },
          "colorscale": [
           [
            0,
            "rgb(165,0,38)"
           ],
           [
            0.1,
            "rgb(215,48,39)"
           ],
           [
            0.2,
            "rgb(244,109,67)"
           ],
           [
            0.3,
            "rgb(253,174,97)"
           ],
           [
            0.4,
            "rgb(254,224,139)"
           ],
           [
            0.5,
            "rgb(255,255,191)"
           ],
           [
            0.6,
            "rgb(217,239,139)"
           ],
           [
            0.7,
            "rgb(166,217,106)"
           ],
           [
            0.8,
            "rgb(102,189,99)"
           ],
           [
            0.9,
            "rgb(26,152,80)"
           ],
           [
            1,
            "rgb(0,104,55)"
           ]
          ],
          "showscale": true
         },
         "mode": "markers",
         "name": "Aprobadas vs Reprobadas",
         "type": "scatter",
         "x": {
          "bdata": "DhAQDxANEhAQEBERDg4REREQDw4QERAREQ4RDw8QDBINDBIREQsODw4RERINDxEREBEQEBEQDhASEA8QEBARERAQERAQEA8QDhEREBEREhEQEQ4REQwQERAPEQ0REhAOERAOERAOEAoQEhEODBEQDhEQEA8PDhAPEA8RDRIREBEREREQEBAPEA8RDREODREQEBIQEQ8OERIPEhAQERIREBENEREREBAOEBEQEBISDBIPDxEOEQsKEg4QDxAPDREPEBARERESDQ4OEQ4SEREODw8QDxEMERAPEA4SEBEREBAPEhAQDw8REBEQEA8QEA8PERAREhIQEA8PDBEPCw8QEBAPEQ8PEREPDg8QEQoSEA8ODw4PERIQEA8PEhARDxIPEhEREA4REhEREREQDw4MEBAREg4NEQ4QDQ8QEAsQDhAQEBIQDRARDw0OEQ8RERERDg8QEBAQDQ8PDRARCw4RERENEBAQEQ8REBIREQ0RERIREg8RDw8ODwwQEREQEQ4RDxASEQ8RDhEODBEPERANEREREA8REg8RDRERDhEPEQ4QEBAQDRIPERIQEBALEBAREBIREBAQDw4RERIREQ4REhAOEBAPEhEQEhAREA8REhALEBAQDxIPEhIREBAPEBASDxEQDw8QDw8REA8SEBIQEBAQEA8=",
          "dtype": "i1"
         },
         "xaxis": "x2",
         "y": {
          "bdata": "AwABAQAEAAEBAQAAAwIAAAEAAgMBAAEAAAIAAgIABAAEBAAAAQUDAwMBAAADAwEAAAABAAEBAwEAAAIAAQIAAAAAAAAAAAEBAwAAAAAAAAABAQIAAAQBAAACAAQAAAAEAAECAAEEAQYAAAACBAABAgAAAQICAwACAAIABAAAAgAAAAAAAQECAAMABAADBAABAgABAAICAQABAAACAAAAAAEEAAAAAQECAgACAAAABAACAgADAAUGAAQAAwABBAABAgAAAAEAAwQEAAIAAAACAgEBAgAFAQECAAIAAQEAAAECAAABAQIBAQABAQEBAgICAQAAAAAAAgIBBAABBgEAAAABAAMCAAABAwIBAAYAAAMDAgIDAQACAgMCAAABAgADAAAAAAIAAAEAAAABAwIEAQEAAAIDAAMAAwIAAQUAAwABAQACBAABAgQCAAIAAAAAAwMCAQAAAwIBAwEABQQAAAEFAQEAAQIAAAAAAAQAAAABAAIAAQEDAwUAAAAAAAMAAgAAAAEBAwACBQADAAEDAAABAAEBAAIAAwAAAwECAAIBAgABAwABAAAAAQEGAAIAAAAAAgABAwIBAQAAAAIAAAADAAABAAAAAAAAAAMBAAEFAQAAAgABAAABAgADAAEAAgABAgIAAgIAAAIAAAAAAAABAAE=",
          "dtype": "i1"
         },
         "yaxis": "y2"
        },
        {
         "marker": {
          "color": "#2ECC71"
         },
         "name": "Tasa Aprobación %",
         "nbinsx": 20,
         "type": "histogram",
         "x": {
          "bdata": "[encoded data, 5336 characters]",
          "dtype": "f8"
         },
         "xaxis": "x3",
         "yaxis": "y3"
        },
        {
         "marker": {
          "color": "#E67E22"
         },
         "name": "Std Notas Finales",
         "type": "box",
         "xaxis": "x4",
         "y": {
          "bdata": "[encoded data, 5336 characters]",
          "dtype": "f8"
         },
         "yaxis": "y4"
        },
        {
         "marker": {
          "color": [
           "#E74C3C",
           "#2ECC71",
           "#95A5A6"
          ]
         },
         "name": "Tendencia Sostenida",
         "type": "bar",
         "x": [
          "Sustained Decrease",
          "Sustained Increase",
          "Neither"
         ],
         "xaxis": "x5",
         "y": [
          32,
          153,
          315
         ],
         "yaxis": "y5"
        }
       ],
       "layout": {
        "annotations": [
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Distribución de Promedio Final",
          "x": 0.225,
          "xanchor": "center",
          "xref": "paper",
          "y": 1,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Tendencia General (Uptrend vs Downtrend)",
          "x": 0.775,
          "xanchor": "center",
          "xref": "paper",
          "y": 1,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Materias Aprobadas vs Reprobadas por Estudiante",
          "x": 0.225,
          "xanchor": "center",
          "xref": "paper",
          "y": 0.6111111111111112,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Tasa de Aprobación (%)",
          "x": 0.775,
          "xanchor": "center",
          "xref": "paper",
          "y": 0.6111111111111112,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Desviación Estándar de Notas Finales",
          "x": 0.225,
          "xanchor": "center",
          "xref": "paper",
          "y": 0.22222222222222224,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Tendencia Sostenida",
          "x": 0.775,
          "xanchor": "center",
          "xref": "paper",
          "y": 0.22222222222222224,
          "yanchor": "bottom",
          "yref": "paper"
         }
        ],
        "height": 900,
        "showlegend": false,
        "template": {
         "data": {
          "bar": [
           {
            "error_x": {
             "color": "#2a3f5f"
            },
            "error_y": {
             "color": "#2a3f5f"
            },
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "bar"
           }
          ],
          "barpolar": [
           {
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "barpolar"
           }
          ],
          "carpet": [
           {
            "aaxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "baxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "type": "carpet"
           }
          ],
          "choropleth": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "choropleth"
           }
          ],
          "contour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "contour"
           }
          ],
          "contourcarpet": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "contourcarpet"
           }
          ],
          "heatmap": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmap"
           }
          ],
          "histogram": [
           {
            "marker": {
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "histogram"
           }
          ],
          "histogram2d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2d"
           }
          ],
          "histogram2dcontour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2dcontour"
           }
          ],
          "mesh3d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "mesh3d"
           }
          ],
          "parcoords": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "parcoords"
           }
          ],
          "pie": [
           {
            "automargin": true,
            "type": "pie"
           }
          ],
          "scatter": [
           {
            "fillpattern": {
             "fillmode": "overlay",
             "size": 10,
             "solidity": 0.2
            },
            "type": "scatter"
           }
          ],
          "scatter3d": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatter3d"
           }
          ],
          "scattercarpet": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattercarpet"
           }
          ],
          "scattergeo": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergeo"
           }
          ],
          "scattergl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergl"
           }
          ],
          "scattermap": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermap"
           }
          ],
          "scattermapbox": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermapbox"
           }
          ],
          "scatterpolar": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolar"
           }
          ],
          "scatterpolargl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolargl"
           }
          ],
          "scatterternary": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterternary"
           }
          ],
          "surface": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "surface"
           }
          ],
          "table": [
           {
            "cells": {
             "fill": {
              "color": "#EBF0F8"
             },
             "line": {
              "color": "white"
             }
            },
            "header": {
             "fill": {
              "color": "#C8D4E3"
             },
             "line": {
              "color": "white"
             }
            },
            "type": "table"
           }
          ]
         },
         "layout": {
          "annotationdefaults": {
           "arrowcolor": "#2a3f5f",
           "arrowhead": 0,
           "arrowwidth": 1
          },
          "autotypenumbers": "strict",
          "coloraxis": {
           "colorbar": {
            "outlinewidth": 0,
            "ticks": ""
           }
          },
          "colorscale": {
           "diverging": [
            [
             0,
             "#8e0152"
            ],
            [
             0.1,
             "#c51b7d"
            ],
            [
             0.2,
             "#de77ae"
            ],
            [
             0.3,
             "#f1b6da"
            ],
            [
             0.4,
             "#fde0ef"
            ],
            [
             0.5,
             "#f7f7f7"
            ],
            [
             0.6,
             "#e6f5d0"
            ],
            [
             0.7,
             "#b8e186"
            ],
            [
             0.8,
             "#7fbc41"
            ],
            [
             0.9,
             "#4d9221"
            ],
            [
             1,
             "#276419"
            ]
           ],
           "sequential": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ],
           "sequentialminus": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ]
          },
          "colorway": [
           "#636efa",
           "#EF553B",
           "#00cc96",
           "#ab63fa",
           "#FFA15A",
           "#19d3f3",
           "#FF6692",
           "#B6E880",
           "#FF97FF",
           "#FECB52"
          ],
          "font": {
           "color": "#2a3f5f"
          },
          "geo": {
           "bgcolor": "white",
           "lakecolor": "white",
           "landcolor": "#E5ECF6",
           "showlakes": true,
           "showland": true,
           "subunitcolor": "white"
          },
          "hoverlabel": {
           "align": "left"
          },
          "hovermode": "closest",
          "mapbox": {
           "style": "light"
          },
          "paper_bgcolor": "white",
          "plot_bgcolor": "#E5ECF6",
          "polar": {
           "angularaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "radialaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "scene": {
           "xaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "yaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "zaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           }
          },
          "shapedefaults": {
           "line": {
            "color": "#2a3f5f"
           }
          },
          "ternary": {
           "aaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "baxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "caxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "title": {
           "x": 0.05
          },
          "xaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          },
          "yaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          }
         }
        },
        "title": {
         "text": "Dashboard - Rendimiento General por Estudiante"
        },
        "xaxis": {
         "anchor": "y",
         "domain": [
          0,
          0.45
         ]
        },
        "xaxis2": {
         "anchor": "y2",
         "domain": [
          0,
          0.45
         ]
        },
        "xaxis3": {
         "anchor": "y3",
         "domain": [
          0.55,
          1
         ]
        },
        "xaxis4": {
         "anchor": "y4",
         "domain": [
          0,
          0.45
         ]
        },
        "xaxis5": {
         "anchor": "y5",
         "domain": [
          0.55,
          1
         ]
        },
        "yaxis": {
         "anchor": "x",
         "domain": [
          0.7777777777777778,
          1
         ]
        },
        "yaxis2": {
         "anchor": "x2",
         "domain": [
          0.3888888888888889,
          0.6111111111111112
         ]
        },
        "yaxis3": {
         "anchor": "x3",
         "domain": [
          0.3888888888888889,
          0.6111111111111112
         ]
        },
        "yaxis4": {
         "anchor": "x4",
         "domain": [
          0,
          0.22222222222222224
         ]
        },
        "yaxis5": {
         "anchor": "x5",
         "domain": [
          0,
          0.22222222222222224
         ]
        }
       }
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Dashboard serializado correctamente\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "Visualización - Rendimiento General por Estudiante\n",
    "\"\"\"\n",
    "\n",
    "# Preparar datos agregados\n",
    "\n",
    "grade_tendency_counts = df_clean[\"grade_tendency\"].value_counts().reset_index()\n",
    "grade_tendency_counts.columns = [\"tendency\", \"count\"]\n",
    "\n",
    "sustained_counts = {\n",
    "    \"Sustained Decrease\": int(df_clean[\"sustained_decrease\"].sum()),\n",
    "    \"Sustained Increase\": int(df_clean[\"sustained_increase\"].sum()),\n",
    "    \"Neither\": int((~df_clean[\"sustained_decrease\"] & ~df_clean[\"sustained_increase\"]).sum())\n",
    "}\n",
    "\n",
    "# Crear subplots\n",
    "\n",
    "fig = make_subplots(\n",
    "\n",
    "    rows=3, cols=2,\n",
    "\n",
    "    subplot_titles=[\n",
    "\n",
    "        \"Distribución de Promedio Final\",\n",
    "        \"Tendencia General (Uptrend vs Downtrend)\",\n",
    "        \"Materias Aprobadas vs Reprobadas por Estudiante\",\n",
    "        \"Tasa de Aprobación (%)\",\n",
    "        \"Desviación Estándar de Notas Finales\",\n",
    "        \"Tendencia Sostenida\"\n",
    "\n",
    "    ],\n",
    "\n",
    "    specs=[\n",
    "\n",
    "        [{\"type\": \"xy\"},     {\"type\": \"domain\"}],\n",
    "        [{\"type\": \"xy\"},     {\"type\": \"xy\"}],\n",
    "        [{\"type\": \"xy\"},     {\"type\": \"xy\"}]\n",
    "\n",
    "    ]\n",
    "\n",
    ")\n",
    "\n",
    "# Histograma promedio final\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Histogram(x=df_clean[\"avg_final\"], nbinsx=20, name=\"Promedio Final\", marker_color=\"#4C9BE8\"),\n",
    "\n",
    "    row=1, col=1\n",
    "\n",
    ")\n",
    "\n",
    "# Tendencia general\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Pie(\n",
    "\n",
    "        labels=grade_tendency_counts[\"tendency\"],\n",
    "        values=grade_tendency_counts[\"count\"],\n",
    "        name=\"Tendencia\"\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=1, col=2\n",
    "\n",
    ")\n",
    "\n",
    "# Scatter aprobadas vs suspendidos\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Scatter(\n",
    "\n",
    "        x=df_clean[\"passed_subjects\"],\n",
    "        y=df_clean[\"failed_subjects\"],\n",
    "        mode=\"markers\",\n",
    "        marker=dict(color=df_clean[\"avg_final\"], colorscale=\"RdYlGn\", showscale=True),\n",
    "        name=\"Aprobadas vs Reprobadas\"\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=2, col=1\n",
    "\n",
    ")\n",
    "\n",
    "# Histograma tasa de aprobación\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Histogram(x=df_clean[\"passed_rate_percent\"], nbinsx=20, name=\"Tasa Aprobación %\", marker_color=\"#2ECC71\"),\n",
    "\n",
    "    row=2, col=2\n",
    "\n",
    ")\n",
    "\n",
    "# Box plot desviación estándar\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Box(y=df_clean[\"final_grade_std\"], name=\"Std Notas Finales\", marker_color=\"#E67E22\"),\n",
    "\n",
    "    row=3, col=1\n",
    "\n",
    ")\n",
    "\n",
    "# Bar tendencia sostenida\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(\n",
    "\n",
    "        x=list(sustained_counts.keys()),\n",
    "        y=list(sustained_counts.values()),\n",
    "        name=\"Tendencia Sostenida\",\n",
    "        marker_color=[\"#E74C3C\", \"#2ECC71\", \"#95A5A6\"]\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=3, col=2\n",
    "\n",
    ")\n",
    "\n",
    "# Layout\n",
    "\n",
    "fig.update_layout(\n",
    "\n",
    "    title_text=\"Dashboard - Rendimiento General por Estudiante\",\n",
    "    height=900,\n",
    "    showlegend=False\n",
    "\n",
    ")\n",
    "\n",
    "# Serializar a JSON\n",
    "\n",
    "dashboard_json = fig.to_json()\n",
    "\n",
    "with open(\"dashboard_student_performance.json\", \"w\") as f:\n",
    "    json.dump(json.loads(dashboard_json), f)\n",
    "\n",
    "fig.show(renderer=\"plotly_mimetype\")\n",
    "\n",
    "print(\"Dashboard serializado correctamente\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "a8180b7a",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-05-06T16:49:31.266197Z",
     "iopub.status.busy": "2026-05-06T16:49:31.266095Z",
     "iopub.status.idle": "2026-05-06T16:49:31.284168Z",
     "shell.execute_reply": "2026-05-06T16:49:31.283735Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Mathematics_final    56.823\n",
      "English_final        62.354\n",
      "Science_final        62.294\n",
      "dtype: float64\n",
      "Mathematics_status    0.82\n",
      "English_status        0.97\n",
      "Science_status        0.95\n",
      "dtype: float64\n",
      "66.091\n",
      "56.507\n",
      "1.0\n",
      "0.81\n",
      "Mathematics_term1    55.9012\n",
      "English_term1        62.0264\n",
      "Science_term1        61.0792\n",
      "dtype: float64 Mathematics_term2    56.3434\n",
      "English_term2        61.8832\n",
      "Science_term2        62.8384\n",
      "dtype: float64 Mathematics_term3    58.2256\n",
      "English_term3        63.1570\n",
      "Science_term3        62.9684\n",
      "dtype: float64\n",
      "Mathematics_final    7.255\n",
      "English_final        7.337\n",
      "Science_final        7.266\n",
      "dtype: float64\n",
      "Additional_Math_term1   NaN\n",
      "Additional_Math_term3   NaN\n",
      "Agriculture_term1       NaN\n",
      "dtype: float64\n",
      "Mathematics_status    500\n",
      "English_status        500\n",
      "Science_status        500\n",
      "dtype: int64\n",
      "500    15\n",
      "201     2\n",
      "182     1\n",
      "209     1\n",
      "185     1\n",
      "Name: count, dtype: int64\n",
      "Mathematics_status    411\n",
      "English_status        483\n",
      "Science_status        477\n",
      "dtype: int64\n",
      "Mathematics_status    411\n",
      "English_status        483\n",
      "Science_status        477\n",
      "dtype: int64\n",
      "Geography\n",
      "Chemistry\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "Rendimiento por asignatura\n",
    "\"\"\"\n",
    "\n",
    "# Nota media por asignatura\n",
    "\n",
    "subject_means = df[final_cols].mean().round(3)\n",
    "\n",
    "print(subject_means.head(3))\n",
    "\n",
    "# Tasa por asignatura\n",
    "\n",
    "pass_rate = df[status_cols].apply(lambda col: (col == \"Pass\").sum() / col.notna().sum()).round(2)\n",
    "\n",
    "print(pass_rate.head(3))\n",
    "\n",
    "# Mayor promedio\n",
    "\n",
    "best_avg = subject_means.max()\n",
    "\n",
    "print(best_avg)\n",
    "\n",
    "# Menor promedio\n",
    "\n",
    "worst_avg = subject_means.min()\n",
    "\n",
    "print(worst_avg)\n",
    "\n",
    "# Asignatura más fácil\n",
    "\n",
    "diff_subject = pass_rate.max()\n",
    "\n",
    "print(diff_subject)\n",
    "\n",
    "# Asignatura más dificil\n",
    "\n",
    "easy_subject = pass_rate.min()\n",
    "\n",
    "print(easy_subject)\n",
    "\n",
    "# Promedio de nota por asignatura por semestre\n",
    "\n",
    "first_semester_avg = df[term_1_columns].mean()\n",
    "second_semester_avg = df[term_2_columns].mean()\n",
    "third_semester_avg = df[term_3_columns].mean()\n",
    "\n",
    "print(first_semester_avg.head(3), second_semester_avg.head(3), third_semester_avg.head(3))\n",
    "\n",
    "# Varianza de notas por materia\n",
    "\n",
    "std_per_subject = df[final_cols].std().round(3)\n",
    "\n",
    "print(std_per_subject.head(3))\n",
    "\n",
    "# Diferencia de medias\n",
    "\n",
    "avg_dif = third_semester_avg - first_semester_avg\n",
    "\n",
    "print(avg_dif.head(3))\n",
    "\n",
    "# Cantidad de estudiantes por materia\n",
    "\n",
    "students_per_subject = df[status_cols].notna().sum()\n",
    "\n",
    "print(students_per_subject.head(3))\n",
    "\n",
    "print(students_per_subject.value_counts())\n",
    "\n",
    "# Cantidad de estudiantes que aprobaron cada materia\n",
    "\n",
    "passed_per_subject = df[status_cols].apply(lambda col: (col == \"Pass\").sum())\n",
    "\n",
    "print(passed_per_subject.head(3))\n",
    "\n",
    "# Cantidad de estudiantes que suspendieron cada materia\n",
    "\n",
    "failed_per_subject = df[status_cols].apply(lambda col: (col == \"Fail\").sum())\n",
    "\n",
    "print(passed_per_subject.head(3))\n",
    "\n",
    "# Más mejoran/empeoran por asignatura durante el curso\n",
    "\n",
    "improved = {}\n",
    "worsened = {}\n",
    "\n",
    "subjects = [c.replace(\"_term1\", \"\") for c in term_1_columns]\n",
    "\n",
    "for subject in subjects:\n",
    "\n",
    "    diff = df[f\"{subject}_term3\"] - df[f\"{subject}_term1\"]\n",
    "    \n",
    "    improved[subject] = (diff > 0).sum()\n",
    "    worsened[subject] = (diff < 0).sum()\n",
    "\n",
    "improved_series = pd.Series(improved).sort_values(ascending=False)\n",
    "worsened_series = pd.Series(worsened).sort_values(ascending=False)\n",
    "\n",
    "print(improved_series.idxmax())\n",
    "print(worsened_series.idxmax())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "63ea53ac",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-05-06T16:49:31.285325Z",
     "iopub.status.busy": "2026-05-06T16:49:31.285246Z",
     "iopub.status.idle": "2026-05-06T16:49:31.304715Z",
     "shell.execute_reply": "2026-05-06T16:49:31.304267Z"
    }
   },
   "outputs": [
    {
     "data": {
      "application/vnd.plotly.v1+json": {
       "config": {
        "plotlyServerURL": "https://plot.ly"
       },
       "data": [
        {
         "marker": {
          "color": "#4C9BE8"
         },
         "name": "Nota Media",
         "type": "bar",
         "x": [
          "Mathematics",
          "English",
          "Science",
          "ICT",
          "Geography",
          "History",
          "Civics",
          "Agriculture",
          "Business_Studies",
          "Physical_Education",
          "Swahili",
          "French",
          "Biology",
          "Chemistry",
          "Physics",
          "Entrepreneurship",
          "Fine_Arts",
          "Music",
          "Additional_Math",
          "Religious_Education"
         ],
         "xaxis": "x",
         "y": {
          "bdata": "001iEFhpTEBaZDvfTy1PQBKDwMqhJU9AhxbZzveTT0DByqFFttNOQN0kBoGV805Ake18PzV2UEDdJAaBlRNPQC2yne+npk9Abef7qfGCUEC28/3UeNlOQC/dJAaB9U5A46WbxCAQT0A3iUFg5UBMQNnO91PjxUxAg8DKoUVmT0BQjZduEntQQOf7qfHShVBA8KfGSzeZTEAxCKwcWqROQA==",
          "dtype": "f8"
         },
         "yaxis": "y"
        },
        {
         "marker": {
          "color": "#2ECC71"
         },
         "name": "% Aprobados",
         "type": "bar",
         "x": [
          "Mathematics",
          "English",
          "Science",
          "ICT",
          "Geography",
          "History",
          "Civics",
          "Agriculture",
          "Business_Studies",
          "Physical_Education",
          "Swahili",
          "French",
          "Biology",
          "Chemistry",
          "Physics",
          "Entrepreneurship",
          "Fine_Arts",
          "Music",
          "Additional_Math",
          "Religious_Education"
         ],
         "xaxis": "x2",
         "y": {
          "bdata": "AAAAAACAVEAAAAAAAEBYQAAAAAAAwFdAAAAAAAAAWEAAAAAAAIBXQAAAAAAAgFdAAAAAAADAWEAAAAAAAMBXQAAAAAAAAFhAAAAAAADAWEAAAAAAAEBXQAAAAAAAwFdAAAAAAADAV0AAAAAAAEBUQAAAAAAAQFVAAAAAAABAWEAAAAAAAABZQAAAAAAAAFlAAAAAAABAVUAAAAAAAEBXQA==",
          "dtype": "f8"
         },
         "yaxis": "y2"
        },
        {
         "marker": {
          "color": "#E67E22"
         },
         "name": "Std",
         "type": "bar",
         "x": [
          "Mathematics",
          "English",
          "Science",
          "ICT",
          "Geography",
          "History",
          "Civics",
          "Agriculture",
          "Business_Studies",
          "Physical_Education",
          "Swahili",
          "French",
          "Biology",
          "Chemistry",
          "Physics",
          "Entrepreneurship",
          "Fine_Arts",
          "Music",
          "Additional_Math",
          "Religious_Education"
         ],
         "xaxis": "x3",
         "y": {
          "bdata": "hetRuB4FHUAMAiuHFlkdQKrx0k1iEB1A0SLb+X7qHUAtsp3vp0YcQM3MzMzMTB5ArBxaZDvfHUDZzvdT4yUdQDeJQWDl0B1ALbKd76fGHUDVeOkmMQgeQAisHFpkuxxAIbByaJHtHUDufD81XjodQBkEVg4tMh5ArkfhehQuHECNl24Sg0AcQNV46SYxCB9AN4lBYOVQHUD8qfHSTeIcQA==",
          "dtype": "f8"
         },
         "yaxis": "y3"
        },
        {
         "marker": {
          "color": "#2ECC71"
         },
         "name": "Aprobados",
         "type": "bar",
         "x": [
          "Mathematics",
          "English",
          "Science",
          "ICT",
          "Geography",
          "History",
          "Civics",
          "Agriculture",
          "Business_Studies",
          "Physical_Education",
          "Swahili",
          "French",
          "Biology",
          "Chemistry",
          "Physics",
          "Entrepreneurship",
          "Fine_Arts",
          "Music",
          "Additional_Math",
          "Religious_Education"
         ],
         "xaxis": "x4",
         "y": {
          "bdata": "mwHjAd0B4AHYAdYB7wHZAeEB8AHQAdsB3AGVAacBsQDRAMgAqgCsAA==",
          "dtype": "i2"
         },
         "yaxis": "y4"
        },
        {
         "marker": {
          "color": "#E74C3C"
         },
         "name": "Reprobados",
         "type": "bar",
         "x": [
          "Mathematics",
          "English",
          "Science",
          "ICT",
          "Geography",
          "History",
          "Civics",
          "Agriculture",
          "Business_Studies",
          "Physical_Education",
          "Swahili",
          "French",
          "Biology",
          "Chemistry",
          "Physics",
          "Entrepreneurship",
          "Fine_Arts",
          "Music",
          "Additional_Math",
          "Religious_Education"
         ],
         "xaxis": "x4",
         "y": {
          "bdata": "WREXFBweBRsTBCQZGF9NBQABHw0=",
          "dtype": "i1"
         },
         "yaxis": "y4"
        },
        {
         "marker": {
          "color": "#27AE60"
         },
         "name": "Mejoran",
         "type": "bar",
         "x": [
          "Geography",
          "Civics",
          "Biology",
          "Business_Studies",
          "Swahili",
          "Mathematics",
          "Agriculture",
          "French",
          "English",
          "Science",
          "Physics",
          "History",
          "ICT",
          "Physical_Education",
          "Chemistry",
          "Additional_Math",
          "Music",
          "Fine_Arts",
          "Entrepreneurship",
          "Religious_Education"
         ],
         "xaxis": "x5",
         "y": {
          "bdata": "JgEkASMBHwEeARsBFQEVARQBEgENAQwBDAEIAQQBdQB0AHAAXwBeAA==",
          "dtype": "i2"
         },
         "yaxis": "y5"
        },
        {
         "marker": {
          "color": "#C0392B"
         },
         "name": "Empeoran",
         "type": "bar",
         "x": [
          "Chemistry",
          "Physical_Education",
          "ICT",
          "History",
          "Physics",
          "Science",
          "Agriculture",
          "English",
          "French",
          "Mathematics",
          "Business_Studies",
          "Swahili",
          "Biology",
          "Civics",
          "Geography",
          "Fine_Arts",
          "Religious_Education",
          "Entrepreneurship",
          "Music",
          "Additional_Math"
         ],
         "xaxis": "x5",
         "y": {
          "bdata": "7wDqAOcA5wDhAOAA3wDeANwA2QDUANMA0QDOAM4AYABbAFcAVABUAA==",
          "dtype": "i2"
         },
         "yaxis": "y5"
        },
        {
         "line": {
          "color": "#3498DB"
         },
         "mode": "lines+markers",
         "name": "Trimestre 1",
         "type": "scatter",
         "x": [
          "Mathematics",
          "English",
          "Science",
          "ICT",
          "Geography",
          "History",
          "Civics",
          "Agriculture",
          "Business_Studies",
          "Physical_Education",
          "Swahili",
          "French",
          "Biology",
          "Chemistry",
          "Physics",
          "Entrepreneurship",
          "Fine_Arts",
          "Music",
          "Additional_Math",
          "Religious_Education"
         ],
         "xaxis": "x6",
         "y": {
          "bdata": "3ZOHhVrzS0ClTkATYQNPQO7rwDkjik5AyeU/pN8OT0CkAbwFEvRNQNXnaiv2t05AGsBbIEE5UEDTvOMUHblOQEq/fR04N09APZtVn6s9UEA/V1uxvyxOQAjOGVHaa05ASr99HThnTkAhjnVxG/1LQB18YTJVUExAvMd7vMe7TkAIYJjK8VFQQJm0x7AyfVBAGcJePP/uS0DRMbw4D51OQA==",
          "dtype": "f8"
         },
         "yaxis": "y6"
        },
        {
         "line": {
          "color": "#F39C12"
         },
         "mode": "lines+markers",
         "name": "Trimestre 2",
         "type": "scatter",
         "x": [
          "Mathematics",
          "English",
          "Science",
          "ICT",
          "Geography",
          "History",
          "Civics",
          "Agriculture",
          "Business_Studies",
          "Physical_Education",
          "Swahili",
          "French",
          "Biology",
          "Chemistry",
          "Physics",
          "Entrepreneurship",
          "Fine_Arts",
          "Music",
          "Additional_Math",
          "Religious_Education"
         ],
         "xaxis": "x6",
         "y": {
          "bdata": "I7n8h/QrTEDh6ZWyDPFOQLJ78rBQa09AtvP91Hi5T0BO845TdCRPQOPHmLuWsE5Aio7k8h9aUECmm8QgsGJOQD8TYcPTe09APL1SliGeUEBMFYxK6sROQLpJDAIr905AtFn1udoKT0AYJlMFo0JMQAwCK4cWuUxA+q7v+q6PT0AEMEzl+EhQQPp3rdOlCVBA906y1BHiTED5FlHX7tVOQA==",
          "dtype": "f8"
         },
         "yaxis": "y6"
        },
        {
         "line": {
          "color": "#27AE60"
         },
         "mode": "lines+markers",
         "name": "Trimestre 3",
         "type": "scatter",
         "x": [
          "Mathematics",
          "English",
          "Science",
          "ICT",
          "Geography",
          "History",
          "Civics",
          "Agriculture",
          "Business_Studies",
          "Physical_Education",
          "Swahili",
          "French",
          "Biology",
          "Chemistry",
          "Physics",
          "Entrepreneurship",
          "Fine_Arts",
          "Music",
          "Additional_Math",
          "Religious_Education"
         ],
         "xaxis": "x6",
         "y": {
          "bdata": "Iv32deAcTUBqvHSTGJRPQCW5/If0e09AGNnO91PzT0Buxf6ye2JPQMWxLm6jcU9ADpwzorTPUEBIUPwYcw9QQH/ZPXlYIFBAhVrTvOOsUECYbhKDwJpPQATFjzF3fU9A5T+k376+T0D7XG3F/oJMQLgehetRSE1AYPqlX/rlT0A4b9JRatZQQGtn0h7DClFA5JuMOGr7TEB2OMS3iHpOQA==",
          "dtype": "f8"
         },
         "yaxis": "y6"
        }
       ],
       "layout": {
        "annotations": [
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Nota Media por Asignatura",
          "x": 0.225,
          "xanchor": "center",
          "xref": "paper",
          "y": 1,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Tasa de Aprobación por Asignatura (%)",
          "x": 0.775,
          "xanchor": "center",
          "xref": "paper",
          "y": 1,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Desviación Estándar por Asignatura",
          "x": 0.225,
          "xanchor": "center",
          "xref": "paper",
          "y": 0.6111111111111112,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Aprobados vs Reprobados por Asignatura",
          "x": 0.775,
          "xanchor": "center",
          "xref": "paper",
          "y": 0.6111111111111112,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Estudiantes que Mejoraron / Empeoraron (T1→T3)",
          "x": 0.225,
          "xanchor": "center",
          "xref": "paper",
          "y": 0.22222222222222224,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Progresión Media por Trimestre",
          "x": 0.775,
          "xanchor": "center",
          "xref": "paper",
          "y": 0.22222222222222224,
          "yanchor": "bottom",
          "yref": "paper"
         }
        ],
        "barmode": "group",
        "height": 1000,
        "showlegend": true,
        "template": {
         "data": {
          "bar": [
           {
            "error_x": {
             "color": "#2a3f5f"
            },
            "error_y": {
             "color": "#2a3f5f"
            },
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "bar"
           }
          ],
          "barpolar": [
           {
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "barpolar"
           }
          ],
          "carpet": [
           {
            "aaxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "baxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "type": "carpet"
           }
          ],
          "choropleth": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "choropleth"
           }
          ],
          "contour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "contour"
           }
          ],
          "contourcarpet": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "contourcarpet"
           }
          ],
          "heatmap": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmap"
           }
          ],
          "histogram": [
           {
            "marker": {
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "histogram"
           }
          ],
          "histogram2d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2d"
           }
          ],
          "histogram2dcontour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2dcontour"
           }
          ],
          "mesh3d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "mesh3d"
           }
          ],
          "parcoords": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "parcoords"
           }
          ],
          "pie": [
           {
            "automargin": true,
            "type": "pie"
           }
          ],
          "scatter": [
           {
            "fillpattern": {
             "fillmode": "overlay",
             "size": 10,
             "solidity": 0.2
            },
            "type": "scatter"
           }
          ],
          "scatter3d": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatter3d"
           }
          ],
          "scattercarpet": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattercarpet"
           }
          ],
          "scattergeo": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergeo"
           }
          ],
          "scattergl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergl"
           }
          ],
          "scattermap": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermap"
           }
          ],
          "scattermapbox": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermapbox"
           }
          ],
          "scatterpolar": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolar"
           }
          ],
          "scatterpolargl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolargl"
           }
          ],
          "scatterternary": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterternary"
           }
          ],
          "surface": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "surface"
           }
          ],
          "table": [
           {
            "cells": {
             "fill": {
              "color": "#EBF0F8"
             },
             "line": {
              "color": "white"
             }
            },
            "header": {
             "fill": {
              "color": "#C8D4E3"
             },
             "line": {
              "color": "white"
             }
            },
            "type": "table"
           }
          ]
         },
         "layout": {
          "annotationdefaults": {
           "arrowcolor": "#2a3f5f",
           "arrowhead": 0,
           "arrowwidth": 1
          },
          "autotypenumbers": "strict",
          "coloraxis": {
           "colorbar": {
            "outlinewidth": 0,
            "ticks": ""
           }
          },
          "colorscale": {
           "diverging": [
            [
             0,
             "#8e0152"
            ],
            [
             0.1,
             "#c51b7d"
            ],
            [
             0.2,
             "#de77ae"
            ],
            [
             0.3,
             "#f1b6da"
            ],
            [
             0.4,
             "#fde0ef"
            ],
            [
             0.5,
             "#f7f7f7"
            ],
            [
             0.6,
             "#e6f5d0"
            ],
            [
             0.7,
             "#b8e186"
            ],
            [
             0.8,
             "#7fbc41"
            ],
            [
             0.9,
             "#4d9221"
            ],
            [
             1,
             "#276419"
            ]
           ],
           "sequential": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ],
           "sequentialminus": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ]
          },
          "colorway": [
           "#636efa",
           "#EF553B",
           "#00cc96",
           "#ab63fa",
           "#FFA15A",
           "#19d3f3",
           "#FF6692",
           "#B6E880",
           "#FF97FF",
           "#FECB52"
          ],
          "font": {
           "color": "#2a3f5f"
          },
          "geo": {
           "bgcolor": "white",
           "lakecolor": "white",
           "landcolor": "#E5ECF6",
           "showlakes": true,
           "showland": true,
           "subunitcolor": "white"
          },
          "hoverlabel": {
           "align": "left"
          },
          "hovermode": "closest",
          "mapbox": {
           "style": "light"
          },
          "paper_bgcolor": "white",
          "plot_bgcolor": "#E5ECF6",
          "polar": {
           "angularaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "radialaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "scene": {
           "xaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "yaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "zaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           }
          },
          "shapedefaults": {
           "line": {
            "color": "#2a3f5f"
           }
          },
          "ternary": {
           "aaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "baxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "caxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "title": {
           "x": 0.05
          },
          "xaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          },
          "yaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          }
         }
        },
        "title": {
         "text": "Dashboard - Rendimiento por Asignatura"
        },
        "xaxis": {
         "anchor": "y",
         "domain": [
          0,
          0.45
         ]
        },
        "xaxis2": {
         "anchor": "y2",
         "domain": [
          0.55,
          1
         ]
        },
        "xaxis3": {
         "anchor": "y3",
         "domain": [
          0,
          0.45
         ]
        },
        "xaxis4": {
         "anchor": "y4",
         "domain": [
          0.55,
          1
         ]
        },
        "xaxis5": {
         "anchor": "y5",
         "domain": [
          0,
          0.45
         ]
        },
        "xaxis6": {
         "anchor": "y6",
         "domain": [
          0.55,
          1
         ]
        },
        "yaxis": {
         "anchor": "x",
         "domain": [
          0.7777777777777778,
          1
         ]
        },
        "yaxis2": {
         "anchor": "x2",
         "domain": [
          0.7777777777777778,
          1
         ]
        },
        "yaxis3": {
         "anchor": "x3",
         "domain": [
          0.3888888888888889,
          0.6111111111111112
         ]
        },
        "yaxis4": {
         "anchor": "x4",
         "domain": [
          0.3888888888888889,
          0.6111111111111112
         ]
        },
        "yaxis5": {
         "anchor": "x5",
         "domain": [
          0,
          0.22222222222222224
         ]
        },
        "yaxis6": {
         "anchor": "x6",
         "domain": [
          0,
          0.22222222222222224
         ]
        }
       }
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Dashboard serializado correctamente\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "Visualización - Rendimiento por Asignatura\n",
    "\"\"\"\n",
    "\n",
    "subject_names = [s.replace(\"_final\", \"\") for s in subject_means.index]\n",
    "pass_names    = [s.replace(\"_status\", \"\") for s in pass_rate.index]\n",
    "std_names     = [s.replace(\"_final\", \"\") for s in std_per_subject.index]\n",
    "term1_names   = [s.replace(\"_term1\", \"\") for s in term_1_columns]\n",
    "\n",
    "# Crear subplots\n",
    "\n",
    "fig = make_subplots(\n",
    "\n",
    "    rows=3, cols=2,\n",
    "\n",
    "    subplot_titles=[\n",
    "\n",
    "        \"Nota Media por Asignatura\",\n",
    "        \"Tasa de Aprobación por Asignatura (%)\",\n",
    "        \"Desviación Estándar por Asignatura\",\n",
    "        \"Aprobados vs Reprobados por Asignatura\",\n",
    "        \"Estudiantes que Mejoraron / Empeoraron (T1→T3)\",\n",
    "        \"Progresión Media por Trimestre\"\n",
    "\n",
    "    ],\n",
    "\n",
    "    specs=[\n",
    "\n",
    "        [{\"type\": \"xy\"}, {\"type\": \"xy\"}],\n",
    "        [{\"type\": \"xy\"}, {\"type\": \"xy\"}],\n",
    "        [{\"type\": \"xy\"}, {\"type\": \"xy\"}]\n",
    "\n",
    "    ]\n",
    "\n",
    ")\n",
    "\n",
    "# Nota media por asignatura\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(x=subject_names, y=subject_means.values, name=\"Nota Media\", marker_color=\"#4C9BE8\"),\n",
    "\n",
    "    row=1, col=1\n",
    "\n",
    ")\n",
    "\n",
    "# Tasa de aprobación\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(x=pass_names, y=(pass_rate.values * 100).round(1), name=\"% Aprobados\", marker_color=\"#2ECC71\"),\n",
    "\n",
    "    row=1, col=2\n",
    "\n",
    ")\n",
    "\n",
    "# Desviación estándar\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(x=std_names, y=std_per_subject.values, name=\"Std\", marker_color=\"#E67E22\"),\n",
    "\n",
    "    row=2, col=1\n",
    "\n",
    ")\n",
    "\n",
    "# Aprobados vs reprobados\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(x=pass_names, y=passed_per_subject.values, name=\"Aprobados\", marker_color=\"#2ECC71\"),\n",
    "\n",
    "    row=2, col=2\n",
    "\n",
    ")\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(x=pass_names, y=failed_per_subject.values, name=\"Reprobados\", marker_color=\"#E74C3C\"),\n",
    "\n",
    "    row=2, col=2\n",
    "\n",
    ")\n",
    "\n",
    "# Mejoran / empeoran T1→T3\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(x=improved_series.index.tolist(), y=improved_series.values, name=\"Mejoran\", marker_color=\"#27AE60\"),\n",
    "\n",
    "    row=3, col=1\n",
    "\n",
    ")\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(x=worsened_series.index.tolist(), y=worsened_series.values, name=\"Empeoran\", marker_color=\"#C0392B\"),\n",
    "\n",
    "    row=3, col=1\n",
    "\n",
    ")\n",
    "\n",
    "# Progresión media por trimestre\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Scatter(x=term1_names, y=first_semester_avg.values, mode=\"lines+markers\", name=\"Trimestre 1\", line=dict(color=\"#3498DB\")),\n",
    "\n",
    "    row=3, col=2\n",
    "\n",
    ")\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Scatter(x=term1_names, y=second_semester_avg.values, mode=\"lines+markers\", name=\"Trimestre 2\", line=dict(color=\"#F39C12\")),\n",
    "\n",
    "    row=3, col=2\n",
    "\n",
    ")\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Scatter(x=term1_names, y=third_semester_avg.values, mode=\"lines+markers\", name=\"Trimestre 3\", line=dict(color=\"#27AE60\")),\n",
    "\n",
    "    row=3, col=2\n",
    "\n",
    ")\n",
    "\n",
    "# Layout\n",
    "\n",
    "fig.update_layout(\n",
    "\n",
    "    title_text=\"Dashboard - Rendimiento por Asignatura\",\n",
    "    height=1000,\n",
    "    barmode=\"group\",\n",
    "    showlegend=True\n",
    "\n",
    ")\n",
    "\n",
    "# Serializar a JSON\n",
    "\n",
    "dashboard_json = fig.to_json()\n",
    "\n",
    "with open(\"dashboard_subject_performance.json\", \"w\") as f:\n",
    "    json.dump(json.loads(dashboard_json), f)\n",
    "\n",
    "fig.show(renderer=\"plotly_mimetype\")\n",
    "\n",
    "print(\"Dashboard serializado correctamente\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "id": "1c559195",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-05-06T16:49:31.305883Z",
     "iopub.status.busy": "2026-05-06T16:49:31.305798Z",
     "iopub.status.idle": "2026-05-06T16:49:31.315331Z",
     "shell.execute_reply": "2026-05-06T16:49:31.314867Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "11.358\n",
      "24 0 11.0\n",
      "-0.03\n",
      "-0.038\n",
      "attendance_absences_total\n",
      "(0, 5]      1.071\n",
      "(5, 10]     1.143\n",
      "(10, 15]    1.042\n",
      "(15, 20]    1.259\n",
      "(20, 30]    1.244\n",
      "Name: failed_subjects, dtype: float64\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "Asistencia\n",
    "\"\"\"\n",
    "\n",
    "# Promedio de ausencias totales\n",
    "\n",
    "avg_absences = df_clean[\"attendance_absences_total\"].mean().round(3)\n",
    "\n",
    "print(avg_absences)\n",
    "\n",
    "# Máximo, mínimo y mediana\n",
    "\n",
    "max_absences = df_clean[\"attendance_absences_total\"].max()\n",
    "min_absences = df_clean[\"attendance_absences_total\"].min()\n",
    "median_absences = df_clean[\"attendance_absences_total\"].median()\n",
    "\n",
    "print(max_absences, min_absences, median_absences)\n",
    "\n",
    "# Correlación ausencias vs promedio de notas finales\n",
    "\n",
    "corr_absences_avg = df_clean[\"attendance_absences_total\"].corr(df_clean[\"avg_final\"]).round(3)\n",
    "\n",
    "print(corr_absences_avg)\n",
    "\n",
    "# Correlación ausencias vs tasa de aprobación\n",
    "\n",
    "corr_absences_pass = df_clean[\"attendance_absences_total\"].corr(df_clean[\"passed_rate\"]).round(3)\n",
    "\n",
    "print(corr_absences_pass)\n",
    "\n",
    "# Umbral de ausencias donde aumenta el Fail\n",
    "\n",
    "absence_bins = pd.cut(df_clean[\"attendance_absences_total\"], bins=[0, 5, 10, 15, 20, 30, 50, 100])\n",
    "threshold_fail = df_clean.groupby(absence_bins, observed=True)[\"failed_subjects\"].mean().round(3)\n",
    "\n",
    "print(threshold_fail)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "b4f9b07c",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-05-06T16:49:31.316467Z",
     "iopub.status.busy": "2026-05-06T16:49:31.316393Z",
     "iopub.status.idle": "2026-05-06T16:49:31.330838Z",
     "shell.execute_reply": "2026-05-06T16:49:31.330409Z"
    }
   },
   "outputs": [
    {
     "data": {
      "application/vnd.plotly.v1+json": {
       "config": {
        "plotlyServerURL": "https://plot.ly"
       },
       "data": [
        {
         "marker": {
          "color": "#4C9BE8"
         },
         "name": "Ausencias",
         "nbinsx": 20,
         "type": "histogram",
         "x": {
          "bdata": "GAQHEhYQCgAODgUOAQMLAQ8CDQsAEQ8NDRYLAQoPBRgIEQcLAQMKBQYFFQgGBxMVABcRDQsFCxcWBhQIEgoTBQcWEQYFBA4LEQELFwcLDQ8AEQ0TCAkUDBgEDxYVCAcBCgkYExgJCg0CAhIICQoBBgoTAQMYFRMLCwQLAhYHCAEJFAcMFwIRBAAMExUDBxUACgkMGA4VAgMVAAEUAwYNDQEHBwUQAgkEAhAFCBAOFwUKCQAGBQARFAQADhAOBwAACxUECBMACgEHBg0IChYPBhcBAgcVDw0NDBYKCQAMFhYKCAYKBhgIDAUGFxEYAgMBAQENDxECDQgAEAgBEQ4IDgkSBBIHFQQGEhcOFQ4NEgAVGAcIDwAWDwEHFwUJAggDDwQEExcJCgIECAEVEQcDBhIVCwkOFgAYAg0NFAIMEhIVBwUVGAkNCA0VCQYDBAYPAgQQFBEUDQQTFBQOFwkHCQsRAAMJBBgVEAEFGA0MDg4EFBIFDxQRFgYCCA0CFwoBDRYYAwQREgcQDg0IChQJDgMTEAAVEAMXDxQNBBgLEBQPCgUCEwUEABcSBBEWDRcMDhcDBgkHFxIYERQHFQwADgEUAwUFCgoCEhYLDxYKAQoWGBELAgYWAQcBFQoLExISCwMVAQQFFA0HBAwBEQkRGAUJCgM=",
          "dtype": "i1"
         },
         "xaxis": "x",
         "yaxis": "y"
        },
        {
         "marker": {
          "color": "#E74C3C",
          "opacity": 0.5
         },
         "mode": "markers",
         "name": "Ausencias vs Promedio",
         "type": "scatter",
         "x": {
          "bdata": "GAQHEhYQCgAODgUOAQMLAQ8CDQsAEQ8NDRYLAQoPBRgIEQcLAQMKBQYFFQgGBxMVABcRDQsFCxcWBhQIEgoTBQcWEQYFBA4LEQELFwcLDQ8AEQ0TCAkUDBgEDxYVCAcBCgkYExgJCg0CAhIICQoBBgoTAQMYFRMLCwQLAhYHCAEJFAcMFwIRBAAMExUDBxUACgkMGA4VAgMVAAEUAwYNDQEHBwUQAgkEAhAFCBAOFwUKCQAGBQARFAQADhAOBwAACxUECBMACgEHBg0IChYPBhcBAgcVDw0NDBYKCQAMFhYKCAYKBhgIDAUGFxEYAgMBAQENDxECDQgAEAgBEQ4IDgkSBBIHFQQGEhcOFQ4NEgAVGAcIDwAWDwEHFwUJAggDDwQEExcJCgIECAEVEQcDBhIVCwkOFgAYAg0NFAIMEhIVBwUVGAkNCA0VCQYDBAYPAgQQFBEUDQQTFBQOFwkHCQsRAAMJBBgVEAEFGA0MDg4EFBIFDxQRFgYCCA0CFwoBDRYYAwQREgcQDg0IChQJDgMTEAAVEAMXDxQNBBgLEBQPCgUCEwUEABcSBBEWDRcMDhcDBgkHFxIYERQHFQwADgEUAwUFCgoCEhYLDxYKAQoWGBELAgYWAQcBFQoLExISCwMVAQQFFA0HBAwBEQkRGAUJCgM=",
          "dtype": "i1"
         },
         "xaxis": "x2",
         "y": {
          "bdata": "[encoded data, 5336 characters]",
          "dtype": "f8"
         },
         "yaxis": "y2"
        },
        {
         "marker": {
          "color": "#2ECC71",
          "opacity": 0.5
         },
         "mode": "markers",
         "name": "Ausencias vs Tasa Aprobación",
         "type": "scatter",
         "x": {
          "bdata": "GAQHEhYQCgAODgUOAQMLAQ8CDQsAEQ8NDRYLAQoPBRgIEQcLAQMKBQYFFQgGBxMVABcRDQsFCxcWBhQIEgoTBQcWEQYFBA4LEQELFwcLDQ8AEQ0TCAkUDBgEDxYVCAcBCgkYExgJCg0CAhIICQoBBgoTAQMYFRMLCwQLAhYHCAEJFAcMFwIRBAAMExUDBxUACgkMGA4VAgMVAAEUAwYNDQEHBwUQAgkEAhAFCBAOFwUKCQAGBQARFAQADhAOBwAACxUECBMACgEHBg0IChYPBhcBAgcVDw0NDBYKCQAMFhYKCAYKBhgIDAUGFxEYAgMBAQENDxECDQgAEAgBEQ4IDgkSBBIHFQQGEhcOFQ4NEgAVGAcIDwAWDwEHFwUJAggDDwQEExcJCgIECAEVEQcDBhIVCwkOFgAYAg0NFAIMEhIVBwUVGAkNCA0VCQYDBAYPAgQQFBEUDQQTFBQOFwkHCQsRAAMJBBgVEAEFGA0MDg4EFBIFDxQRFgYCCA0CFwoBDRYYAwQREgcQDg0IChQJDgMTEAAVEAMXDxQNBBgLEBQPCgUCEwUEABcSBBEWDRcMDhcDBgkHFxIYERQHFQwADgEUAwUFCgoCEhYLDxYKAQoWGBELAgYWAQcBFQoLExISCwMVAQQFFA0HBAwBEQkRGAUJCgM=",
          "dtype": "i1"
         },
         "xaxis": "x3",
         "y": {
          "bdata": "[encoded data, 5336 characters]",
          "dtype": "f8"
         },
         "yaxis": "y3"
        },
        {
         "marker": {
          "color": "#E67E22"
         },
         "name": "Media Reprobadas",
         "type": "bar",
         "x": [
          "(0, 5]",
          "(5, 10]",
          "(10, 15]",
          "(15, 20]",
          "(20, 30]"
         ],
         "xaxis": "x4",
         "y": {
          "bdata": "iUFg5dAi8T99PzVeuknyP3npJjEIrPA/vp8aL90k9D+BlUOLbOfzPw==",
          "dtype": "f8"
         },
         "yaxis": "y4"
        }
       ],
       "layout": {
        "annotations": [
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Distribución de Ausencias Totales",
          "x": 0.225,
          "xanchor": "center",
          "xref": "paper",
          "y": 1,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Ausencias vs Promedio Final (r=-0.03)",
          "x": 0.775,
          "xanchor": "center",
          "xref": "paper",
          "y": 1,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Ausencias vs Tasa de Aprobación (r=-0.038)",
          "x": 0.225,
          "xanchor": "center",
          "xref": "paper",
          "y": 0.375,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Media de Reprobadas por Rango de Ausencias",
          "x": 0.775,
          "xanchor": "center",
          "xref": "paper",
          "y": 0.375,
          "yanchor": "bottom",
          "yref": "paper"
         }
        ],
        "height": 700,
        "showlegend": false,
        "template": {
         "data": {
          "bar": [
           {
            "error_x": {
             "color": "#2a3f5f"
            },
            "error_y": {
             "color": "#2a3f5f"
            },
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "bar"
           }
          ],
          "barpolar": [
           {
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "barpolar"
           }
          ],
          "carpet": [
           {
            "aaxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "baxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "type": "carpet"
           }
          ],
          "choropleth": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "choropleth"
           }
          ],
          "contour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "contour"
           }
          ],
          "contourcarpet": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "contourcarpet"
           }
          ],
          "heatmap": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmap"
           }
          ],
          "histogram": [
           {
            "marker": {
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "histogram"
           }
          ],
          "histogram2d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2d"
           }
          ],
          "histogram2dcontour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2dcontour"
           }
          ],
          "mesh3d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "mesh3d"
           }
          ],
          "parcoords": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "parcoords"
           }
          ],
          "pie": [
           {
            "automargin": true,
            "type": "pie"
           }
          ],
          "scatter": [
           {
            "fillpattern": {
             "fillmode": "overlay",
             "size": 10,
             "solidity": 0.2
            },
            "type": "scatter"
           }
          ],
          "scatter3d": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatter3d"
           }
          ],
          "scattercarpet": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattercarpet"
           }
          ],
          "scattergeo": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergeo"
           }
          ],
          "scattergl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergl"
           }
          ],
          "scattermap": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermap"
           }
          ],
          "scattermapbox": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermapbox"
           }
          ],
          "scatterpolar": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolar"
           }
          ],
          "scatterpolargl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolargl"
           }
          ],
          "scatterternary": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterternary"
           }
          ],
          "surface": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "surface"
           }
          ],
          "table": [
           {
            "cells": {
             "fill": {
              "color": "#EBF0F8"
             },
             "line": {
              "color": "white"
             }
            },
            "header": {
             "fill": {
              "color": "#C8D4E3"
             },
             "line": {
              "color": "white"
             }
            },
            "type": "table"
           }
          ]
         },
         "layout": {
          "annotationdefaults": {
           "arrowcolor": "#2a3f5f",
           "arrowhead": 0,
           "arrowwidth": 1
          },
          "autotypenumbers": "strict",
          "coloraxis": {
           "colorbar": {
            "outlinewidth": 0,
            "ticks": ""
           }
          },
          "colorscale": {
           "diverging": [
            [
             0,
             "#8e0152"
            ],
            [
             0.1,
             "#c51b7d"
            ],
            [
             0.2,
             "#de77ae"
            ],
            [
             0.3,
             "#f1b6da"
            ],
            [
             0.4,
             "#fde0ef"
            ],
            [
             0.5,
             "#f7f7f7"
            ],
            [
             0.6,
             "#e6f5d0"
            ],
            [
             0.7,
             "#b8e186"
            ],
            [
             0.8,
             "#7fbc41"
            ],
            [
             0.9,
             "#4d9221"
            ],
            [
             1,
             "#276419"
            ]
           ],
           "sequential": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ],
           "sequentialminus": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ]
          },
          "colorway": [
           "#636efa",
           "#EF553B",
           "#00cc96",
           "#ab63fa",
           "#FFA15A",
           "#19d3f3",
           "#FF6692",
           "#B6E880",
           "#FF97FF",
           "#FECB52"
          ],
          "font": {
           "color": "#2a3f5f"
          },
          "geo": {
           "bgcolor": "white",
           "lakecolor": "white",
           "landcolor": "#E5ECF6",
           "showlakes": true,
           "showland": true,
           "subunitcolor": "white"
          },
          "hoverlabel": {
           "align": "left"
          },
          "hovermode": "closest",
          "mapbox": {
           "style": "light"
          },
          "paper_bgcolor": "white",
          "plot_bgcolor": "#E5ECF6",
          "polar": {
           "angularaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "radialaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "scene": {
           "xaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "yaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "zaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           }
          },
          "shapedefaults": {
           "line": {
            "color": "#2a3f5f"
           }
          },
          "ternary": {
           "aaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "baxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "caxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "title": {
           "x": 0.05
          },
          "xaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          },
          "yaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          }
         }
        },
        "title": {
         "text": "Dashboard - Asistencia"
        },
        "xaxis": {
         "anchor": "y",
         "domain": [
          0,
          0.45
         ]
        },
        "xaxis2": {
         "anchor": "y2",
         "domain": [
          0.55,
          1
         ]
        },
        "xaxis3": {
         "anchor": "y3",
         "domain": [
          0,
          0.45
         ]
        },
        "xaxis4": {
         "anchor": "y4",
         "domain": [
          0.55,
          1
         ]
        },
        "yaxis": {
         "anchor": "x",
         "domain": [
          0.625,
          1
         ]
        },
        "yaxis2": {
         "anchor": "x2",
         "domain": [
          0.625,
          1
         ]
        },
        "yaxis3": {
         "anchor": "x3",
         "domain": [
          0,
          0.375
         ]
        },
        "yaxis4": {
         "anchor": "x4",
         "domain": [
          0,
          0.375
         ]
        }
       }
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Dashboard serializado correctamente\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "Visualización - Asistencia\n",
    "\"\"\"\n",
    "\n",
    "threshold_labels = [str(i) for i in threshold_fail.index]\n",
    "\n",
    "# Crear subplots\n",
    "\n",
    "fig = make_subplots(\n",
    "\n",
    "    rows=2, cols=2,\n",
    "\n",
    "    subplot_titles=[\n",
    "\n",
    "        \"Distribución de Ausencias Totales\",\n",
    "        f\"Ausencias vs Promedio Final (r={corr_absences_avg})\",\n",
    "        f\"Ausencias vs Tasa de Aprobación (r={corr_absences_pass})\",\n",
    "        \"Media de Reprobadas por Rango de Ausencias\"\n",
    "\n",
    "    ],\n",
    "\n",
    "    specs=[\n",
    "\n",
    "        [{\"type\": \"xy\"}, {\"type\": \"xy\"}],\n",
    "        [{\"type\": \"xy\"}, {\"type\": \"xy\"}]\n",
    "\n",
    "    ]\n",
    "\n",
    ")\n",
    "\n",
    "# Histograma de ausencias\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Histogram(x=df_clean[\"attendance_absences_total\"], nbinsx=20, name=\"Ausencias\", marker_color=\"#4C9BE8\"),\n",
    "\n",
    "    row=1, col=1\n",
    "\n",
    ")\n",
    "\n",
    "# Scatter ausencias vs promedio final\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Scatter(\n",
    "\n",
    "        x=df_clean[\"attendance_absences_total\"],\n",
    "        y=df_clean[\"avg_final\"],\n",
    "        mode=\"markers\",\n",
    "        marker=dict(color=\"#E74C3C\", opacity=0.5),\n",
    "        name=\"Ausencias vs Promedio\"\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=1, col=2\n",
    "\n",
    ")\n",
    "\n",
    "# Scatter ausencias vs tasa de aprobación\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Scatter(\n",
    "\n",
    "        x=df_clean[\"attendance_absences_total\"],\n",
    "        y=df_clean[\"passed_rate_percent\"],\n",
    "        mode=\"markers\",\n",
    "        marker=dict(color=\"#2ECC71\", opacity=0.5),\n",
    "        name=\"Ausencias vs Tasa Aprobación\"\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=2, col=1\n",
    "\n",
    ")\n",
    "\n",
    "# Media de reprobadas por rango de ausencias\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(\n",
    "\n",
    "        x=threshold_labels,\n",
    "        y=threshold_fail.values,\n",
    "        name=\"Media Reprobadas\",\n",
    "        marker_color=\"#E67E22\"\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=2, col=2\n",
    "\n",
    ")\n",
    "\n",
    "# Layout\n",
    "\n",
    "fig.update_layout(\n",
    "\n",
    "    title_text=\"Dashboard - Asistencia\",\n",
    "    height=700,\n",
    "    showlegend=False\n",
    "\n",
    ")\n",
    "\n",
    "# Serializar a JSON\n",
    "\n",
    "dashboard_json = fig.to_json()\n",
    "\n",
    "with open(\"dashboard_attendance.json\", \"w\") as f:\n",
    "    json.dump(json.loads(dashboard_json), f)\n",
    "\n",
    "fig.show(renderer=\"plotly_mimetype\")\n",
    "\n",
    "print(\"Dashboard serializado correctamente\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "id": "2ed3f365",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-05-06T16:49:31.332130Z",
     "iopub.status.busy": "2026-05-06T16:49:31.332031Z",
     "iopub.status.idle": "2026-05-06T16:49:31.338307Z",
     "shell.execute_reply": "2026-05-06T16:49:31.337887Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gender\n",
      "F    61.556\n",
      "M    62.082\n",
      "Name: avg_final, dtype: float64\n",
      "gender\n",
      "F    0.931\n",
      "M    0.935\n",
      "Name: passed_rate, dtype: float64\n",
      "country\n",
      "Burundi     61.398\n",
      "Kenia       61.879\n",
      "Ruanda      61.440\n",
      "Tanzania    61.875\n",
      "Uganda      62.452\n",
      "Name: avg_final, dtype: float64\n",
      "city\n",
      "Arusha           62.432\n",
      "Bujumbura        61.449\n",
      "Dar es Salaam    62.143\n",
      "Dodoma           60.571\n",
      "Eldoret          60.931\n",
      "Gitega           61.140\n",
      "Gulu             62.748\n",
      "Huye             60.426\n",
      "Jinja            62.480\n",
      "Kampala          62.972\n",
      "Kayanza          60.389\n",
      "Kigali           63.062\n",
      "Kisumu           63.005\n",
      "Mbale            60.806\n",
      "Mbarara          63.587\n",
      "Mbeya            61.381\n",
      "Mombasa          60.176\n",
      "Musanze          61.856\n",
      "Mwanza           63.048\n",
      "Nairobi          61.417\n",
      "Nakuru           64.535\n",
      "Ngozi            61.570\n",
      "Rubavu           60.686\n",
      "Ruyigi           62.519\n",
      "Rwamagana        60.872\n",
      "Name: avg_final, dtype: float64\n",
      "age\n",
      "11    25\n",
      "12    44\n",
      "13    74\n",
      "14    72\n",
      "15    58\n",
      "16    77\n",
      "17    75\n",
      "18    47\n",
      "19    28\n",
      "Name: count, dtype: int64\n",
      "age\n",
      "11    67.654\n",
      "12    66.818\n",
      "13    65.649\n",
      "14    63.668\n",
      "15    61.425\n",
      "16    59.879\n",
      "17    58.301\n",
      "18    57.385\n",
      "19    56.642\n",
      "Name: avg_final, dtype: float64\n",
      "academic_year\n",
      "2025-2026    61.805\n",
      "Name: avg_final, dtype: float64\n",
      "course\n",
      "Primary 6      67.558\n",
      "Secondary 1    66.145\n",
      "Secondary 2    63.625\n",
      "Secondary 3    61.679\n",
      "Secondary 4    59.741\n",
      "Secondary 5    57.623\n",
      "Secondary 6    56.903\n",
      "Name: avg_final, dtype: float64\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "Demografía\n",
    "\"\"\"\n",
    "\n",
    "# Promedio de notas por género\n",
    "\n",
    "avg_by_gender = df_clean.groupby(\"gender\")[\"avg_final\"].mean().round(3)\n",
    "\n",
    "print(avg_by_gender)\n",
    "\n",
    "# Tasa de aprobación por género\n",
    "\n",
    "pass_rate_gender = df_clean.groupby(\"gender\")[\"passed_rate\"].mean().round(3)\n",
    "\n",
    "print(pass_rate_gender)\n",
    "\n",
    "# Promedio de notas por país\n",
    "\n",
    "avg_by_country = df_clean.groupby(\"country\")[\"avg_final\"].mean().round(3)\n",
    "\n",
    "print(avg_by_country)\n",
    "\n",
    "# Promedio de notas por ciudad\n",
    "\n",
    "avg_by_city = df_clean.groupby(\"city\")[\"avg_final\"].mean().round(3)\n",
    "\n",
    "print(avg_by_city)\n",
    "\n",
    "# Distribución de edades\n",
    "\n",
    "age_distribution = df_clean[\"age\"].value_counts().sort_index()\n",
    "\n",
    "print(age_distribution)\n",
    "\n",
    "# Promedio de notas por edad\n",
    "\n",
    "avg_by_age = df_clean.groupby(\"age\")[\"avg_final\"].mean().round(3)\n",
    "\n",
    "print(avg_by_age)\n",
    "\n",
    "# Rendimiento por año académico\n",
    "\n",
    "avg_by_year = df_clean.groupby(\"academic_year\")[\"avg_final\"].mean().round(3)\n",
    "\n",
    "print(avg_by_year)\n",
    "\n",
    "# Rendimiento por course\n",
    "\n",
    "avg_by_course = df_clean.groupby(\"course\")[\"avg_final\"].mean().round(3)\n",
    "\n",
    "print(avg_by_course)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "id": "ae8aa9a8",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-05-06T16:49:31.339353Z",
     "iopub.status.busy": "2026-05-06T16:49:31.339282Z",
     "iopub.status.idle": "2026-05-06T16:49:31.355526Z",
     "shell.execute_reply": "2026-05-06T16:49:31.355090Z"
    }
   },
   "outputs": [
    {
     "data": {
      "application/vnd.plotly.v1+json": {
       "config": {
        "plotlyServerURL": "https://plot.ly"
       },
       "data": [
        {
         "marker": {
          "color": [
           "#E74C3C",
           "#3498DB"
          ]
         },
         "name": "Avg por Género",
         "type": "bar",
         "x": [
          "F",
          "M"
         ],
         "xaxis": "x",
         "y": {
          "bdata": "ukkMAivHTkDRItv5fgpPQA==",
          "dtype": "f8"
         },
         "yaxis": "y"
        },
        {
         "marker": {
          "color": [
           "#E74C3C",
           "#3498DB"
          ]
         },
         "name": "% Aprobados por Género",
         "type": "bar",
         "x": [
          "F",
          "M"
         ],
         "xaxis": "x2",
         "y": {
          "bdata": "Z2ZmZmZGV0AAAAAAAGBXQA==",
          "dtype": "f8"
         },
         "yaxis": "y2"
        },
        {
         "marker": {
          "color": "#9B59B6"
         },
         "name": "Avg por País",
         "type": "bar",
         "x": [
          "Burundi",
          "Kenia",
          "Ruanda",
          "Tanzania",
          "Uganda"
         ],
         "xaxis": "x3",
         "y": {
          "bdata": "bef7qfGyTkCNl24Sg/BOQLgehetRuE5AAAAAAADwTkBg5dAi2zlPQA==",
          "dtype": "f8"
         },
         "yaxis": "y3"
        },
        {
         "marker": {
          "color": "#F39C12"
         },
         "name": "Nº Estudiantes",
         "type": "bar",
         "x": [
          11,
          12,
          13,
          14,
          15,
          16,
          17,
          18,
          19
         ],
         "xaxis": "x4",
         "y": {
          "bdata": "GSxKSDpNSy8c",
          "dtype": "i1"
         },
         "yaxis": "y4"
        },
        {
         "line": {
          "color": "#E67E22"
         },
         "mode": "lines+markers",
         "name": "Avg por Edad",
         "type": "scatter",
         "x": [
          11,
          12,
          13,
          14,
          15,
          16,
          17,
          18,
          19
         ],
         "xaxis": "x5",
         "y": {
          "bdata": "YOXQItvpUEAxCKwcWrRQQKjGSzeJaVBAL90kBoHVT0BmZmZmZrZOQI2XbhKD8E1ASgwCK4cmTUDhehSuR7FMQBkEVg4tUkxA",
          "dtype": "f8"
         },
         "yaxis": "y5"
        },
        {
         "marker": {
          "color": "#1ABC9C"
         },
         "name": "Avg por Curso",
         "type": "bar",
         "x": [
          "Primary 6",
          "Secondary 1",
          "Secondary 2",
          "Secondary 3",
          "Secondary 4",
          "Secondary 5",
          "Secondary 6"
         ],
         "xaxis": "x6",
         "y": {
          "bdata": "wcqhRbbjUEDhehSuR4lQQAAAAAAA0E9A9P3UeOnWTkACK4cW2d5NQDm0yHa+z0xA3SQGgZVzTEA=",
          "dtype": "f8"
         },
         "yaxis": "y6"
        }
       ],
       "layout": {
        "annotations": [
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Promedio Final por Género",
          "x": 0.225,
          "xanchor": "center",
          "xref": "paper",
          "y": 1,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Tasa de Aprobación por Género (%)",
          "x": 0.775,
          "xanchor": "center",
          "xref": "paper",
          "y": 1,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Promedio Final por País",
          "x": 0.225,
          "xanchor": "center",
          "xref": "paper",
          "y": 0.6111111111111112,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Distribución de Estudiantes por Edad",
          "x": 0.775,
          "xanchor": "center",
          "xref": "paper",
          "y": 0.6111111111111112,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Promedio Final por Edad",
          "x": 0.225,
          "xanchor": "center",
          "xref": "paper",
          "y": 0.22222222222222224,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Promedio Final por Curso",
          "x": 0.775,
          "xanchor": "center",
          "xref": "paper",
          "y": 0.22222222222222224,
          "yanchor": "bottom",
          "yref": "paper"
         }
        ],
        "height": 1000,
        "showlegend": false,
        "template": {
         "data": {
          "bar": [
           {
            "error_x": {
             "color": "#2a3f5f"
            },
            "error_y": {
             "color": "#2a3f5f"
            },
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "bar"
           }
          ],
          "barpolar": [
           {
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "barpolar"
           }
          ],
          "carpet": [
           {
            "aaxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "baxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "type": "carpet"
           }
          ],
          "choropleth": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "choropleth"
           }
          ],
          "contour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "contour"
           }
          ],
          "contourcarpet": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "contourcarpet"
           }
          ],
          "heatmap": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmap"
           }
          ],
          "histogram": [
           {
            "marker": {
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "histogram"
           }
          ],
          "histogram2d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2d"
           }
          ],
          "histogram2dcontour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2dcontour"
           }
          ],
          "mesh3d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "mesh3d"
           }
          ],
          "parcoords": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "parcoords"
           }
          ],
          "pie": [
           {
            "automargin": true,
            "type": "pie"
           }
          ],
          "scatter": [
           {
            "fillpattern": {
             "fillmode": "overlay",
             "size": 10,
             "solidity": 0.2
            },
            "type": "scatter"
           }
          ],
          "scatter3d": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatter3d"
           }
          ],
          "scattercarpet": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattercarpet"
           }
          ],
          "scattergeo": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergeo"
           }
          ],
          "scattergl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergl"
           }
          ],
          "scattermap": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermap"
           }
          ],
          "scattermapbox": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermapbox"
           }
          ],
          "scatterpolar": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolar"
           }
          ],
          "scatterpolargl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolargl"
           }
          ],
          "scatterternary": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterternary"
           }
          ],
          "surface": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "surface"
           }
          ],
          "table": [
           {
            "cells": {
             "fill": {
              "color": "#EBF0F8"
             },
             "line": {
              "color": "white"
             }
            },
            "header": {
             "fill": {
              "color": "#C8D4E3"
             },
             "line": {
              "color": "white"
             }
            },
            "type": "table"
           }
          ]
         },
         "layout": {
          "annotationdefaults": {
           "arrowcolor": "#2a3f5f",
           "arrowhead": 0,
           "arrowwidth": 1
          },
          "autotypenumbers": "strict",
          "coloraxis": {
           "colorbar": {
            "outlinewidth": 0,
            "ticks": ""
           }
          },
          "colorscale": {
           "diverging": [
            [
             0,
             "#8e0152"
            ],
            [
             0.1,
             "#c51b7d"
            ],
            [
             0.2,
             "#de77ae"
            ],
            [
             0.3,
             "#f1b6da"
            ],
            [
             0.4,
             "#fde0ef"
            ],
            [
             0.5,
             "#f7f7f7"
            ],
            [
             0.6,
             "#e6f5d0"
            ],
            [
             0.7,
             "#b8e186"
            ],
            [
             0.8,
             "#7fbc41"
            ],
            [
             0.9,
             "#4d9221"
            ],
            [
             1,
             "#276419"
            ]
           ],
           "sequential": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ],
           "sequentialminus": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ]
          },
          "colorway": [
           "#636efa",
           "#EF553B",
           "#00cc96",
           "#ab63fa",
           "#FFA15A",
           "#19d3f3",
           "#FF6692",
           "#B6E880",
           "#FF97FF",
           "#FECB52"
          ],
          "font": {
           "color": "#2a3f5f"
          },
          "geo": {
           "bgcolor": "white",
           "lakecolor": "white",
           "landcolor": "#E5ECF6",
           "showlakes": true,
           "showland": true,
           "subunitcolor": "white"
          },
          "hoverlabel": {
           "align": "left"
          },
          "hovermode": "closest",
          "mapbox": {
           "style": "light"
          },
          "paper_bgcolor": "white",
          "plot_bgcolor": "#E5ECF6",
          "polar": {
           "angularaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "radialaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "scene": {
           "xaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "yaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "zaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           }
          },
          "shapedefaults": {
           "line": {
            "color": "#2a3f5f"
           }
          },
          "ternary": {
           "aaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "baxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "caxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "title": {
           "x": 0.05
          },
          "xaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          },
          "yaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          }
         }
        },
        "title": {
         "text": "Dashboard - Demografía"
        },
        "xaxis": {
         "anchor": "y",
         "domain": [
          0,
          0.45
         ]
        },
        "xaxis2": {
         "anchor": "y2",
         "domain": [
          0.55,
          1
         ]
        },
        "xaxis3": {
         "anchor": "y3",
         "domain": [
          0,
          0.45
         ]
        },
        "xaxis4": {
         "anchor": "y4",
         "domain": [
          0.55,
          1
         ]
        },
        "xaxis5": {
         "anchor": "y5",
         "domain": [
          0,
          0.45
         ]
        },
        "xaxis6": {
         "anchor": "y6",
         "domain": [
          0.55,
          1
         ]
        },
        "yaxis": {
         "anchor": "x",
         "domain": [
          0.7777777777777778,
          1
         ]
        },
        "yaxis2": {
         "anchor": "x2",
         "domain": [
          0.7777777777777778,
          1
         ]
        },
        "yaxis3": {
         "anchor": "x3",
         "domain": [
          0.3888888888888889,
          0.6111111111111112
         ]
        },
        "yaxis4": {
         "anchor": "x4",
         "domain": [
          0.3888888888888889,
          0.6111111111111112
         ]
        },
        "yaxis5": {
         "anchor": "x5",
         "domain": [
          0,
          0.22222222222222224
         ]
        },
        "yaxis6": {
         "anchor": "x6",
         "domain": [
          0,
          0.22222222222222224
         ]
        }
       }
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Dashboard serializado correctamente\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "Visualización - Demografía\n",
    "\"\"\"\n",
    "\n",
    "# Crear subplots\n",
    "\n",
    "fig = make_subplots(\n",
    "\n",
    "    rows=3, cols=2,\n",
    "\n",
    "    subplot_titles=[\n",
    "\n",
    "        \"Promedio Final por Género\",\n",
    "        \"Tasa de Aprobación por Género (%)\",\n",
    "        \"Promedio Final por País\",\n",
    "        \"Distribución de Estudiantes por Edad\",\n",
    "        \"Promedio Final por Edad\",\n",
    "        \"Promedio Final por Curso\"\n",
    "\n",
    "    ],\n",
    "\n",
    "    specs=[\n",
    "\n",
    "        [{\"type\": \"xy\"}, {\"type\": \"xy\"}],\n",
    "        [{\"type\": \"xy\"}, {\"type\": \"xy\"}],\n",
    "        [{\"type\": \"xy\"}, {\"type\": \"xy\"}]\n",
    "\n",
    "    ]\n",
    "\n",
    ")\n",
    "\n",
    "# Promedio final por género\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(\n",
    "\n",
    "        x=avg_by_gender.index.tolist(),\n",
    "        y=avg_by_gender.values,\n",
    "        name=\"Avg por Género\",\n",
    "        marker_color=[\"#E74C3C\", \"#3498DB\"]\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=1, col=1\n",
    "\n",
    ")\n",
    "\n",
    "# Tasa de aprobación por género\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(\n",
    "\n",
    "        x=pass_rate_gender.index.tolist(),\n",
    "        y=(pass_rate_gender * 100).values,\n",
    "        name=\"% Aprobados por Género\",\n",
    "        marker_color=[\"#E74C3C\", \"#3498DB\"]\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=1, col=2\n",
    "\n",
    ")\n",
    "\n",
    "# Promedio final por país\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(\n",
    "\n",
    "        x=avg_by_country.index.tolist(),\n",
    "        y=avg_by_country.values,\n",
    "        name=\"Avg por País\",\n",
    "        marker_color=\"#9B59B6\"\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=2, col=1\n",
    "\n",
    ")\n",
    "\n",
    "# Distribución de estudiantes por edad\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(\n",
    "\n",
    "        x=age_distribution.index.tolist(),\n",
    "        y=age_distribution.values,\n",
    "        name=\"Nº Estudiantes\",\n",
    "        marker_color=\"#F39C12\"\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=2, col=2\n",
    "\n",
    ")\n",
    "\n",
    "# Promedio final por edad\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Scatter(\n",
    "\n",
    "        x=avg_by_age.index.tolist(),\n",
    "        y=avg_by_age.values,\n",
    "        mode=\"lines+markers\",\n",
    "        name=\"Avg por Edad\",\n",
    "        line=dict(color=\"#E67E22\")\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=3, col=1\n",
    "\n",
    ")\n",
    "\n",
    "# Promedio final por curso\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(\n",
    "\n",
    "        x=avg_by_course.index.tolist(),\n",
    "        y=avg_by_course.values,\n",
    "        name=\"Avg por Curso\",\n",
    "        marker_color=\"#1ABC9C\"\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=3, col=2\n",
    "\n",
    ")\n",
    "\n",
    "# Layout\n",
    "\n",
    "fig.update_layout(\n",
    "\n",
    "    title_text=\"Dashboard - Demografía\",\n",
    "    height=1000,\n",
    "    showlegend=False\n",
    "\n",
    ")\n",
    "\n",
    "# Serializar a JSON\n",
    "\n",
    "dashboard_json = fig.to_json()\n",
    "\n",
    "with open(\"dashboard_demographics.json\", \"w\") as f:\n",
    "    json.dump(json.loads(dashboard_json), f)\n",
    "\n",
    "fig.show(renderer=\"plotly_mimetype\")\n",
    "\n",
    "print(\"Dashboard serializado correctamente\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "5ea97e75",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-05-06T16:49:31.356610Z",
     "iopub.status.busy": "2026-05-06T16:49:31.356532Z",
     "iopub.status.idle": "2026-05-06T16:49:31.362529Z",
     "shell.execute_reply": "2026-05-06T16:49:31.361911Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "class_group\n",
      "A    62.029\n",
      "B    61.776\n",
      "C    61.611\n",
      "Name: avg_final, dtype: float64\n",
      "class_group\n",
      "A    0.935\n",
      "B    0.930\n",
      "C    0.933\n",
      "Name: passed_rate, dtype: float64\n",
      "school_name\n",
      "Bright Future School          62.267\n",
      "Burundi Digital School        61.389\n",
      "Coastal Learning Centre       62.517\n",
      "Community Hope Centre         60.469\n",
      "Future Leaders School         60.692\n",
      "Great Lakes Academy           61.625\n",
      "Green Hills Academy           62.398\n",
      "Hillside Secondary            61.970\n",
      "Hope Rural School             62.288\n",
      "Kilimani Academy              61.805\n",
      "Kilimanjaro Digital School    62.221\n",
      "Lake Zone Institute           61.878\n",
      "Lakeview Secondary            61.257\n",
      "Mwanga Community School       61.077\n",
      "Nile Bridge Academy           62.309\n",
      "Pearl Learning Centre         62.340\n",
      "Rift Valley High              61.328\n",
      "Savannah Academy              62.208\n",
      "Sunrise Learning School       62.510\n",
      "Ubuntu Secondary              60.911\n",
      "Uhuru Secondary               61.756\n",
      "Umuco Learning Centre         61.378\n",
      "Unity Secondary               62.722\n",
      "Victoria Community School     62.606\n",
      "Vision Rwanda School          61.508\n",
      "Name: avg_final, dtype: float64\n",
      "school_name\n",
      "Bright Future School          0.957\n",
      "Burundi Digital School        0.950\n",
      "Coastal Learning Centre       0.940\n",
      "Community Hope Centre         0.914\n",
      "Future Leaders School         0.921\n",
      "Great Lakes Academy           0.941\n",
      "Green Hills Academy           0.934\n",
      "Hillside Secondary            0.927\n",
      "Hope Rural School             0.942\n",
      "Kilimani Academy              0.957\n",
      "Kilimanjaro Digital School    0.916\n",
      "Lake Zone Institute           0.908\n",
      "Lakeview Secondary            0.931\n",
      "Mwanga Community School       0.952\n",
      "Nile Bridge Academy           0.938\n",
      "Pearl Learning Centre         0.931\n",
      "Rift Valley High              0.910\n",
      "Savannah Academy              0.948\n",
      "Sunrise Learning School       0.933\n",
      "Ubuntu Secondary              0.913\n",
      "Uhuru Secondary               0.938\n",
      "Umuco Learning Centre         0.924\n",
      "Unity Secondary               0.921\n",
      "Victoria Community School     0.961\n",
      "Vision Rwanda School          0.919\n",
      "Name: passed_rate, dtype: float64\n",
      "school_name\n",
      "Bright Future School          12.652\n",
      "Burundi Digital School        11.150\n",
      "Coastal Learning Centre       14.167\n",
      "Community Hope Centre         11.583\n",
      "Future Leaders School         10.739\n",
      "Great Lakes Academy           13.333\n",
      "Green Hills Academy            8.059\n",
      "Hillside Secondary            12.522\n",
      "Hope Rural School             11.957\n",
      "Kilimani Academy              11.389\n",
      "Kilimanjaro Digital School    11.353\n",
      "Lake Zone Institute           11.235\n",
      "Lakeview Secondary            11.100\n",
      "Mwanga Community School       12.091\n",
      "Nile Bridge Academy           10.174\n",
      "Pearl Learning Centre         12.812\n",
      "Rift Valley High              11.947\n",
      "Savannah Academy              13.750\n",
      "Sunrise Learning School        8.133\n",
      "Ubuntu Secondary              11.130\n",
      "Uhuru Secondary                7.762\n",
      "Umuco Learning Centre         11.647\n",
      "Unity Secondary               12.619\n",
      "Victoria Community School      9.857\n",
      "Vision Rwanda School           9.958\n",
      "Name: attendance_absences_total, dtype: float64\n",
      "Lake Zone Institute\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "Grupo y escuela\n",
    "\"\"\"\n",
    "\n",
    "# Promedio por class_group\n",
    "\n",
    "avg_by_group = df_clean.groupby(\"class_group\")[\"avg_final\"].mean().round(3)\n",
    "\n",
    "print(avg_by_group)\n",
    "\n",
    "# Tasa de aprobación por class_group\n",
    "\n",
    "pass_rate_group = df_clean.groupby(\"class_group\")[\"passed_rate\"].mean().round(3)\n",
    "\n",
    "print(pass_rate_group)\n",
    "\n",
    "# Promedio por escuela\n",
    "\n",
    "avg_by_school = df_clean.groupby(\"school_name\")[\"avg_final\"].mean().round(3)\n",
    "\n",
    "print(avg_by_school)\n",
    "\n",
    "# Tasa de aprobación por escuela\n",
    "\n",
    "pass_rate_school = df_clean.groupby(\"school_name\")[\"passed_rate\"].mean().round(3)\n",
    "\n",
    "print(pass_rate_school)\n",
    "\n",
    "# Promedio de ausencias por escuela\n",
    "\n",
    "avg_absences_school = df_clean.groupby(\"school_name\")[\"attendance_absences_total\"].mean().round(3)\n",
    "\n",
    "print(avg_absences_school)\n",
    "\n",
    "# Escuela con mayor tasa de reprobación\n",
    "\n",
    "worst_school = pass_rate_school.idxmin()\n",
    "\n",
    "print(worst_school)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "c553780f",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-05-06T16:49:31.363740Z",
     "iopub.status.busy": "2026-05-06T16:49:31.363659Z",
     "iopub.status.idle": "2026-05-06T16:49:31.378143Z",
     "shell.execute_reply": "2026-05-06T16:49:31.377716Z"
    }
   },
   "outputs": [
    {
     "data": {
      "application/vnd.plotly.v1+json": {
       "config": {
        "plotlyServerURL": "https://plot.ly"
       },
       "data": [
        {
         "marker": {
          "color": [
           "#3498DB",
           "#9B59B6",
           "#1ABC9C"
          ]
         },
         "name": "Avg por Grupo",
         "type": "bar",
         "x": [
          "A",
          "B",
          "C"
         ],
         "xaxis": "x",
         "y": {
          "bdata": "wcqhRbYDT0AX2c73U+NOQJHtfD81zk5A",
          "dtype": "f8"
         },
         "yaxis": "y"
        },
        {
         "marker": {
          "color": [
           "#3498DB",
           "#9B59B6",
           "#1ABC9C"
          ]
         },
         "name": "% Aprobados por Grupo",
         "type": "bar",
         "x": [
          "A",
          "B",
          "C"
         ],
         "xaxis": "x2",
         "y": {
          "bdata": "AAAAAABgV0AAAAAAAEBXQDQzMzMzU1dA",
          "dtype": "f8"
         },
         "yaxis": "y2"
        },
        {
         "marker": {
          "color": "#4C9BE8"
         },
         "name": "Avg por Escuela",
         "type": "bar",
         "x": [
          "Bright Future School",
          "Burundi Digital School",
          "Coastal Learning Centre",
          "Community Hope Centre",
          "Future Leaders School",
          "Great Lakes Academy",
          "Green Hills Academy",
          "Hillside Secondary",
          "Hope Rural School",
          "Kilimani Academy",
          "Kilimanjaro Digital School",
          "Lake Zone Institute",
          "Lakeview Secondary",
          "Mwanga Community School",
          "Nile Bridge Academy",
          "Pearl Learning Centre",
          "Rift Valley High",
          "Savannah Academy",
          "Sunrise Learning School",
          "Ubuntu Secondary",
          "Uhuru Secondary",
          "Umuco Learning Centre",
          "Unity Secondary",
          "Victoria Community School",
          "Vision Rwanda School"
         ],
         "xaxis": "x3",
         "y": {
          "bdata": "GQRWDi0iT0BvEoPAyrFOQBkEVg4tQk9AeekmMQg8TkB/arx0k1hOQAAAAAAA0E5Abef7qfEyT0Bcj8L1KPxOQL6fGi/dJE9A16NwPQrnTkA/NV66SRxPQKrx0k1i8E5AN4lBYOWgTkBg5dAi24lOQGQ730+NJ09A7FG4HoUrT0BEi2zn+6lOQLTIdr6fGk9A4XoUrkdBT0D4U+Olm3ROQFTjpZvE4E5AqvHSTWKwTkAj2/l+alxPQCGwcmiRTU9AGy/dJAbBTkA=",
          "dtype": "f8"
         },
         "yaxis": "y3"
        },
        {
         "marker": {
          "color": "#E74C3C"
         },
         "name": "Ausencias Medias",
         "type": "bar",
         "x": [
          "Bright Future School",
          "Burundi Digital School",
          "Coastal Learning Centre",
          "Community Hope Centre",
          "Future Leaders School",
          "Great Lakes Academy",
          "Green Hills Academy",
          "Hillside Secondary",
          "Hope Rural School",
          "Kilimani Academy",
          "Kilimanjaro Digital School",
          "Lake Zone Institute",
          "Lakeview Secondary",
          "Mwanga Community School",
          "Nile Bridge Academy",
          "Pearl Learning Centre",
          "Rift Valley High",
          "Savannah Academy",
          "Sunrise Learning School",
          "Ubuntu Secondary",
          "Uhuru Secondary",
          "Umuco Learning Centre",
          "Unity Secondary",
          "Victoria Community School",
          "Vision Rwanda School"
         ],
         "xaxis": "x4",
         "y": {
          "bdata": "5/up8dJNKUDNzMzMzEwmQC/dJAaBVSxA0SLb+X4qJ0DufD81XnolQNEi2/l+qipAke18PzUeIEAlBoGVQwspQESLbOf76SdAukkMAivHJkDb+X5qvLQmQLgehetReCZAMzMzMzMzJkA730+Nly4oQAwCK4cWWSRAObTIdr6fKUC+nxov3eQnQAAAAAAAgCtAarx0kxhEIEDD9Shcj0ImQD81XrpJDB9AJQaBlUNLJ0CwcmiR7TwpQBBYObTItiNA0SLb+X7qI0A=",
          "dtype": "f8"
         },
         "yaxis": "y4"
        }
       ],
       "layout": {
        "annotations": [
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Promedio Final por Grupo",
          "x": 0.225,
          "xanchor": "center",
          "xref": "paper",
          "y": 1,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Tasa de Aprobación por Grupo (%)",
          "x": 0.775,
          "xanchor": "center",
          "xref": "paper",
          "y": 1,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Promedio Final por Escuela",
          "x": 0.225,
          "xanchor": "center",
          "xref": "paper",
          "y": 0.375,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Ausencias Medias por Escuela",
          "x": 0.775,
          "xanchor": "center",
          "xref": "paper",
          "y": 0.375,
          "yanchor": "bottom",
          "yref": "paper"
         }
        ],
        "height": 800,
        "showlegend": false,
        "template": {
         "data": {
          "bar": [
           {
            "error_x": {
             "color": "#2a3f5f"
            },
            "error_y": {
             "color": "#2a3f5f"
            },
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "bar"
           }
          ],
          "barpolar": [
           {
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "barpolar"
           }
          ],
          "carpet": [
           {
            "aaxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "baxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "type": "carpet"
           }
          ],
          "choropleth": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "choropleth"
           }
          ],
          "contour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "contour"
           }
          ],
          "contourcarpet": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "contourcarpet"
           }
          ],
          "heatmap": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmap"
           }
          ],
          "histogram": [
           {
            "marker": {
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "histogram"
           }
          ],
          "histogram2d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2d"
           }
          ],
          "histogram2dcontour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2dcontour"
           }
          ],
          "mesh3d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "mesh3d"
           }
          ],
          "parcoords": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "parcoords"
           }
          ],
          "pie": [
           {
            "automargin": true,
            "type": "pie"
           }
          ],
          "scatter": [
           {
            "fillpattern": {
             "fillmode": "overlay",
             "size": 10,
             "solidity": 0.2
            },
            "type": "scatter"
           }
          ],
          "scatter3d": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatter3d"
           }
          ],
          "scattercarpet": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattercarpet"
           }
          ],
          "scattergeo": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergeo"
           }
          ],
          "scattergl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergl"
           }
          ],
          "scattermap": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermap"
           }
          ],
          "scattermapbox": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermapbox"
           }
          ],
          "scatterpolar": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolar"
           }
          ],
          "scatterpolargl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolargl"
           }
          ],
          "scatterternary": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterternary"
           }
          ],
          "surface": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "surface"
           }
          ],
          "table": [
           {
            "cells": {
             "fill": {
              "color": "#EBF0F8"
             },
             "line": {
              "color": "white"
             }
            },
            "header": {
             "fill": {
              "color": "#C8D4E3"
             },
             "line": {
              "color": "white"
             }
            },
            "type": "table"
           }
          ]
         },
         "layout": {
          "annotationdefaults": {
           "arrowcolor": "#2a3f5f",
           "arrowhead": 0,
           "arrowwidth": 1
          },
          "autotypenumbers": "strict",
          "coloraxis": {
           "colorbar": {
            "outlinewidth": 0,
            "ticks": ""
           }
          },
          "colorscale": {
           "diverging": [
            [
             0,
             "#8e0152"
            ],
            [
             0.1,
             "#c51b7d"
            ],
            [
             0.2,
             "#de77ae"
            ],
            [
             0.3,
             "#f1b6da"
            ],
            [
             0.4,
             "#fde0ef"
            ],
            [
             0.5,
             "#f7f7f7"
            ],
            [
             0.6,
             "#e6f5d0"
            ],
            [
             0.7,
             "#b8e186"
            ],
            [
             0.8,
             "#7fbc41"
            ],
            [
             0.9,
             "#4d9221"
            ],
            [
             1,
             "#276419"
            ]
           ],
           "sequential": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ],
           "sequentialminus": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ]
          },
          "colorway": [
           "#636efa",
           "#EF553B",
           "#00cc96",
           "#ab63fa",
           "#FFA15A",
           "#19d3f3",
           "#FF6692",
           "#B6E880",
           "#FF97FF",
           "#FECB52"
          ],
          "font": {
           "color": "#2a3f5f"
          },
          "geo": {
           "bgcolor": "white",
           "lakecolor": "white",
           "landcolor": "#E5ECF6",
           "showlakes": true,
           "showland": true,
           "subunitcolor": "white"
          },
          "hoverlabel": {
           "align": "left"
          },
          "hovermode": "closest",
          "mapbox": {
           "style": "light"
          },
          "paper_bgcolor": "white",
          "plot_bgcolor": "#E5ECF6",
          "polar": {
           "angularaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "radialaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "scene": {
           "xaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "yaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "zaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           }
          },
          "shapedefaults": {
           "line": {
            "color": "#2a3f5f"
           }
          },
          "ternary": {
           "aaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "baxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "caxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "title": {
           "x": 0.05
          },
          "xaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          },
          "yaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          }
         }
        },
        "title": {
         "text": "Dashboard - Grupo y Escuela"
        },
        "xaxis": {
         "anchor": "y",
         "domain": [
          0,
          0.45
         ]
        },
        "xaxis2": {
         "anchor": "y2",
         "domain": [
          0.55,
          1
         ]
        },
        "xaxis3": {
         "anchor": "y3",
         "domain": [
          0,
          0.45
         ]
        },
        "xaxis4": {
         "anchor": "y4",
         "domain": [
          0.55,
          1
         ]
        },
        "yaxis": {
         "anchor": "x",
         "domain": [
          0.625,
          1
         ]
        },
        "yaxis2": {
         "anchor": "x2",
         "domain": [
          0.625,
          1
         ]
        },
        "yaxis3": {
         "anchor": "x3",
         "domain": [
          0,
          0.375
         ]
        },
        "yaxis4": {
         "anchor": "x4",
         "domain": [
          0,
          0.375
         ]
        }
       }
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Dashboard serializado correctamente\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "Visualización - Grupo y Escuela\n",
    "\"\"\"\n",
    "\n",
    "# Crear subplots\n",
    "\n",
    "fig = make_subplots(\n",
    "\n",
    "    rows=2, cols=2,\n",
    "\n",
    "    subplot_titles=[\n",
    "\n",
    "        \"Promedio Final por Grupo\",\n",
    "        \"Tasa de Aprobación por Grupo (%)\",\n",
    "        \"Promedio Final por Escuela\",\n",
    "        \"Ausencias Medias por Escuela\"\n",
    "\n",
    "    ],\n",
    "\n",
    "    specs=[\n",
    "\n",
    "        [{\"type\": \"xy\"}, {\"type\": \"xy\"}],\n",
    "        [{\"type\": \"xy\"}, {\"type\": \"xy\"}]\n",
    "\n",
    "    ]\n",
    "\n",
    ")\n",
    "\n",
    "# Promedio final por grupo\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(\n",
    "\n",
    "        x=avg_by_group.index.tolist(),\n",
    "        y=avg_by_group.values,\n",
    "        name=\"Avg por Grupo\",\n",
    "        marker_color=[\"#3498DB\", \"#9B59B6\", \"#1ABC9C\"]\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=1, col=1\n",
    "\n",
    ")\n",
    "\n",
    "# Tasa de aprobación por grupo\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(\n",
    "\n",
    "        x=pass_rate_group.index.tolist(),\n",
    "        y=(pass_rate_group * 100).values,\n",
    "        name=\"% Aprobados por Grupo\",\n",
    "        marker_color=[\"#3498DB\", \"#9B59B6\", \"#1ABC9C\"]\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=1, col=2\n",
    "\n",
    ")\n",
    "\n",
    "# Promedio final por escuela\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(\n",
    "\n",
    "        x=avg_by_school.index.tolist(),\n",
    "        y=avg_by_school.values,\n",
    "        name=\"Avg por Escuela\",\n",
    "        marker_color=\"#4C9BE8\"\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=2, col=1\n",
    "\n",
    ")\n",
    "\n",
    "# Ausencias medias por escuela\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(\n",
    "\n",
    "        x=avg_absences_school.index.tolist(),\n",
    "        y=avg_absences_school.values,\n",
    "        name=\"Ausencias Medias\",\n",
    "        marker_color=\"#E74C3C\"\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=2, col=2\n",
    "\n",
    ")\n",
    "\n",
    "# Layout\n",
    "\n",
    "fig.update_layout(\n",
    "\n",
    "    title_text=\"Dashboard - Grupo y Escuela\",\n",
    "    height=800,\n",
    "    showlegend=False\n",
    "\n",
    ")\n",
    "\n",
    "# Serializar a JSON\n",
    "\n",
    "dashboard_json = fig.to_json()\n",
    "\n",
    "with open(\"dashboard_school_group.json\", \"w\") as f:\n",
    "    json.dump(json.loads(dashboard_json), f)\n",
    "\n",
    "fig.show(renderer=\"plotly_mimetype\")\n",
    "\n",
    "print(\"Dashboard serializado correctamente\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "id": "b2b43781",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-05-06T16:49:31.379448Z",
     "iopub.status.busy": "2026-05-06T16:49:31.379351Z",
     "iopub.status.idle": "2026-05-06T16:49:31.385617Z",
     "shell.execute_reply": "2026-05-06T16:49:31.385159Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "support_level\n",
      "Medium    268\n",
      "Low       125\n",
      "High      107\n",
      "Name: count, dtype: int64\n",
      "support_level\n",
      "High      61.780\n",
      "Low       62.080\n",
      "Medium    61.687\n",
      "Name: avg_final, dtype: float64\n",
      "support_level\n",
      "High      0.922\n",
      "Low       0.942\n",
      "Medium    0.933\n",
      "Name: passed_rate, dtype: float64\n",
      "support_level\n",
      "High      11.720\n",
      "Low       11.544\n",
      "Medium    11.127\n",
      "Name: attendance_absences_total, dtype: float64\n",
      "0.081\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "Soporte\n",
    "\"\"\"\n",
    "\n",
    "# Distribución por support_level\n",
    "\n",
    "support_distribution = df_clean[\"support_level\"].value_counts()\n",
    "\n",
    "print(support_distribution)\n",
    "\n",
    "# Promedio de notas por support_level\n",
    "\n",
    "avg_by_support = df_clean.groupby(\"support_level\")[\"avg_final\"].mean().round(3)\n",
    "\n",
    "print(avg_by_support)\n",
    "\n",
    "# Tasa de aprobación por support_level\n",
    "\n",
    "pass_rate_support = df_clean.groupby(\"support_level\")[\"passed_rate\"].mean().round(3)\n",
    "\n",
    "print(pass_rate_support)\n",
    "\n",
    "# Promedio de ausencias por support_level\n",
    "\n",
    "avg_absences_support = df_clean.groupby(\"support_level\")[\"attendance_absences_total\"].mean().round(3)\n",
    "\n",
    "print(avg_absences_support)\n",
    "\n",
    "# Correlación support_level vs materias reprobadas\n",
    "\n",
    "support_map = {\"Low\": 0, \"Medium\": 1, \"High\": 2}\n",
    "df_clean[\"support_level_num\"] = df_clean[\"support_level\"].map(support_map)\n",
    "corr_support_fail = df_clean[\"support_level_num\"].corr(df_clean[\"failed_subjects\"]).round(3)\n",
    "\n",
    "print(corr_support_fail)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "id": "b45634db",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-05-06T16:49:31.386852Z",
     "iopub.status.busy": "2026-05-06T16:49:31.386774Z",
     "iopub.status.idle": "2026-05-06T16:49:31.403890Z",
     "shell.execute_reply": "2026-05-06T16:49:31.403448Z"
    }
   },
   "outputs": [
    {
     "data": {
      "application/vnd.plotly.v1+json": {
       "config": {
        "plotlyServerURL": "https://plot.ly"
       },
       "data": [
        {
         "domain": {
          "x": [
           0,
           0.45
          ],
          "y": [
           0.625,
           1
          ]
         },
         "labels": [
          "Medium",
          "Low",
          "High"
         ],
         "marker": {
          "colors": [
           "#F39C12",
           "#E74C3C",
           "#2ECC71"
          ]
         },
         "name": "Distribución Soporte",
         "type": "pie",
         "values": {
          "bdata": "DAF9AGsA",
          "dtype": "i2"
         }
        },
        {
         "marker": {
          "color": [
           "#2ECC71",
           "#E74C3C",
           "#F39C12"
          ]
         },
         "name": "Avg Final",
         "type": "bar",
         "x": [
          "High",
          "Low",
          "Medium"
         ],
         "xaxis": "x",
         "y": {
          "bdata": "pHA9CtfjTkAK16NwPQpPQA4tsp3v105A",
          "dtype": "f8"
         },
         "yaxis": "y"
        },
        {
         "marker": {
          "color": [
           "#2ECC71",
           "#E74C3C",
           "#F39C12"
          ]
         },
         "name": "% Aprobados",
         "type": "bar",
         "x": [
          "High",
          "Low",
          "Medium"
         ],
         "xaxis": "x2",
         "y": {
          "bdata": "zczMzMwMV0DMzMzMzIxXQDQzMzMzU1dA",
          "dtype": "f8"
         },
         "yaxis": "y2"
        },
        {
         "marker": {
          "color": [
           "#2ECC71",
           "#E74C3C",
           "#F39C12"
          ]
         },
         "name": "Ausencias Medias",
         "type": "bar",
         "x": [
          "High",
          "Low",
          "Medium"
         ],
         "xaxis": "x3",
         "y": {
          "bdata": "cT0K16NwJ0BKDAIrhxYnQBsv3SQGQSZA",
          "dtype": "f8"
         },
         "yaxis": "y3"
        }
       ],
       "layout": {
        "annotations": [
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Distribución de Nivel de Soporte",
          "x": 0.225,
          "xanchor": "center",
          "xref": "paper",
          "y": 1,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Promedio Final por Nivel de Soporte",
          "x": 0.775,
          "xanchor": "center",
          "xref": "paper",
          "y": 1,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Tasa de Aprobación por Nivel de Soporte (%)",
          "x": 0.225,
          "xanchor": "center",
          "xref": "paper",
          "y": 0.375,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Ausencias Medias por Nivel de Soporte",
          "x": 0.775,
          "xanchor": "center",
          "xref": "paper",
          "y": 0.375,
          "yanchor": "bottom",
          "yref": "paper"
         }
        ],
        "height": 700,
        "showlegend": false,
        "template": {
         "data": {
          "bar": [
           {
            "error_x": {
             "color": "#2a3f5f"
            },
            "error_y": {
             "color": "#2a3f5f"
            },
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "bar"
           }
          ],
          "barpolar": [
           {
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "barpolar"
           }
          ],
          "carpet": [
           {
            "aaxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "baxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "type": "carpet"
           }
          ],
          "choropleth": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "choropleth"
           }
          ],
          "contour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "contour"
           }
          ],
          "contourcarpet": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "contourcarpet"
           }
          ],
          "heatmap": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmap"
           }
          ],
          "histogram": [
           {
            "marker": {
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "histogram"
           }
          ],
          "histogram2d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2d"
           }
          ],
          "histogram2dcontour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2dcontour"
           }
          ],
          "mesh3d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "mesh3d"
           }
          ],
          "parcoords": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "parcoords"
           }
          ],
          "pie": [
           {
            "automargin": true,
            "type": "pie"
           }
          ],
          "scatter": [
           {
            "fillpattern": {
             "fillmode": "overlay",
             "size": 10,
             "solidity": 0.2
            },
            "type": "scatter"
           }
          ],
          "scatter3d": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatter3d"
           }
          ],
          "scattercarpet": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattercarpet"
           }
          ],
          "scattergeo": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergeo"
           }
          ],
          "scattergl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergl"
           }
          ],
          "scattermap": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermap"
           }
          ],
          "scattermapbox": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermapbox"
           }
          ],
          "scatterpolar": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolar"
           }
          ],
          "scatterpolargl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolargl"
           }
          ],
          "scatterternary": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterternary"
           }
          ],
          "surface": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "surface"
           }
          ],
          "table": [
           {
            "cells": {
             "fill": {
              "color": "#EBF0F8"
             },
             "line": {
              "color": "white"
             }
            },
            "header": {
             "fill": {
              "color": "#C8D4E3"
             },
             "line": {
              "color": "white"
             }
            },
            "type": "table"
           }
          ]
         },
         "layout": {
          "annotationdefaults": {
           "arrowcolor": "#2a3f5f",
           "arrowhead": 0,
           "arrowwidth": 1
          },
          "autotypenumbers": "strict",
          "coloraxis": {
           "colorbar": {
            "outlinewidth": 0,
            "ticks": ""
           }
          },
          "colorscale": {
           "diverging": [
            [
             0,
             "#8e0152"
            ],
            [
             0.1,
             "#c51b7d"
            ],
            [
             0.2,
             "#de77ae"
            ],
            [
             0.3,
             "#f1b6da"
            ],
            [
             0.4,
             "#fde0ef"
            ],
            [
             0.5,
             "#f7f7f7"
            ],
            [
             0.6,
             "#e6f5d0"
            ],
            [
             0.7,
             "#b8e186"
            ],
            [
             0.8,
             "#7fbc41"
            ],
            [
             0.9,
             "#4d9221"
            ],
            [
             1,
             "#276419"
            ]
           ],
           "sequential": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ],
           "sequentialminus": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ]
          },
          "colorway": [
           "#636efa",
           "#EF553B",
           "#00cc96",
           "#ab63fa",
           "#FFA15A",
           "#19d3f3",
           "#FF6692",
           "#B6E880",
           "#FF97FF",
           "#FECB52"
          ],
          "font": {
           "color": "#2a3f5f"
          },
          "geo": {
           "bgcolor": "white",
           "lakecolor": "white",
           "landcolor": "#E5ECF6",
           "showlakes": true,
           "showland": true,
           "subunitcolor": "white"
          },
          "hoverlabel": {
           "align": "left"
          },
          "hovermode": "closest",
          "mapbox": {
           "style": "light"
          },
          "paper_bgcolor": "white",
          "plot_bgcolor": "#E5ECF6",
          "polar": {
           "angularaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "radialaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "scene": {
           "xaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "yaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "zaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           }
          },
          "shapedefaults": {
           "line": {
            "color": "#2a3f5f"
           }
          },
          "ternary": {
           "aaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "baxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "caxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "title": {
           "x": 0.05
          },
          "xaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          },
          "yaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          }
         }
        },
        "title": {
         "text": "Dashboard - Nivel de Soporte"
        },
        "xaxis": {
         "anchor": "y",
         "domain": [
          0.55,
          1
         ]
        },
        "xaxis2": {
         "anchor": "y2",
         "domain": [
          0,
          0.45
         ]
        },
        "xaxis3": {
         "anchor": "y3",
         "domain": [
          0.55,
          1
         ]
        },
        "yaxis": {
         "anchor": "x",
         "domain": [
          0.625,
          1
         ]
        },
        "yaxis2": {
         "anchor": "x2",
         "domain": [
          0,
          0.375
         ]
        },
        "yaxis3": {
         "anchor": "x3",
         "domain": [
          0,
          0.375
         ]
        }
       }
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Dashboard serializado correctamente\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "Visualización - Soporte\n",
    "\"\"\"\n",
    "\n",
    "support_colors = {\"High\": \"#2ECC71\", \"Low\": \"#E74C3C\", \"Medium\": \"#F39C12\"}\n",
    "bar_colors = [support_colors.get(k, \"#95A5A6\") for k in avg_by_support.index]\n",
    "\n",
    "# Crear subplots\n",
    "\n",
    "fig = make_subplots(\n",
    "\n",
    "    rows=2, cols=2,\n",
    "\n",
    "    subplot_titles=[\n",
    "\n",
    "        \"Distribución de Nivel de Soporte\",\n",
    "        \"Promedio Final por Nivel de Soporte\",\n",
    "        \"Tasa de Aprobación por Nivel de Soporte (%)\",\n",
    "        \"Ausencias Medias por Nivel de Soporte\"\n",
    "\n",
    "    ],\n",
    "\n",
    "    specs=[\n",
    "\n",
    "        [{\"type\": \"domain\"}, {\"type\": \"xy\"}],\n",
    "        [{\"type\": \"xy\"},     {\"type\": \"xy\"}]\n",
    "\n",
    "    ]\n",
    "\n",
    ")\n",
    "\n",
    "# Distribución de nivel de soporte\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Pie(\n",
    "\n",
    "        labels=support_distribution.index.tolist(),\n",
    "        values=support_distribution.values,\n",
    "        marker_colors=[support_colors.get(k, \"#95A5A6\") for k in support_distribution.index],\n",
    "        name=\"Distribución Soporte\"\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=1, col=1\n",
    "\n",
    ")\n",
    "\n",
    "# Promedio final por nivel de soporte\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(\n",
    "\n",
    "        x=avg_by_support.index.tolist(),\n",
    "        y=avg_by_support.values,\n",
    "        name=\"Avg Final\",\n",
    "        marker_color=bar_colors\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=1, col=2\n",
    "\n",
    ")\n",
    "\n",
    "# Tasa de aprobación por nivel de soporte\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(\n",
    "\n",
    "        x=pass_rate_support.index.tolist(),\n",
    "        y=(pass_rate_support * 100).values,\n",
    "        name=\"% Aprobados\",\n",
    "        marker_color=bar_colors\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=2, col=1\n",
    "\n",
    ")\n",
    "\n",
    "# Ausencias medias por nivel de soporte\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(\n",
    "\n",
    "        x=avg_absences_support.index.tolist(),\n",
    "        y=avg_absences_support.values,\n",
    "        name=\"Ausencias Medias\",\n",
    "        marker_color=bar_colors\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=2, col=2\n",
    "\n",
    ")\n",
    "\n",
    "# Layout\n",
    "\n",
    "fig.update_layout(\n",
    "\n",
    "    title_text=\"Dashboard - Nivel de Soporte\",\n",
    "    height=700,\n",
    "    showlegend=False\n",
    "\n",
    ")\n",
    "\n",
    "# Serializar a JSON\n",
    "\n",
    "dashboard_json = fig.to_json()\n",
    "\n",
    "with open(\"dashboard_support.json\", \"w\") as f:\n",
    "    json.dump(json.loads(dashboard_json), f)\n",
    "\n",
    "fig.show(renderer=\"plotly_mimetype\")\n",
    "\n",
    "print(\"Dashboard serializado correctamente\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "id": "bcacb712",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-05-06T16:49:31.405076Z",
     "iopub.status.busy": "2026-05-06T16:49:31.404982Z",
     "iopub.status.idle": "2026-05-06T16:49:31.412247Z",
     "shell.execute_reply": "2026-05-06T16:49:31.411811Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Mathematics            0.442\n",
      "English               -0.143\n",
      "Science                1.759\n",
      "ICT                    1.333\n",
      "Geography              2.378\n",
      "History               -0.058\n",
      "Civics                 0.514\n",
      "Agriculture           -0.675\n",
      "Business_Studies       0.536\n",
      "Physical_Education     1.507\n",
      "Swahili                1.189\n",
      "French                 1.088\n",
      "Biology                1.278\n",
      "Chemistry              0.543\n",
      "Physics                0.818\n",
      "Entrepreneurship       1.655\n",
      "Fine_Arts             -0.140\n",
      "Music                 -1.805\n",
      "Additional_Math        1.899\n",
      "Religious_Education    0.444\n",
      "dtype: float64\n",
      "Mathematics            1.882\n",
      "English                1.274\n",
      "Science                0.130\n",
      "ICT                    0.452\n",
      "Geography              0.485\n",
      "History                1.508\n",
      "Civics                 1.837\n",
      "Agriculture            3.470\n",
      "Business_Studies       1.538\n",
      "Physical_Education     0.231\n",
      "Swahili                1.671\n",
      "French                 1.049\n",
      "Biology                1.405\n",
      "Chemistry              0.503\n",
      "Physics                1.119\n",
      "Entrepreneurship       0.674\n",
      "Fine_Arts              2.210\n",
      "Music                  4.017\n",
      "Additional_Math        0.198\n",
      "Religious_Education   -0.714\n",
      "dtype: float64\n",
      "Mathematics            2.324\n",
      "English                1.131\n",
      "Science                1.889\n",
      "ICT                    1.785\n",
      "Geography              2.863\n",
      "History                1.451\n",
      "Civics                 2.351\n",
      "Agriculture            2.795\n",
      "Business_Studies       2.074\n",
      "Physical_Education     1.738\n",
      "Swahili                2.859\n",
      "French                 2.138\n",
      "Biology                2.684\n",
      "Chemistry              1.046\n",
      "Physics                1.937\n",
      "Entrepreneurship       2.330\n",
      "Fine_Arts              2.070\n",
      "Music                  2.212\n",
      "Additional_Math        2.097\n",
      "Religious_Education   -0.270\n",
      "dtype: float64\n",
      "72.2\n",
      "27.8\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "Progresión trimestral\n",
    "\"\"\"\n",
    "\n",
    "# Variación promedio term1 -> term2 por materia\n",
    "term1_term2_diff = {}\n",
    "term2_term3_diff = {}\n",
    "term1_term3_diff = {}\n",
    "\n",
    "for subject in subjects:\n",
    "    t1 = df_clean[f\"{subject}_term1\"].mean()\n",
    "    t2 = df_clean[f\"{subject}_term2\"].mean()\n",
    "    t3 = df_clean[f\"{subject}_term3\"].mean()\n",
    "    \n",
    "    term1_term2_diff[subject] = round(t2 - t1, 3)\n",
    "    term2_term3_diff[subject] = round(t3 - t2, 3)\n",
    "    term1_term3_diff[subject] = round(t3 - t1, 3)\n",
    "\n",
    "term1_term2_diff = pd.Series(term1_term2_diff)\n",
    "term2_term3_diff = pd.Series(term2_term3_diff)\n",
    "term1_term3_diff = pd.Series(term1_term3_diff)\n",
    "\n",
    "print(term1_term2_diff)\n",
    "print(term2_term3_diff)\n",
    "print(term1_term3_diff)\n",
    "\n",
    "# % estudiantes que mejoran entre term1 y term3 (global)\n",
    "improved_pct = (\n",
    "\n",
    "    (df_clean[term_3_columns].mean(axis=1) > df_clean[term_1_columns].mean(axis=1)).sum()\n",
    "    / len(df_clean) * 100\n",
    "\n",
    ").round(3)\n",
    "\n",
    "print(improved_pct)\n",
    "\n",
    "# % estudiantes que empeoran entre term1 y term3 (global)\n",
    "worsened_pct = (\n",
    "\n",
    "    (df_clean[term_3_columns].mean(axis=1) < df_clean[term_1_columns].mean(axis=1)).sum()\n",
    "    / len(df_clean) * 100\n",
    "\n",
    ").round(3)\n",
    "\n",
    "print(worsened_pct)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "id": "8ffc687e",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-05-06T16:49:31.413314Z",
     "iopub.status.busy": "2026-05-06T16:49:31.413244Z",
     "iopub.status.idle": "2026-05-06T16:49:31.479451Z",
     "shell.execute_reply": "2026-05-06T16:49:31.479001Z"
    }
   },
   "outputs": [
    {
     "data": {
      "application/vnd.plotly.v1+json": {
       "config": {
        "plotlyServerURL": "https://plot.ly"
       },
       "data": [
        {
         "marker": {
          "color": [
           "#2ECC71",
           "#E74C3C",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#E74C3C",
           "#2ECC71",
           "#E74C3C",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#E74C3C",
           "#E74C3C",
           "#2ECC71",
           "#2ECC71"
          ]
         },
         "name": "T1→T2",
         "type": "bar",
         "x": [
          "Mathematics",
          "English",
          "Science",
          "ICT",
          "Geography",
          "History",
          "Civics",
          "Agriculture",
          "Business_Studies",
          "Physical_Education",
          "Swahili",
          "French",
          "Biology",
          "Chemistry",
          "Physics",
          "Entrepreneurship",
          "Fine_Arts",
          "Music",
          "Additional_Math",
          "Religious_Education"
         ],
         "xaxis": "x",
         "y": {
          "bdata": "fT81XrpJ3D/n+6nx0k3Cv76fGi/dJPw/hxbZzvdT9T+gGi/dJAYDQBkEVg4tsq2/ppvEILBy4D+amZmZmZnlv/T91HjpJuE/6SYxCKwc+D+gGi/dJAbzP5zEILByaPE/ppvEILBy9D/HSzeJQWDhP5MYBFYOLeo/exSuR+F6+j/sUbgehevBv+F6FK5H4fy//Knx0k1i/j/RItv5fmrcPw==",
          "dtype": "f8"
         },
         "yaxis": "y"
        },
        {
         "marker": {
          "color": [
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#E74C3C"
          ]
         },
         "name": "T2→T3",
         "type": "bar",
         "x": [
          "Mathematics",
          "English",
          "Science",
          "ICT",
          "Geography",
          "History",
          "Civics",
          "Agriculture",
          "Business_Studies",
          "Physical_Education",
          "Swahili",
          "French",
          "Biology",
          "Chemistry",
          "Physics",
          "Entrepreneurship",
          "Fine_Arts",
          "Music",
          "Additional_Math",
          "Religious_Education"
         ],
         "xaxis": "x2",
         "y": {
          "bdata": "6SYxCKwc/j/8qfHSTWL0P6RwPQrXo8A/IbByaJHt3D8K16NwPQrfP1TjpZvEIPg/MQisHFpk/T/D9Shcj8ILQM/3U+Olm/g/xSCwcmiRzT8j2/l+arz6P2IQWDm0yPA/exSuR+F69j9/arx0kxjgP4GVQ4ts5/E/xSCwcmiR5T+uR+F6FK4BQMUgsHJoERBA8tJNYhBYyT8MAiuHFtnmvw==",
          "dtype": "f8"
         },
         "yaxis": "y2"
        },
        {
         "marker": {
          "color": [
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#2ECC71",
           "#E74C3C"
          ]
         },
         "name": "T1→T3",
         "type": "bar",
         "x": [
          "Mathematics",
          "English",
          "Science",
          "ICT",
          "Geography",
          "History",
          "Civics",
          "Agriculture",
          "Business_Studies",
          "Physical_Education",
          "Swahili",
          "French",
          "Biology",
          "Chemistry",
          "Physics",
          "Entrepreneurship",
          "Fine_Arts",
          "Music",
          "Additional_Math",
          "Religious_Education"
         ],
         "xaxis": "x3",
         "y": {
          "bdata": "ZDvfT42XAkB/arx0kxjyP9NNYhBYOf4/j8L1KFyP/D+BlUOLbOcGQJ7vp8ZLN/c/AiuHFtnOAkBcj8L1KFwGQGQ730+NlwBAAiuHFtnO+z+sHFpkO98GQLTIdr6fGgFARrbz/dR4BUAj2/l+arzwP8uhRbbz/f4/pHA9CtejAkCPwvUoXI8AQBkEVg4tsgFALbKd76fGAEBI4XoUrkfRvw==",
          "dtype": "f8"
         },
         "yaxis": "y3"
        },
        {
         "domain": {
          "x": [
           0.55,
           1
          ],
          "y": [
           0,
           0.375
          ]
         },
         "labels": [
          "Mejoran",
          "Empeoran"
         ],
         "marker": {
          "colors": [
           "#2ECC71",
           "#E74C3C"
          ]
         },
         "name": "Tendencia Global",
         "type": "pie",
         "values": [
          72.2,
          27.8
         ]
        }
       ],
       "layout": {
        "annotations": [
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Variación Trimestre 1 → 2 por Asignatura",
          "x": 0.225,
          "xanchor": "center",
          "xref": "paper",
          "y": 1,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Variación Trimestre 2 → 3 por Asignatura",
          "x": 0.775,
          "xanchor": "center",
          "xref": "paper",
          "y": 1,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "Variación Trimestre 1 → 3 por Asignatura",
          "x": 0.225,
          "xanchor": "center",
          "xref": "paper",
          "y": 0.375,
          "yanchor": "bottom",
          "yref": "paper"
         },
         {
          "font": {
           "size": 16
          },
          "showarrow": false,
          "text": "% Estudiantes que Mejoran / Empeoran (Global)",
          "x": 0.775,
          "xanchor": "center",
          "xref": "paper",
          "y": 0.375,
          "yanchor": "bottom",
          "yref": "paper"
         }
        ],
        "height": 800,
        "showlegend": false,
        "template": {
         "data": {
          "bar": [
           {
            "error_x": {
             "color": "#2a3f5f"
            },
            "error_y": {
             "color": "#2a3f5f"
            },
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "bar"
           }
          ],
          "barpolar": [
           {
            "marker": {
             "line": {
              "color": "#E5ECF6",
              "width": 0.5
             },
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "barpolar"
           }
          ],
          "carpet": [
           {
            "aaxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "baxis": {
             "endlinecolor": "#2a3f5f",
             "gridcolor": "white",
             "linecolor": "white",
             "minorgridcolor": "white",
             "startlinecolor": "#2a3f5f"
            },
            "type": "carpet"
           }
          ],
          "choropleth": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "choropleth"
           }
          ],
          "contour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "contour"
           }
          ],
          "contourcarpet": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "contourcarpet"
           }
          ],
          "heatmap": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "heatmap"
           }
          ],
          "histogram": [
           {
            "marker": {
             "pattern": {
              "fillmode": "overlay",
              "size": 10,
              "solidity": 0.2
             }
            },
            "type": "histogram"
           }
          ],
          "histogram2d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2d"
           }
          ],
          "histogram2dcontour": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "histogram2dcontour"
           }
          ],
          "mesh3d": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "type": "mesh3d"
           }
          ],
          "parcoords": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "parcoords"
           }
          ],
          "pie": [
           {
            "automargin": true,
            "type": "pie"
           }
          ],
          "scatter": [
           {
            "fillpattern": {
             "fillmode": "overlay",
             "size": 10,
             "solidity": 0.2
            },
            "type": "scatter"
           }
          ],
          "scatter3d": [
           {
            "line": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatter3d"
           }
          ],
          "scattercarpet": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattercarpet"
           }
          ],
          "scattergeo": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergeo"
           }
          ],
          "scattergl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattergl"
           }
          ],
          "scattermap": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermap"
           }
          ],
          "scattermapbox": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scattermapbox"
           }
          ],
          "scatterpolar": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolar"
           }
          ],
          "scatterpolargl": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterpolargl"
           }
          ],
          "scatterternary": [
           {
            "marker": {
             "colorbar": {
              "outlinewidth": 0,
              "ticks": ""
             }
            },
            "type": "scatterternary"
           }
          ],
          "surface": [
           {
            "colorbar": {
             "outlinewidth": 0,
             "ticks": ""
            },
            "colorscale": [
             [
              0,
              "#0d0887"
             ],
             [
              0.1111111111111111,
              "#46039f"
             ],
             [
              0.2222222222222222,
              "#7201a8"
             ],
             [
              0.3333333333333333,
              "#9c179e"
             ],
             [
              0.4444444444444444,
              "#bd3786"
             ],
             [
              0.5555555555555556,
              "#d8576b"
             ],
             [
              0.6666666666666666,
              "#ed7953"
             ],
             [
              0.7777777777777778,
              "#fb9f3a"
             ],
             [
              0.8888888888888888,
              "#fdca26"
             ],
             [
              1,
              "#f0f921"
             ]
            ],
            "type": "surface"
           }
          ],
          "table": [
           {
            "cells": {
             "fill": {
              "color": "#EBF0F8"
             },
             "line": {
              "color": "white"
             }
            },
            "header": {
             "fill": {
              "color": "#C8D4E3"
             },
             "line": {
              "color": "white"
             }
            },
            "type": "table"
           }
          ]
         },
         "layout": {
          "annotationdefaults": {
           "arrowcolor": "#2a3f5f",
           "arrowhead": 0,
           "arrowwidth": 1
          },
          "autotypenumbers": "strict",
          "coloraxis": {
           "colorbar": {
            "outlinewidth": 0,
            "ticks": ""
           }
          },
          "colorscale": {
           "diverging": [
            [
             0,
             "#8e0152"
            ],
            [
             0.1,
             "#c51b7d"
            ],
            [
             0.2,
             "#de77ae"
            ],
            [
             0.3,
             "#f1b6da"
            ],
            [
             0.4,
             "#fde0ef"
            ],
            [
             0.5,
             "#f7f7f7"
            ],
            [
             0.6,
             "#e6f5d0"
            ],
            [
             0.7,
             "#b8e186"
            ],
            [
             0.8,
             "#7fbc41"
            ],
            [
             0.9,
             "#4d9221"
            ],
            [
             1,
             "#276419"
            ]
           ],
           "sequential": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ],
           "sequentialminus": [
            [
             0,
             "#0d0887"
            ],
            [
             0.1111111111111111,
             "#46039f"
            ],
            [
             0.2222222222222222,
             "#7201a8"
            ],
            [
             0.3333333333333333,
             "#9c179e"
            ],
            [
             0.4444444444444444,
             "#bd3786"
            ],
            [
             0.5555555555555556,
             "#d8576b"
            ],
            [
             0.6666666666666666,
             "#ed7953"
            ],
            [
             0.7777777777777778,
             "#fb9f3a"
            ],
            [
             0.8888888888888888,
             "#fdca26"
            ],
            [
             1,
             "#f0f921"
            ]
           ]
          },
          "colorway": [
           "#636efa",
           "#EF553B",
           "#00cc96",
           "#ab63fa",
           "#FFA15A",
           "#19d3f3",
           "#FF6692",
           "#B6E880",
           "#FF97FF",
           "#FECB52"
          ],
          "font": {
           "color": "#2a3f5f"
          },
          "geo": {
           "bgcolor": "white",
           "lakecolor": "white",
           "landcolor": "#E5ECF6",
           "showlakes": true,
           "showland": true,
           "subunitcolor": "white"
          },
          "hoverlabel": {
           "align": "left"
          },
          "hovermode": "closest",
          "mapbox": {
           "style": "light"
          },
          "paper_bgcolor": "white",
          "plot_bgcolor": "#E5ECF6",
          "polar": {
           "angularaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "radialaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "scene": {
           "xaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "yaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           },
           "zaxis": {
            "backgroundcolor": "#E5ECF6",
            "gridcolor": "white",
            "gridwidth": 2,
            "linecolor": "white",
            "showbackground": true,
            "ticks": "",
            "zerolinecolor": "white"
           }
          },
          "shapedefaults": {
           "line": {
            "color": "#2a3f5f"
           }
          },
          "ternary": {
           "aaxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "baxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           },
           "bgcolor": "#E5ECF6",
           "caxis": {
            "gridcolor": "white",
            "linecolor": "white",
            "ticks": ""
           }
          },
          "title": {
           "x": 0.05
          },
          "xaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          },
          "yaxis": {
           "automargin": true,
           "gridcolor": "white",
           "linecolor": "white",
           "ticks": "",
           "title": {
            "standoff": 15
           },
           "zerolinecolor": "white",
           "zerolinewidth": 2
          }
         }
        },
        "title": {
         "text": "Dashboard - Progresión Trimestral"
        },
        "xaxis": {
         "anchor": "y",
         "domain": [
          0,
          0.45
         ]
        },
        "xaxis2": {
         "anchor": "y2",
         "domain": [
          0.55,
          1
         ]
        },
        "xaxis3": {
         "anchor": "y3",
         "domain": [
          0,
          0.45
         ]
        },
        "yaxis": {
         "anchor": "x",
         "domain": [
          0.625,
          1
         ]
        },
        "yaxis2": {
         "anchor": "x2",
         "domain": [
          0.625,
          1
         ]
        },
        "yaxis3": {
         "anchor": "x3",
         "domain": [
          0,
          0.375
         ]
        }
       }
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Dashboard serializado correctamente\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "Visualización - Progresión Trimestral\n",
    "\"\"\"\n",
    "\n",
    "colors_t1t2 = [\"#2ECC71\" if v >= 0 else \"#E74C3C\" for v in term1_term2_diff.values]\n",
    "colors_t2t3 = [\"#2ECC71\" if v >= 0 else \"#E74C3C\" for v in term2_term3_diff.values]\n",
    "colors_t1t3 = [\"#2ECC71\" if v >= 0 else \"#E74C3C\" for v in term1_term3_diff.values]\n",
    "\n",
    "# Crear subplots\n",
    "\n",
    "fig = make_subplots(\n",
    "\n",
    "    rows=2, cols=2,\n",
    "\n",
    "    subplot_titles=[\n",
    "\n",
    "        \"Variación Trimestre 1 → 2 por Asignatura\",\n",
    "        \"Variación Trimestre 2 → 3 por Asignatura\",\n",
    "        \"Variación Trimestre 1 → 3 por Asignatura\",\n",
    "        \"% Estudiantes que Mejoran / Empeoran (Global)\"\n",
    "\n",
    "    ],\n",
    "\n",
    "    specs=[\n",
    "\n",
    "        [{\"type\": \"xy\"},     {\"type\": \"xy\"}],\n",
    "        [{\"type\": \"xy\"},     {\"type\": \"domain\"}]\n",
    "\n",
    "    ]\n",
    "\n",
    ")\n",
    "\n",
    "# Variación T1 → T2\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(\n",
    "\n",
    "        x=term1_term2_diff.index.tolist(),\n",
    "        y=term1_term2_diff.values,\n",
    "        name=\"T1→T2\",\n",
    "        marker_color=colors_t1t2\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=1, col=1\n",
    "\n",
    ")\n",
    "\n",
    "# Variación T2 → T3\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(\n",
    "\n",
    "        x=term2_term3_diff.index.tolist(),\n",
    "        y=term2_term3_diff.values,\n",
    "        name=\"T2→T3\",\n",
    "        marker_color=colors_t2t3\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=1, col=2\n",
    "\n",
    ")\n",
    "\n",
    "# Variación T1 → T3\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Bar(\n",
    "\n",
    "        x=term1_term3_diff.index.tolist(),\n",
    "        y=term1_term3_diff.values,\n",
    "        name=\"T1→T3\",\n",
    "        marker_color=colors_t1t3\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=2, col=1\n",
    "\n",
    ")\n",
    "\n",
    "# % Mejoran / empeoran global\n",
    "\n",
    "fig.add_trace(\n",
    "\n",
    "    go.Pie(\n",
    "\n",
    "        labels=[\"Mejoran\", \"Empeoran\"],\n",
    "        values=[improved_pct, worsened_pct],\n",
    "        marker_colors=[\"#2ECC71\", \"#E74C3C\"],\n",
    "        name=\"Tendencia Global\"\n",
    "\n",
    "    ),\n",
    "\n",
    "    row=2, col=2\n",
    "\n",
    ")\n",
    "\n",
    "# Layout\n",
    "\n",
    "fig.update_layout(\n",
    "\n",
    "    title_text=\"Dashboard - Progresión Trimestral\",\n",
    "    height=800,\n",
    "    showlegend=False\n",
    "\n",
    ")\n",
    "\n",
    "# Serializar a JSON\n",
    "\n",
    "dashboard_json = fig.to_json()\n",
    "\n",
    "with open(\"dashboard_term_progression.json\", \"w\") as f:\n",
    "    \n",
    "    json.dump(json.loads(dashboard_json), f)\n",
    "\n",
    "fig.show(renderer=\"plotly_mimetype\")\n",
    "\n",
    "print(\"Dashboard serializado correctamente\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "id": "35bc3bd3",
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "Guardar Dataset Final en un CSV\n",
    "\"\"\"\n",
    "\n",
    "df_clean.insert(0, \"student_id\", df[\"student_id\"])\n",
    "\n",
    "df_clean[\"notes\"] = df[\"notes\"]\n",
    "\n",
    "df_clean.to_csv(\"../datasets/clean_dataset.csv\", index = False)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "internal_venv (3.13.11)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
