停止猜测你的健康:使用 Streamlit 和 ECharts 构建统一的 Quantified Self 仪表盘

发布: (2026年2月9日 GMT+8 09:00)
6 分钟阅读
原文: Dev.to

Source: Dev.to

Beck_Moulton

Source:

介绍

您是否厌倦了为了查看睡眠对血糖水平的影响而在五个不同的应用之间切换?欢迎来到 Quantified Self 的世界。在这个可穿戴设备泛滥的时代,真正的挑战不是收集数据,而是 数据工程 与综合。

在本教程中,我们将使用 StreamlitEChartsPandas 构建一个统一的健康仪表盘。我们将通过对齐来自 Oura Ring、Apple Watch 和连续血糖监测仪(CGM)的时间序列数据,来解决“异构数据问题”。完成本指南后,您将拥有一个专业级的 Quantified Self 可视化 工具,能够将原始健康指标转化为可操作的洞察。

架构概览:从原始日志到洞察

处理健康数据很棘手,因为每个设备的采样频率各不相同。你的连续血糖监测仪(CGM)可能每 5 分钟发送一次数据,而 Oura Ring 则每天只提供一次“睡眠评分”。

graph TD
    A[Oura Ring API] -->|Daily Metrics| B[(SQL Database)]
    C[Apple Watch / HealthKit] -->|Heart Rate/Steps| B
    D[Continuous Glucose Monitor] -->|5‑min Glucose| B
    B --> E{Data Alignment Layer}
    E -->|Pandas Resampling| F[Unified DataFrame]
    F --> G[Streamlit Frontend]
    G --> H[ECharts Interactive Viz]

前置条件

确保已安装以下 技术栈

  • Python 3.9+
  • Streamlit – UI 框架
  • Pandas – 数据处理
  • SQLAlchemy – 数据库接口
  • streamlit‑echarts – 交互式图表
pip install streamlit pandas sqlalchemy streamlit-echarts

第一步:数据层(SQLAlchemy)

首先,我们从集中存储中提取数据。此示例假设您已将健康数据同步到 SQLite(或 PostgreSQL)数据库中。

import pandas as pd
from sqlalchemy import create_engine

# 数据库连接
engine = create_engine('sqlite:///health_data.db')

def load_health_data():
    # 从不同来源获取指标
    cgm_df = pd.read_sql("SELECT timestamp, glucose_value FROM cgm_logs", engine)
    activity_df = pd.read_sql(
        "SELECT date, sleep_score, readiness_score FROM oura_metrics",
        engine,
    )

    # 确保 datetime 类型
    cgm_df["timestamp"] = pd.to_datetime(cgm_df["timestamp"])
    activity_df["date"] = pd.to_datetime(activity_df["date"])

    return cgm_df, activity_df

第2步:对齐魔法(Pandas)

这是进行 数据工程 的环节。我们使用 resamplemerge_asof 将 5 分钟的 CGM 数据与每日 Oura 评分对齐,从而创建一个连续的时间轴。

def align_data(cgm, activity):
    # 将 CGM 重采样为每小时的平均值,以降低噪声
    cgm_hourly = (
        cgm.set_index("timestamp")
        .resample("H")
        .mean()
        .reset_index()
    )

    # 将每日活动数据合并回每小时的时间轴
    # 左连接保持高频时间轴完整
    merged = pd.merge_asof(
        cgm_hourly.sort_values("timestamp"),
        activity.sort_values("date"),
        left_on="timestamp",
        right_on="date",
        direction="backward",
    )
    return merged

第3步:使用 ECharts 可视化

标准图表很无聊。对于健康数据,我们需要 交互性。ECharts 让我们可以放大特定的睡眠质量差的夜晚,精准查看血糖的变化。

from streamlit_echarts import st_echarts

def render_health_chart(df):
    options = {
        "title": {"text": "Glucose vs. Sleep Correlation"},
        "tooltip": {"trigger": "axis"},
        "legend": {"data": ["Glucose", "Sleep Score"]},
        "xAxis": {
            "type": "category",
            "data": df["timestamp"]
            .dt.strftime("%m-%d %H:%M")
            .tolist(),
        },
        "yAxis": [
            {"type": "value", "name": "Glucose (mg/dL)"},
            {"type": "value", "name": "Score", "max": 100},
        ],
        "series": [
            {
                "name": "Glucose",
                "type": "line",
                "data": df["glucose_value"].tolist(),
                "smooth": True,
                "itemStyle": {"color": "#ff4d4f"},
            },
            {
                "name": "Sleep Score",
                "type": "bar",
                "yAxisIndex": 1,
                "data": df["sleep_score"].tolist(),
                "itemStyle": {"color": "#1890ff", "opacity": 0.3},
            },
        ],
        "dataZoom": [{"type": "slider"}],  # Add zoom control
    }
    st_echarts(options=options, height="500px")

“官方”扩展方式

本地仪表盘是一个很好的起点,但要将周末项目转变为可投入生产的健康科技平台,需要:

  • 实时同步
  • 符合 HIPAA 标准的数据处理
  • 强大且可扩展的管道

想了解高级架构模式以及大规模时间序列数据的生产就绪示例,请访问 WellAlly Blog 的技术深度解析。内容涵盖生物特征数据安全、高性能建模等主题。

综合示例

以下是一个最简的 Streamlit 应用,将所有内容整合在一起。

import streamlit as st

# Load and align data
cgm_df, activity_df = load_health_data()
merged_df = align_data(cgm_df, activity_df)

st.title("Quantified Self Health Dashboard")
st.subheader("Glucose vs. Sleep Score")

render_health_chart(merged_df)

运行应用:

streamlit run your_app.py

扩展示例

import streamlit as st

def main():
    st.set_page_config(page_title="Quantified Self Dashboard", layout="wide")
    st.title("📊 My Health Data Universe")

    st.sidebar.header("Filters")
    date_range = st.sidebar.date_input("Select Date Range")

    # Load and process
    cgm, activity = load_health_data()
    aligned_df = align_data(cgm, activity)

    # UI Layout
    col1, col2 = st.columns(2)
    with col1:
        st.metric("Avg Glucose", f"{aligned_df['glucose_value'].mean():.1f} mg/dL")
    with col2:
        st.metric("Avg Sleep Score", f"{aligned_df['sleep_score'].mean():.0f}")

    render_health_chart(aligned_df)

if __name__ == "__main__":
    main()

结论

通过统一您的数据,您不再只看孤立的数字,而是开始看到 模式。也许您的血糖在睡眠不足 2 小时 REM 睡眠的夜晚会飙升?现在您拥有数据来证明这一点!

接下来做什么?

  • 使用 Scikit‑learn 添加 异常检测,标记高血糖事件。
  • 集成 Apple Health XML 导出,以获得更细致的粒度。
  • 查看 WellAlly Blog,获取更多健康科技工程的灵感。

祝玩得开心!

这篇文章对您有帮助吗?在下方留言,告诉我们您最常追踪的健康指标是什么! 👇

0 浏览
Back to Blog

相关文章

阅读更多 »

Power BI 中的模式与数据建模

引言 数据建模,顾名思义,包含对数据的重构以及从已清洗和结构化的数据中创建有洞察力的可视化。在 Power BI…