fitbit-intraday-exploration.ipynb
Play around with the data from the Fitbit Intraday integration.
Bla bla
Let's start by loading some Python modules and the data itself
We will start by extracting our heart rate data. It is stored in Open Humans in a per-second resolution. But as this is rather noisy we will try to average it later on onto a per-minute resolution. We will focus on data from a single month.
Define the year-month below by changing the month_of_interest
variable. The default is January 2019:
Now we can load R
and the libraries we will be using. We also pass over our first data set, which includes all the heart-rate data, collected on a per-minute basis.
Let's now create the per-minute average heart-rates and plot them over time.
The graph shows each day as a line graph with the heart rate on the Y-axis. The blue line gives the smoothed curve observed during the day. This is rather noisy data, and there's not much to see except the lower, more uniform heart rate during sleep.
Let's see what we can learn if we sum up the data more and display it as a heat map instead of overlaying all the days. Instead of generating average heart rates per minute, we generate mean heart rates for 15 minutes intervals and plot those:
The X-axis shows the time of day from midnight to midnight, on the Y-axis we see the different days for the month we have chosen. Each cell gives the average heart-rate for that interval, with white cells having a low heart rate and blue cells higher heart rates.
The two black lines show 09:00 in the morning and 18:00 (6pm). Given that I have a ~30 minute walk from home to the office and back, you can easily identify regular work days and when I made my way home/to the office.
Let's now do a heatmap that does the same graph, but sums up our steps for 15 minute intervals along the day. First we extract the corresponding data from Open Humans:
Now we can graph the data:
Let's now have a look at the floors climbed on different days in the same way:
A single weekend outlier makes those hide very well, but there's a slight pattern in the mornings & afternoons: Getting up into the office and climbing back to Downtown Berkeley.
Bla bla
Let's start by loading some Python modules and the data itself
from ohapi import api
import os
import requests
import tempfile
import json
import datetime
import pandas as pd
user_details = api.exchange_oauth2_member(os.environ.get('OH_ACCESS_TOKEN'))
We will start by extracting our heart rate data. It is stored in Open Humans in a per-second resolution. But as this is rather noisy we will try to average it later on onto a per-minute resolution. We will focus on data from a single month.
Define the year-month below by changing the month_of_interest
variable. The default is January 2019:
month_of_interest = '2019-01'
heart_rate = []
time = []
group = []
for i in user_details['data']:
if i['source'] == 'direct-sharing-191' and i['basename'] == 'fitbit-intraday-{}.json'.format(month_of_interest):
data = json.loads(requests.get(i['download_url']).content)
for day in data['activities-heart-intraday']:
for dpoint in day['dataset']:
heart_rate.append(dpoint['value'])
time.append(datetime.datetime.strptime('2019-01-01 '+dpoint['time'][:6]+'00','%Y-%m-%d %H:%M:%S'))
group.append(day['date'])
dataframe = pd.DataFrame(
data = {
'time': time,
'heart_rate': heart_rate,
'date': group
}
)
Now we can load R
and the libraries we will be using. We also pass over our first data set, which includes all the heart-rate data, collected on a per-minute basis.
%load_ext rpy2.ipython
%%R
library(tidyverse)
library(lubridate)
Let's now create the per-minute average heart-rates and plot them over time.
%%R -i dataframe -w 8 -h 4 --units in -r 200
aggdata <-aggregate(dataframe, by=list(dataframe$time,dataframe$date),
FUN=mean, na.rm=TRUE)
aggdata$date <- as.Date(aggdata$Group.2)
aggdata$weekday <- wday(aggdata$date, label=TRUE)
aggdata$weekend <- aggdata$weekday %in% c('Sun','Sat')
aggdata$weekend <- ifelse(aggdata$weekend == TRUE, "weekend", "weekday")
dataframe$weekday <- wday(dataframe$date, label=TRUE)
dataframe$weekend <- dataframe$weekday %in% c('Sun','Sat')
dataframe$weekend <- ifelse(dataframe$weekend == TRUE, "weekend", "weekday")
aggdata_for_smooth <-aggregate(dataframe, by=list(dataframe$time, dataframe$weekend),
FUN=mean, na.rm=TRUE)
aggdata_for_smooth$weekend <- aggdata_for_smooth$Group.2
ggplot(aggdata,aes(aggdata$time, aggdata$heart_rate, group=as.Date(aggdata$Group.2))) +
geom_line(alpha=0.1) +
geom_smooth(data=aggdata_for_smooth,aes(aggdata_for_smooth$Group.1,aggdata_for_smooth$heart_rate,group=NULL), method='loess') +
theme_minimal() + scale_x_datetime('time') + scale_y_continuous('heart rate') + facet_grid(weekend ~ .)