File size: 5,748 Bytes
ffd39e7
 
 
6552319
ffd39e7
 
 
 
 
 
 
 
 
 
 
 
 
854f695
 
ffd39e7
 
 
 
 
 
 
 
 
 
 
 
 
 
1b94250
ffd39e7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99e3c0f
 
 
7f6a483
 
f1688db
a17a72b
 
7f6a483
 
60e14a3
 
a17a72b
 
8436af1
a17a72b
ffd39e7
 
 
 
 
 
f1688db
b89fc19
ffd39e7
 
 
 
 
 
 
 
c18ccd9
8753be4
14d901a
 
 
 
 
 
 
 
 
8753be4
14d901a
8753be4
14d901a
 
8753be4
 
14d901a
 
8753be4
14d901a
 
 
 
 
 
 
5d9323d
14d901a
 
8753be4
493a1c3
ffd39e7
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import matplotlib.pyplot as plt
import io
import streamlit as st
from graphviz import Digraph

class Visualization:
    def plot_intervention_statistics(self, intervention_stats):
        sessions_held = intervention_stats['Intervention Sessions Held'].values[0]
        sessions_not_held = intervention_stats['Intervention Sessions Not Held'].values[0]

        fig, ax = plt.subplots()
        ax.bar(['Intervention Sessions'], [sessions_held], label='Held', color='#358E66')
        ax.bar(['Intervention Sessions'], [sessions_not_held], bottom=[sessions_held], label='Not Held', color='#91D6B8')

        ax.text(0, sessions_held / 2, str(sessions_held), ha='center', va='center', color='white', fontweight='bold', fontsize=14)
        ax.text(0, sessions_held + sessions_not_held / 2, str(sessions_not_held), ha='center', va='center', color='black', fontweight='bold', fontsize=14)

        ax.set_ylabel('Dosage')
        ax.set_title('Intervention Dosage', fontsize=16)
        handles, labels = ax.get_legend_handles_labels()
        ax.legend(handles[::-1], labels[::-1])

        ax.spines['top'].set_visible(False)
        ax.spines['right'].set_visible(False)
        
        st.pyplot(fig)
        return fig

    def plot_student_metrics(self, student_metrics_df, attendance_avg_stats, engagement_avg_stats):
        fig, ax = plt.subplots(figsize=(10, 6))
        bar_width = 0.35
        index = range(len(student_metrics_df))

        attendance_bars = ax.bar(
            [i - bar_width / 2 for i in index], 
            student_metrics_df['Attendance (%)'], 
            width=bar_width, label='Attendance (%)', 
            color='#005288', alpha=0.7
        )
        engagement_bars = ax.bar(
            [i + bar_width / 2 for i in index], 
            student_metrics_df['Engagement (%)'], 
            width=bar_width, label='Engagement (%)', 
            color='#3AB0FF', alpha=0.7
        )

        for bar in attendance_bars:
            height = bar.get_height()
            ax.text(bar.get_x() + bar.get_width() / 2, height, f'{height:.0f}%', ha='center', va='bottom', color='black')

        for bar in engagement_bars:
            height = bar.get_height()
            ax.text(bar.get_x() + bar.get_width() / 2, height, f'{height:.0f}%', ha='center', va='bottom', color='black')

        # Get the current x-axis limits
        x_min, x_max = ax.get_xlim()

        # Highlight the range 80-89 for "Engagement Threshold" and 90-100 for "Attendance Threshold"
        ax.fill_betweenx(y=[90, 100], x1=x_min, x2=x_max, color='#005288', alpha=0.2, label='Attendance Threshold: ≥ 90%')
        ax.fill_betweenx(y=[80, 90], x1=x_min, x2=x_max, color='#3AB0FF', alpha=0.2, label='Engagement Threshold: ≥ 80%')

        # Add horizontal lines for thresholds and averages
        # ax.axhline(y=90, color='#005288', linestyle=':', linewidth=1.5, label=f'Attendance Threshold: ≥ 90%')
        # ax.axhline(y=80, color='#3AB0FF', linestyle=':', linewidth=1.5, label=f'Engagement Threshold: ≥ 80%')
        ax.axhline(y=attendance_avg_stats, color='#005288', linestyle='--', linewidth=1.5, label=f'Attendance Average: {attendance_avg_stats}%')
        ax.axhline(y=engagement_avg_stats, color='#3AB0FF', linestyle='--', linewidth=1.5, label=f'Engagement Average: {engagement_avg_stats}%')
        
        # Set the x-limits to ensure the fill covers the entire plot width
        ax.set_xlim(left=x_min, right=x_max)
        
        ax.set_xlabel('Student')
        ax.set_ylabel('Percentage (%)')
        ax.set_title('Student Attendance and Engagement Metrics')
        ax.legend(loc='upper right', frameon=False)
        ax.set_xticks(index)
        ax.set_xticklabels(student_metrics_df['Student'], rotation=0, ha='right')
        ax.set_ylim(0, 140)
        ax.yaxis.set_ticks(range(0, 124, 25))

        ax.spines['top'].set_visible(False)
        ax.spines['right'].set_visible(False)

        plt.tight_layout()
        st.pyplot(fig)
        return fig

    def build_tree_diagram(self, row):
        dot = Digraph()
    
        # Add the student's name as the first node
        student_name = row['Student']  # Assuming 'Student' is the column name for student names
        dot.node("Student", student_name)
    
        # Connect the student's name to the first question
        dot.edge("Student", "Q1")
    
        # Add the first question node
        dot.node("Q1", "Has the student attended ≥ 90% of interventions?")
    
        if row["Attended ≥ 90%"] == "No":
            # If attendance is less than 90%, add the corresponding action node
            dot.node("A1", "Address Attendance", shape="box")
            dot.edge("Q1", "A1", label="No")
        else:
            # If attendance is 90% or more, proceed to the next question
            dot.node("Q2", "Has the student been engaged ≥ 80% of intervention time?")
            dot.edge("Q1", "Q2", label="Yes")
    
            if row["Engagement ≥ 80%"] == "No":
                # If engagement is less than 80%, add the corresponding action node
                dot.node("A2", "Address Engagement", shape="box")
                dot.edge("Q2", "A2", label="No")
            else:
                # If engagement is 80% or more, add the final action node
                dot.node("A3", "Consider barriers, fidelity, and progress monitoring", shape="box")
                dot.edge("Q2", "A3", label="Yes")
    
        return dot
    
    def download_chart(self, fig, filename):
        buffer = io.BytesIO()
        fig.savefig(buffer, format='png')
        buffer.seek(0)
        st.download_button(label="Download Chart", data=buffer, file_name=filename, mime='image/png', icon="📊", use_container_width=True)