import streamlit as st import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # Load Data @st.cache_data def load_data(): return pd.read_csv("inbody_with_clusters.csv", parse_dates=["Test Date"]) df = load_data() st.title("📊 InBody 270 Dashboard") st.markdown("Explore trends, clusters, and body composition metrics.") # Sidebar Filters with st.sidebar: st.header("🔎 Filter") id_options = df['ID'].unique() selected_ids = st.multiselect("Select Patient ID(s)", id_options, default=list(id_options[:5])) gender = st.radio("Gender", options=["All", "M", "F"]) bmi_range = st.slider("BMI Range", float(df["27. BMI (Body Mass Index)"].min()), float(df["27. BMI (Body Mass Index)"].max()), (18.5, 35.0)) # Apply Filters filtered = df[df["ID"].isin(selected_ids)] if gender != "All": filtered = filtered[filtered["3. Gender"] == gender] filtered = filtered[(filtered["27. BMI (Body Mass Index)"] >= bmi_range[0]) & (filtered["27. BMI (Body Mass Index)"] <= bmi_range[1])] # Line Chart: Weight/BMI/BFM over time st.subheader("📈 Trends Over Time") metric = st.selectbox("Select a Metric to Plot", ['6. Weight', '27. BMI (Body Mass Index)', '18. BFM (Body Fat Mass)']) fig, ax = plt.subplots(figsize=(10, 5)) sns.lineplot(data=filtered, x="Test Date", y=metric, hue="ID", marker="o", ax=ax) st.pyplot(fig) # Cluster Scatterplot st.subheader("🧬 Body Type Clusters") fig2, ax2 = plt.subplots() sns.scatterplot(data=filtered, x="18. BFM (Body Fat Mass)", y="24. SMM (Skeletal Muscle Mass)", hue="Body Type Cluster", palette="Set1", ax=ax2) st.pyplot(fig2) # Summary Table st.subheader("📋 Latest Measurements (Per Patient)") latest = filtered.sort_values("Test Date").groupby("ID").tail(1) st.dataframe(latest[["ID", "Test Date", "6. Weight", "27. BMI (Body Mass Index)", "18. BFM (Body Fat Mass)", "24. SMM (Skeletal Muscle Mass)", "58. BMR (Basal Metabolic Rate)", "Body Type Cluster"]]) # Download option st.download_button("📥 Download Filtered Data", latest.to_csv(index=False), file_name="filtered_inbody.csv")