import gradio as gr import pandas as pd import numpy as np import matplotlib.pyplot as plt def plot_likert_scores(file): # Load the Excel file into pandas df = pd.read_excel(file.name, sheet_name=0, header=None) # Extract pre and post survey blocks (edit row indices if needed) pre_df = df.iloc[1:5, :6].copy() post_df = df.iloc[12:15, :6].copy() pre_df.columns = ['identifier', 'Degree', 'Confidence', 'Feedback', 'Preparedness', 'Enjoyment'] post_df.columns = ['identifier', 'Degree', 'Confidence', 'Feedback', 'Preparedness', 'Enjoyment'] # Clean identifier def clean_identifier(x): try: return int(str(x).strip()) except: return np.nan pre_df['identifier'] = pre_df['identifier'].apply(clean_identifier) post_df['identifier'] = post_df['identifier'].apply(clean_identifier) pre_df = pre_df.dropna(subset=['identifier']) post_df = post_df.dropna(subset=['identifier']) pre_df['identifier'] = pre_df['identifier'].astype(int) post_df['identifier'] = post_df['identifier'].astype(int) # Filter for identifier 7 pre_7 = pre_df[pre_df['identifier'] == 7] post_7 = post_df[post_df['identifier'] == 7] # If data for identifier 7 is missing if pre_7.empty or post_7.empty: return "Identifier 7 is missing from pre or post survey data. Please check your file." # Map Likert values likert_map = { 'Strongly Disagree': 1, 'Disagree': 2, 'Agree': 3, 'Strongly Agree': 4 } questions = ['Confidence', 'Feedback', 'Enjoyment'] pretty_labels = ['Confidence', 'Feedback', 'Enjoyment'] pre_scores = [likert_map.get(pre_7[q].values[0], np.nan) for q in questions] post_scores = [likert_map.get(post_7[q].values[0], np.nan) for q in questions] # Plot x = np.arange(len(questions)) width = 0.35 fig, ax = plt.subplots(figsize=(7, 5)) bars1 = ax.bar(x - width/2, pre_scores, width, label='Pre-survey', color='#3182bd', edgecolor='black') bars2 = ax.bar(x + width/2, post_scores, width, label='Post-survey', color='#fdae6b', edgecolor='black') # Add value labels for bar in bars1 + bars2: height = bar.get_height() if not np.isnan(height): ax.annotate(f'{int(height)}', xy=(bar.get_x() + bar.get_width() / 2, height), xytext=(0, 5), textcoords="offset points", ha='center', va='bottom', fontsize=12, fontweight='bold') ax.set_xticks(x) ax.set_xticklabels(pretty_labels, fontsize=13, fontweight='bold') ax.set_ylim(0.5, 4.5) ax.set_yticks([1, 2, 3, 4]) ax.set_yticklabels(['Strongly Disagree', 'Disagree', 'Agree', 'Strongly Agree'], fontsize=12) ax.set_ylabel('Likert Score', fontsize=13, fontweight='bold') ax.set_title('Identifier 7: Pre vs Post Likert Scores', fontsize=15, fontweight='bold') ax.legend(fontsize=12) ax.grid(axis='y', linestyle='--', alpha=0.7) plt.tight_layout() return fig # Gradio interface demo = gr.Interface( fn=plot_likert_scores, inputs=gr.File(label="Upload your Excel file (.xlsx)"), outputs=gr.Plot(label="Likert Plot for Identifier 7"), title="Pre vs Post Likert Plot (Identifier 7)", description="Upload your survey Excel file. This tool compares pre/post Likert scores for Confidence, Feedback, and Enjoyment for respondent 7.", allow_flagging='never' ) if __name__ == "__main__": demo.launch()