はじめに
fitbitとは、心拍数、歩数や睡眠をトラッキングするために腕に着用するタイプのスマートウォッチです。ここでは、Fitbit APIを使って一週間分の睡眠データを取得してmatplotlibでまとめて表示する方法を解説します。
手順
APIの登録など
その1を参照してください。
fitbit-pythonのインストールなど
その2を参照してください。
モジュールのインポートなど
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import fitbit
from ast import literal_eval
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import numpy as np
import seaborn as sns
import datetime as dt
plt.style.use('bmh')
バージョン
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version
import matplotlib
print(matplotlib.__version__)
3.4.2
print(fitbit.__version__)
0.3.1
print(pd.__version__)
1.2.4
print(np.__version__)
1.20.3
print(sns.__version__)
0.11.1
APIの認証
CLIENT_ID, tokenなどを定義
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CLIENT_ID = "####"
CLIENT_SECRET = "#################"
TOKEN_FILE = "token.txt"
tokens = open(TOKEN_FILE).read()
token_dict = literal_eval(tokens)
access_token = token_dict['access_token']
refresh_token = token_dict['refresh_token']
その1で取得したCLIENT_IDとCLIENT_SECRETとtoken.txtをここで使います。token.txtは実行ファイルと同じ場所に置いておきます。
認証
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def updateToken(token):
f = open(TOKEN_FILE, 'w')
f.write(str(token))
f.close()
return
client = fitbit.Fitbit(CLIENT_ID, CLIENT_SECRET,
access_token = access_token, refresh_token = refresh_token, refresh_cb = updateToken)
fitbit.Fitbit()
により、認証を行います。updateToken
関数はtokenの更新用の関数でrefresh_cb
に updateToken
とすることでtokenが期限切れの際に随時更新してくれるようになります。
1週間分のデータの取得
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
DATE = "2021-05-27"
DATE = dt.datetime.strptime(DATE, '%Y-%m-%d')
#1週間分のデータの取得
data_1w=[]
for i in range(7):
DATE_ = DATE+ dt.timedelta(days=i)
data_sleep = client.sleep(DATE_)
data_sleep_ = data_sleep["sleep"][0]["levels"]["data"]
data_sleep_ = pd.DataFrame.from_dict(data_sleep_)
data_sleep_.index=pd.to_datetime(data_sleep_["dateTime"])
data_1w.append(data_sleep_)
DATE+ dt.timedelta(days=i)で日付を一日単位でずらしながら、client.sleep(DATE_)
により睡眠データが入手します。取得したデータはpd.DataFrame.from_dictによりデータフレームにし、リストに格納していきます。
リストの最初のデータフレームは以下のようになっています。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
data_1w[0]
"""
dateTime level seconds
dateTime
2021-05-26 22:43:00 2021-05-26T22:43:00.000 wake 300
2021-05-26 22:48:00 2021-05-26T22:48:00.000 light 1110
2021-05-26 23:06:30 2021-05-26T23:06:30.000 deep 390
2021-05-26 23:13:00 2021-05-26T23:13:00.000 light 2520
2021-05-26 23:55:00 2021-05-26T23:55:00.000 deep 420
2021-05-27 00:02:00 2021-05-27T00:02:00.000 light 4200
2021-05-27 01:12:00 2021-05-27T01:12:00.000 rem 270
2021-05-27 01:16:30 2021-05-27T01:16:30.000 light 1050
2021-05-27 01:34:00 2021-05-27T01:34:00.000 wake 360
2021-05-27 01:40:00 2021-05-27T01:40:00.000 light 2880
2021-05-27 02:28:00 2021-05-27T02:28:00.000 rem 270
2021-05-27 02:32:30 2021-05-27T02:32:30.000 light 750
2021-05-27 02:45:00 2021-05-27T02:45:00.000 rem 1560
2021-05-27 03:11:00 2021-05-27T03:11:00.000 light 210
2021-05-27 03:14:30 2021-05-27T03:14:30.000 wake 330
2021-05-27 03:20:00 2021-05-27T03:20:00.000 light 3780
2021-05-27 04:23:00 2021-05-27T04:23:00.000 deep 420
2021-05-27 04:30:00 2021-05-27T04:30:00.000 light 2340
2021-05-27 05:09:00 2021-05-27T05:09:00.000 rem 360
2021-05-27 05:15:00 2021-05-27T05:15:00.000 light 870
2021-05-27 05:29:30 2021-05-27T05:29:30.000 wake 660
2021-05-27 05:40:30 2021-05-27T05:40:30.000 light 270
2021-05-27 05:45:00 2021-05-27T05:45:00.000 wake 300
2021-05-27 05:50:00 2021-05-27T05:50:00.000 light 330
"""
睡眠のレベルを数値化
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#レベルを数値化
for i in range(7):
data_1w[i].loc[data_1w[i]['level']=="wake","level_int"]= 3
data_1w[i].loc[data_1w[i]['level']=="rem","level_int"]= 2
data_1w[i].loc[data_1w[i]['level']=="light","level_int"]= 1
data_1w[i].loc[data_1w[i]['level']=="deep","level_int"]= 0
data_1w[i] = data_1w[i].astype({'level_int': 'int'})
睡眠のレベルデータを数値データに変換します。
表示範囲の設定
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#x軸表示範囲
xlim0=np.array([dt.datetime(2021,5,26,22,0,0),dt.datetime(2021,5,27,8,0,0)])
xlim1 = xlim0+dt.timedelta(days=1)
xlim2 = xlim1+dt.timedelta(days=1)
xlim3 = xlim2+dt.timedelta(days=1)
xlim4 = xlim3+dt.timedelta(days=1)
xlim5 = xlim4+dt.timedelta(days=1)
xlim6 = xlim5+dt.timedelta(days=1)
xlims = [xlim0,xlim1,xlim2,xlim3,xlim4,xlim5,xlim6]
それぞれの日付に対して22:00から8:00までデータを表示するために表示範囲のデータをdatetime形式で作成しておきます。
1週間分の睡眠データの表示
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fig,ax=plt.subplots(7,1,dpi=100,figsize=(6,10))
ax= ax.ravel()
[ax[i].step(data_1w[i].index.values, data_1w[i]["level_int"].values,"-",where='post',lw=2) for i in range(7)]
[ax[i].text(0.05, 1.1, xlims[i][1].strftime('%m/%d'), horizontalalignment='center',verticalalignment='center', transform=ax[i].transAxes) for i in range(7)]
[ax[i].set_xlim(xlims[i]) for i in range(7)]
for a in ax:
locator = mdates.AutoDateLocator()
formatter = mdates.DateFormatter("%H:%M")
a.xaxis.set_major_locator(locator)
a.xaxis.set_major_formatter(formatter)
a.set(yticks=np.arange(4),yticklabels=["Deep","Light","Rem","Wake"])
ax[6].set(xlabel="Time")
ax[3].set(ylabel="Sleep level")
i=2
ax[i].text(0.05, 1.1, xlims[i][1].strftime('%m/%d'), horizontalalignment='center',verticalalignment='center', transform=ax[i].transAxes, color="b")
i=3
ax[i].text(0.05, 1.1, xlims[i][1].strftime('%m/%d'), horizontalalignment='center',verticalalignment='center', transform=ax[i].transAxes, color="r")
plt.tight_layout()
plt.savefig("sleep_1w.png",dpi=130)
plt.show()
ax[i].step()
でそれぞれの日の睡眠データを順次プロットしていきます。ax[i].text()
でそれぞれのプロットの日付を左上に表示します。ax[i].set_xlim()
でx軸の表示範囲を調整します。
全てリスト内包で処理しています。
x軸の表示形式については、mdates.DateFormatter(“%H:%M”)により時間と分の形式で表示できるようになります。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
i=2
ax[i].text(0.05, 1.1, xlims[i][1].strftime('%m/%d'), horizontalalignment='center',verticalalignment='center', transform=ax[i].transAxes, color="b")
i=3
ax[i].text(0.05, 1.1, xlims[i][1].strftime('%m/%d'), horizontalalignment='center',verticalalignment='center', transform=ax[i].transAxes, color="r")
土曜を青、日曜の日付を赤にしています。
コードをダウンロード(.pyファイル) コードをダウンロード(.ipynbファイル)
コメント