Garminが提供するスマートウォッチはGPS機能を搭載したアスリート向けモデルというイメージがありますが、アスリートでなくても日々の健康管理に気を使い最大限のパフォーマンスを生み出したいビジネスマンにも魅力的なスマートウォッチが多くあります。
Garminのスマートウォッチは心拍数データを分析することにより一日のストレスを追跡したり、後どれくらいアクティブに動けるかのエネルギー残量のモニタリングを行ったり、呼吸数と睡眠の確認、そして燃焼カロリー数などがわかります。
私はGarminのスマートウォッチの中の「Instinctシリーズ」を用いて日々のサウナ活動、通称「サ活」を記録しており、そのデータをプログラミング言語の「Python」で解析する方法をこの記事にまとめました。今回はそのデータである「 fitファイル 」を処理して心拍データをグラフ化するコードを紹介します。
こちらの記事ではさらにPythonを使っての可視化を深堀しておりますので興味がある人はこちらもご覧ください。
Garmin Connectから fitファイル をダウンロード
Garmin Connectでは様々なアクティビティや健康状態が可視化されて確認することができます。これらのデータをPythonで自分でも読み取り、自分の健康やアクティビティを可視化するための方法を紹介します。
しかしGarmin Connectの各種ページを見てみてもcsvファイルでエクスポートできるデータは限られており、「心拍数」などのファイルは含まれておりません。そのデータは以下の設定中の「オリジナルをエクスポート」から得られる「 fitファイル 」に含まれております。
この「fitファイル」のFITは、”Flexible and Interoperable Data Transfer (FIT)”を意味しております。FITに関する詳細はこちらのページから確認できます。
fitファイルを開く「python-fitparse」と「fitdecode」
Pythonでこの「fitファイル」を扱うためには、それ用のライブラリをインストールする必要があります。現在調べた中では「python-fitparse」と「fitdecode」の2種類がありGoogleでの検索ヒット数/GitHubでのお気に入り数は以下の通りでした。
- python-fitparse 2,230件/Star:560
- fitdecode 900件/Star:70
今回は実際に両方使ってみて、「fitdecode」をベースにしたこちらのサイトでの処理を参考に処理したもので自分の望むデータを取り出せましたので、実際のコードを紹介します。
「 fitdecode 」で心拍数を可視化 コード紹介
fitdecode は 先ほど紹介した python-fitparse をベースに作成されており、より新しくfitparseでできなかった処理を可能としたモジュールです。
ちなみに本記事で紹介するのは以下の環境での動作確認済みコードです。
◆ Mac OS
◆ Python 3
◆ JupyterLab
fitファイルのデコード, dataframe作成
まずはfitdecodeをインストールします。
1 |
!pip install fitdecode |
その後動作確認のため、fitdecode に記載のサンプルファイルを実行します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# fitdecodeのGitHubオリジナル import fitdecode with fitdecode.FitReader('xxxxxx_ACTIVITY.fit') as fit: for frame in fit: # The yielded frame object is of one of the following types: # * fitdecode.FitHeader (FIT_FRAME_HEADER) # * fitdecode.FitDefinitionMessage (FIT_FRAME_DEFINITION) # * fitdecode.FitDataMessage (FIT_FRAME_DATA) # * fitdecode.FitCRC (FIT_FRAME_CRC) if frame.frame_type == fitdecode.FIT_FRAME_DATA: # Here, frame is a FitDataMessage object. # A FitDataMessage object contains decoded values that # are directly usable in your script logic. print(frame.name) |
この処理は、fitファイルをdecodeしてframe
として[FitDataMessage object]を格納します。この[FitDataMessage object]中に解析可能なデータが保存されています。その中からframe_typeがFIT_FRAME_DATA
を抽出しその名前を表示させております。
以下のような実行結果が表示されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
file_id file_creator event device_info device_info device_info device_info device_info unknown_22 unknown_141 device_settings user_profile unknown_79 sport unknown_13 zones_target record |
今回抽出したい「心拍数データ」は上記のframeの中のrecord
の中に存在しております。このrecordからデータを取り出してpandas dataframeで表示するのが以下のコードです。
このコードでは8行目にif frame.name == 'record':
でrecord
のデータを取り出しております。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import fitdecode datas = [] with fitdecode.FitReader('./00_Garmin file/8014951130_ACTIVITY.fit') as fit: for frame in fit: if isinstance(frame, fitdecode.FitDataMessage): if frame.name == 'record': data = {} for field in frame.fields: data[field.name] = field.value data[field.name + '_units'] = field.units datas.append(data) # dataframeで表示 df = pd.DataFrame(datas) df |
実行すると私の場合は20列のdataframeを取り出すことができました。各列名を確認してみるとこの中のheart_rate
が目的のデータです。
1 2 3 4 5 6 7 8 9 10 |
df.columns # 実行結果 # Index(['timestamp', 'timestamp_units', 'distance', 'distance_units', 'enhanced_altitude', 'enhanced_altitude_units', 'unknown_88', 'unknown_88_units', 'heart_rate', 'heart_rate_units', 'cadence', 'cadence_units', 'temperature', 'temperature_units', 'fractional_cadence', 'fractional_cadence_units', 'unknown_136', 'unknown_136_units', 'unknown_87', 'unknown_87_units'], dtype='object') |
心拍数データの可視化
dataframeから心拍数データheart_rate
をpythonのmatplotlibを用いて可視化します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# 時系列折れ線グラフ %matplotlib inline import matplotlib.pyplot as plt import pandas as pd import matplotlib.dates as mdates fig = plt.figure() ax = fig.add_subplot(1,1,1) # 縦軸:数値 y = df["heart_rate"] ax.plot(y) # Add some text for labels, title and custom x-axis tick labels, etc. ax.set_xlabel('time [s]', fontsize=14) ax.set_ylabel('Heart rate [bpm]', fontsize=14) ax.set_title('heart rate from Garmin fit file', fontsize=18) ax.grid() # グラフの表示 plt.show() |
実行結果は以下の通りで、これで心拍データをpython上で可視化することができました。
この後にpython中で色々と処理を加えることで「サウナ・水風呂・移動中・ととのい」の各フェーズでの心拍数を可視化することもできます。この表示方法についてはまた別の記事で紹介できればと思います。
最後に
今回は以下の項目をPythonのコード付きで紹介しました。
- Garmin Connectから fitファイル をダウンロード
- Python「 fitdecode 」でfitファイルをdecode
- Python matplotlib で心拍数を可視化
サウナでの「ととのい」体験はストレスの高い日々を生き抜くための癒しをもたらしてくれますが、どのように過ごせばよりととのいやすくなるか、を自分探すために今回のようにGarminでログをとったり実際にグラフを可視化してみることで気づきが得られるかと思います。
次回の記事ではさらに踏み込んだグラフの可視化について紹介しております。
コメント
[…] サウナの心拍データをPythonで解析 ~ fitファイル 処理編 ~Garminが提供するスマートウォッチはGPS機能を搭載したアスリート向けモデルというイメージがありますが、アスリートでなくても […]