MIRA / app.py
stevafernandes's picture
Create app.py
d1bec89 verified
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()