Spaces:
Running
Running
File size: 6,378 Bytes
addc7dc 33ecdbc addc7dc 33ecdbc ff310de 33ecdbc ff310de 33ecdbc ff310de 33ecdbc ff310de 33ecdbc |
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 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
import gradio as gr
import numpy as np
import pandas as pd
def load_health_data():
# Load the CSV file into a pandas DataFrame
df = pd.read_csv('healthdata.csv', header=2)
# Replace null values with empty strings
df = df.replace({np.nan: "", None: ""})
return df
def get_device_data(device):
df = load_health_data()
# Common columns for all devices
base_cols = ['Day', 'Date', 'Day of Week']
if device == "AppleWatch + AutoSleep":
# Get columns with AS suffix + base columns
device_cols = base_cols + [col for col in df.columns if 'AS' in col]
elif device == "8sleep Pod 4 Ultra":
# Get columns with 8S suffix + base columns
device_cols = base_cols + [col for col in df.columns if '8S' in col]
elif device == "Oura":
# Get columns with OU suffix + base columns
device_cols = base_cols + [col for col in df.columns if 'OU' in col]
elif device == "Whoop":
# Get columns with WH suffix + base columns
device_cols = base_cols + [col for col in df.columns if 'WH' in col]
else:
return df
# Add the Average and Notes columns if they exist
if 'Average' in df.columns:
device_cols.append('Average')
if 'Notes' in df.columns:
device_cols.append('Notes')
return df[device_cols]
def get_color_for_metric(val, metric_name):
"""Return a color based on the metric type and value"""
try:
val = float(val)
except (ValueError, TypeError):
return ""
# Define thresholds for different metrics
if "BPM" in metric_name:
# Lower is better for BPM
if val <= 50:
return "background-color: rgba(0, 180, 0, 0.3)" # Green
elif val >= 54:
return "background-color: rgba(180, 0, 0, 0.3)" # Red
else:
return "background-color: rgba(180, 180, 180, 0.1)" # Light gray for middle range
elif "Score" in metric_name:
# Higher is better for Score
if val >= 85:
return "background-color: rgba(0, 180, 0, 0.3)" # Dark green
elif val >= 75:
return "background-color: rgba(0, 140, 0, 0.2)" # Medium green
elif val <= 70:
return "background-color: rgba(180, 0, 0, 0.3)" # Red
else:
return "background-color: rgba(180, 180, 180, 0.1)" # Light gray
elif "HRV" in metric_name:
# Higher is better for HRV
if val >= 80:
return "background-color: rgba(0, 180, 0, 0.3)" # Dark green
elif val <= 55:
return "background-color: rgba(180, 0, 0, 0.3)" # Red
else:
return "background-color: rgba(180, 180, 180, 0.1)" # Light gray
elif "Deep" in metric_name:
# Higher might be better for Deep sleep
if val >= 1.0:
return "background-color: rgba(0, 180, 0, 0.3)" # Green
elif val <= 0.2:
return "background-color: rgba(180, 0, 0, 0.3)" # Red
else:
return "background-color: rgba(180, 180, 180, 0.1)" # Light gray
elif "REM" in metric_name:
# Higher might be better for REM
if val >= 1.5:
return "background-color: rgba(0, 180, 0, 0.3)" # Green
elif val <= 0.8:
return "background-color: rgba(180, 0, 0, 0.3)" # Red
else:
return "background-color: rgba(180, 180, 180, 0.1)" # Light gray
elif "Light" in metric_name:
# Medium values might be ideal for Light sleep
if 5.0 <= val <= 6.0:
return "background-color: rgba(0, 180, 0, 0.3)" # Green
elif val >= 6.3 or val <= 4.5:
return "background-color: rgba(180, 0, 0, 0.3)" # Red
else:
return "background-color: rgba(180, 180, 180, 0.1)" # Light gray
return "" # Default no color
def prepare_data_with_styling(df):
data = df.values.tolist()
headers = list(df.columns)
# Create styling
styling = []
for row in data:
row_styling = []
for i, val in enumerate(row):
if headers[i] in ['Day', 'Date', 'Day of Week', 'Notes'] or val == "":
row_styling.append(["", ""])
else:
style = get_color_for_metric(val, headers[i])
row_styling.append(["", f"width: var(--cell-width-3); left: auto; {style}"])
styling.append(row_styling)
return {
"data": data,
"headers": headers,
"metadata": {
"styling": styling
}
}
column_widths = [70,150,150,150,150]
# Create the Gradio application using Blocks
with gr.Blocks(title="@Andrej Karpathy's Sleep Data") as demo:
gr.Markdown("# @karpathy's Sleep Data")
gr.Markdown("This app displays Andrej Karpathy's sleep tracking data from multiple devices. See his [blog post](https://karpathy.bearblog.dev/finding-the-best-sleep-tracker/) to learn more about the data and the process of finding the best sleep tracker.")
with gr.Tabs():
with gr.TabItem("AppleWatch + AutoSleep"):
df = get_device_data("AppleWatch + AutoSleep")
gr.Dataframe(prepare_data_with_styling(df), show_search="search", column_widths=column_widths, show_copy_button=True, pinned_columns=1)
with gr.TabItem("8sleep Pod 4 Ultra"):
df = get_device_data("8sleep Pod 4 Ultra")
gr.Dataframe(prepare_data_with_styling(df), show_search="search", column_widths=column_widths, show_copy_button=True, pinned_columns=1)
with gr.TabItem("Oura"):
df = get_device_data("Oura")
gr.Dataframe(prepare_data_with_styling(df), show_search="search", column_widths=column_widths, show_copy_button=True, pinned_columns=1)
with gr.TabItem("Whoop"):
df = get_device_data("Whoop")
gr.Dataframe(prepare_data_with_styling(df), show_search="search", column_widths=column_widths, show_copy_button=True, pinned_columns=1)
with gr.TabItem("All Data"):
df = load_health_data()
gr.Dataframe(prepare_data_with_styling(df), show_search="search", column_widths=column_widths, show_copy_button=True, pinned_columns=1)
if __name__ == "__main__":
demo.launch()
|