Details for quantified-flu-fitbit.ipynb

Published by gedankenstuecke


A notebook that visualizes your resting heart rate before & after flu/cold events


Tags & Data Sources

quantifiedflu Fitbit Connection


Please log in to comment.

Last updated 3 weeks, 5 days ago

Heart rate & body temperature variations when sick

A Fitbit allows you to measure vital signs during sleep such as resting heart rate. Here we will use this data to see if there are any patterns that emerge before falling sick. This is part of the #quantifiedflu project that came out of one of the Open Humans community calls!

If you haven't connected your Fitbit account to Open Humans this notebook will fail. Go here to connect your account.

There are three parameters you can easily change for this notebook in the cell below:

  • The first one, sick_dates, is a list of dates on which you fell sick. Enter dates as YYYY-MM-DD format, e.g. 2019-11-29 for the 29th of November 2019. You can provide as many sick dates as you remember as a comma-separated ist.
  • The second one, weeks_before_sick, decides how many weeks before the actual falling sick you want to have shown in your graphs. By default it is 3.
  • The third one, weeks_after_sick, decides how many weeks after the event you want to see in your graph. By default it's 1.
In [1]:
sick_dates = ['2018-12-31']
weeks_before_sick = 3
weeks_after_sick = 1

The code below will now get your data from Open Humans and create a table with all the data points in the date ranges you specified above:

In [2]:
from ohapi import api
import os
import requests
import tempfile
import arrow

user_details = api.exchange_oauth2_member(os.environ.get('OH_ACCESS_TOKEN'))
for i in user_details['data']:
    if i['basename'] == 'fitbit-data.json' and i['source'] == 'direct-sharing-102':
        fitbit_data = requests.get(i['download_url']).json()

sd_dict = {}

for sd in sick_dates:
    sdd = arrow.get(sd)
    period_start = sdd.shift(weeks=weeks_before_sick*-1).format('YYYY-MM-DD')
    period_end = sdd.shift(weeks=weeks_after_sick).format('YYYY-MM-DD')
    sd_dict[sd] = {'period_start': period_start, 'period_end': period_end}

period = []
timestamp = []
heart_rate = []

for p in sd_dict.keys():
    for month in fitbit_data['heart']:
        for entry in fitbit_data['heart'][month]['activities-heart']:
            sdate = arrow.get(entry['dateTime'])
            if (sdate >= arrow.get(sd_dict[p]['period_start'])) and (sdate <= arrow.get(sd_dict[p]['period_end'])):

import pandas as pd
dataframe = pd.DataFrame(
    data = {
        'period': period,
        'timestamp': timestamp,
        'heart_rate': heart_rate,

Visualizing heart rate changes around the sick dates:

Heart rate changes

Each sick-period will be it's own little sub-graph, with the date of falling sick being highlighted by a vertical, red bar. Each sick-period shows the resting heart rate changes, as well as a fitted line for the data.

In [3]:
%load_ext rpy2.ipython
In [4]:
%%R -i dataframe -w 15 -h 4 --units in -r 200

ggplot(subset(dataframe,dataframe$heart_rate > 0), aes(x=as.Date(timestamp),y=heart_rate,color=period)) + 
    geom_vline(aes(xintercept=as.Date(period)),alpha=0.6,color='red') + 
    geom_point(alpha=1) + 
    geom_smooth(method='loess') + theme_minimal() + scale_x_date('timestamp') + 
    facet_grid(. ~ period, scales='free')

Can you observe clear patterns? Is there something unexpected in your data? You can publish your own notebook after running it via the menu above: Click File -> Share Notebook -> Upload to Open Humans to share it with others.