fitbit_sleep_analysis.ipynb
Analysis of sleep data collected by Fitbit.
import pandas as pd
import json
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import urllib
import requests
import os
import tempfile
from datetime import datetime
from ohapi import api
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 = requests.get(i['download_url']).json()
'''
data = requests.get('https://www.openhumans.org/api/public/project/102/datafiles/').json()
for i in data['results']:
if i['id'] == 9135000:
fitbit = requests.get(i['download_url']).json()
'''
DateTime = []
year = '2018'
def GetData(obj,year,key):
name = key.split('-')[-1]
name = []
for day in fitbit[obj][year][key]:
name.append(day['value'])
return name
for day in fitbit['minutes-to-sleep'][year]['sleep-minutesToFallAsleep']:
DateTime.append(datetime.strptime(day['dateTime'],'%Y-%m-%d'))
sleepData = pd.DataFrame(
data = {
'minutesToFallAsleep': GetData('minutes-to-sleep',year,'sleep-minutesToFallAsleep'),
'minutesAfterWakeup': GetData('sleep-minutes-after-wakeup',year,'sleep-minutesAfterWakeup'),
'startTime': GetData('sleep-start-time',year,'sleep-startTime'),
'minutesAwake': GetData('awake-minutes',year,'sleep-minutesAwake'),
'timeInBed': GetData('time-in-bed',year,'sleep-timeInBed'),
'awakeningsCount': GetData('sleep-awakenings',year,'sleep-awakeningsCount'),
'sleepEfficiency': GetData('sleep-efficiency',year,'sleep-efficiency'),
'minutesAsleep':GetData('sleep-minutes',year,'sleep-minutesAsleep')
}
)
DateTime = pd.DataFrame(DateTime)
sleepData = pd.concat([DateTime, sleepData], axis=1)
sleepData.rename(columns={sleepData.columns[0]: 'DateTime'}, inplace=True)
sleepData = pd.DataFrame(sleepData.set_index('DateTime', drop= False))
col = ['minutesToFallAsleep','minutesAfterWakeup','timeInBed','awakeningsCount','minutesAsleep','sleepEfficiency']
sleepData[col] = sleepData[col].mask(sleepData[col].applymap(str).eq('0'))
import matplotlib.dates as mdates
sleepData['timeInBed'] = sleepData['timeInBed'].astype(float)
sleepData['hourInBed'] = sleepData['timeInBed']/60
sleepDesc = pd.DataFrame(sleepData['hourInBed'].describe())
sleepDesc
avgSleepHours = round(sleepDesc['hourInBed']['mean'],2)
summary = 'Averaging a sleep of {} hours with a standardized deviation of {} hours'.format(avgSleepHours, round(sleepDesc['hourInBed']['std'],2))
fig, ax = plt.subplots(figsize = (20,6))
plt.hist(sleepData['hourInBed'], bins = 8, range = (3, 10), color="navy")
plt.xlim(3, 10)
plt.xticks(range(3, 10))
plt.axvline(avgSleepHours, color="orangered", linestyle='--')
plt.xlabel('Hours in Bed')
plt.ylabel('Count');
plt.title('Figure 1. Bar chart of Hours in Bed', fontsize=15)
bbox_props1 = dict(boxstyle='round4, pad=0.6', fc='cyan', ec='b', lw=.5)
ax.annotate(summary,
fontsize=12,
fontweight='demi',
xy=(avgSleepHours, 120),
xycoords='data',
xytext=(10, -30),
textcoords='offset points',
arrowprops=dict(arrowstyle="simple",), bbox=bbox_props1)
plt.show()
fig, ax = plt.subplots(figsize = (20,6))
plt.plot(sleepData['DateTime'],sleepData['hourInBed'], linestyle='-',
markersize=10, color='c', label='% Light', linewidth=3.0, alpha=0.9)
plt.ylabel('hourInBed', fontsize=14)
plt.axhline(avgSleepHours, color="orangered", linestyle='--')
plt.title('Figure 2. Line plot of Hours in Bed over {}'.format(year), fontsize = 15)
ax.annotate
ax.xaxis.set_major_locator(mdates.WeekdayLocator(byweekday=6))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%D'))
ax.grid(True)
plt.xticks(rotation=90)
plt.plot()
plt.show()
SleepPattern = sleepData[['minutesAwake','minutesAsleep']].astype(float)
avgSleep = SleepPattern.mean()
fig = plt.figure(figsize = (6,6))
labels=['Awake', 'Asleep']
plt.pie(avgSleep, colors = ['lightskyblue', 'yellowgreen'], autopct='%1.1f%%', labels=labels, textprops=dict(color="w"))
my_circle=plt.Circle( (0,0), 0.7, color='white')
p=plt.gcf()
p.gca().add_artist(my_circle)
plt.title('Figure 3. Average of types of sleep over {}'.format(year), fontsize=15)
plt.legend()
plt.show()
sleepData['Day of week'] = sleepData.index.weekday_name
weekday = ['Monday','Tuesday','Wednesday','Thursday','Friday']
weekend = ['Saturday','Sunday']
sleepData.loc[sleepData['Day of week'].isin(weekday), 'IsWeekday'] = 'Weekday'
sleepData.loc[sleepData['Day of week'].isin(weekend), 'IsWeekday'] = 'Weekend'
sleepData[['minutesAsleep', 'minutesAwake', 'sleepEfficiency']] = sleepData[['minutesAsleep', 'minutesAwake', 'sleepEfficiency']].astype(float)
dayGroupedData = sleepData.groupby(['Day of week']).mean()
dayGroupedData
dayofweek = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
fig = plt.figure(figsize = (10,5))
plt.bar((dayGroupedData.index), dayGroupedData['minutesAwake'], width = 0.4, color='slateblue', label='Minutes Awake')
plt.bar((dayGroupedData.index), dayGroupedData['minutesAsleep'], width = 0.4, color='dodgerblue', label='Minutes Asleep', bottom=dayGroupedData['minutesAwake'])
plt.bar((dayGroupedData.index), dayGroupedData['timeInBed'],width = 0.4, color='lightskyblue', label='Time in Bed', bottom=dayGroupedData['minutesAsleep'])
plt.xticks(np.arange(len(dayofweek)),dayofweek)
plt.title('Figure 4. Wake/Asleep Minutes While in Bed over One Week ', fontsize = 15)
plt.legend(loc='upper right')
plt.show()
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot('Day of week', 'timeInBed', data=sleepData, marker='o', markersize=8, linestyle='None', color ='salmon')
dayGroupedData = dayGroupedData.reset_index(drop=False)
ax.plot(dayGroupedData['timeInBed'],color='r', linewidth=2, label='Average Time in Bed' )
ax.set_ylabel('Time in Bed')
ax.set_xlabel('Day of Week')
plt.title('Figure 5. Run Chart of Minutes in Bed with Average value by Day of the Week', fontsize = 15)
plt.xticks(np.arange(len(dayofweek)),dayofweek)
plt.legend()
plt.show()
sleepData.groupby('IsWeekday').mean()
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(ncols=2,nrows=2,figsize=(10, 10))
xticks = ['Weekday','Weekend']
sleepData.groupby('IsWeekday')['timeInBed'].mean().plot(kind='bar', ax = ax1)
ax1.set_title('Comparison of Time in Bed')
ax1.set_xticklabels(xticks, rotation = 0, ha="right")
ax1.xaxis.label.set_visible(False)
sleepData.groupby('IsWeekday')['minutesAsleep'].mean().plot(kind='bar', ax = ax2)
ax2.set_title('Comparison of Minutes Asleep')
ax2.set_xticklabels(xticks, rotation = 0, ha="right")
ax2.xaxis.label.set_visible(False)
sleepData.groupby('IsWeekday')['minutesAwake'].mean().plot(kind='bar', ax = ax3)
ax3.set_title('Comparison of Minutes Awake')
ax3.set_xticklabels(xticks,rotation = 0, ha="right")
ax3.xaxis.label.set_visible(False)
sleepData.groupby('IsWeekday')['sleepEfficiency'].mean().plot(kind='bar', ax = ax4)
ax4.set_title('Comparison of Sleep Efficiency')
ax4.set_xticklabels(xticks,rotation = 0, ha="right")
ax4.xaxis.label.set_visible(False)
plt.suptitle('Figure 6. Sleep Comparison Between Weekday and Weekend')
plt.show()
sleepData['Month'] = sleepData.index.month
fig, axes = plt.subplots(3, 1, figsize=(12,10), sharex=False)
Month = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
for name, ax in zip(['timeInBed','minutesAsleep', 'minutesAwake','sleepEfficiency'], axes):
sns.boxplot(data=sleepData, x='Month', y=name, ax=ax)
ax.set_ylabel('Minutes')
ax.set_title(name)
ax.set_xticklabels(Month)
if ax != axes[-1]:
ax.set_xlabel('')
plt.suptitle('Figure 7. Sleep Change over Year {}'.format(year))
plt.show()