Apple Watch(未完)

ヘルスケアデータの心拍数を読む

iPhoneの「ヘルスケア」アプリを開き,右上の自分のアイコンをタップし,「すべてのヘルスケアデータを書き出す」をタップする。共有方法は何でもいいが,簡単なのは「"ファイル"に保存」で,そのままiCloud Driveに保存する。iPhoneがWi-Fiでインターネットに接続していなければ同期しないかもしれないので注意。

MacのFinderでiCloud Driveにアクセスし,「書き出したデータ.zip」というファイルをカレントディレクトリに持ってきて(あるいは以下のZipファイル名としてフルパスで '/Users/自分の名前/Library/Mobile Documents/com~apple~CloudDocs/書き出したデータ.zip' を指定して),次のスクリプトを走らせる:

#! /usr/bin/env python3

from zipfile import ZipFile
import xml.etree.ElementTree as ET

with ZipFile('書き出したデータ.zip') as zipdata, \
     zipdata.open('apple_health_export/export.xml') as f:
    tree = ET.parse(f)

root = tree.getroot()
for x in root.findall('Record'):
    if x.get('type') == 'HKQuantityTypeIdentifierHeartRate':
        y = x.find('MetadataEntry')
        print(x.get('startDate')[:19], x.get('value'), y.get('value'), sep=',')

標準出力に日時・心拍数・そのときの運動状態(0,1,2)のCSVが出力されるので,適当にリダイレクトしてファイルに収める。あとはFitbitと同様にグラフを描けばよい。CSVからグラフを描く簡単なプログラムを挙げておく:

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import seaborn as sns
import pandas as pd

df = pd.read_csv('healthdata.csv', header=None,
                 names=['datetime', 'heartrate', 'motion'],
                 index_col='datetime', parse_dates=['datetime'])

locator = mdates.AutoDateLocator()
formatter = mdates.ConciseDateFormatter(locator)
pd.plotting.register_matplotlib_converters()
cm = plt.get_cmap('jet')

plt.figure(figsize=[10,5])
ax = sns.scatterplot(df.index, df['heartrate'], hue=df['heartrate'],
                     style=df['motion'], palette=cm, hue_norm=(60,150))
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(formatter)
plt.xlim(min(df.index), max(df.index))
plt.ylim(50, 170)

もしプログラム上で日時を制限したいなら,例えば次のようにすればよい:

df = df[df.index >= pd.Timestamp("2019-09-30 00:00:00")]

ほかにも,例えば HKQuantityTypeIdentifierHeartRateVariabilitySDNN というタイプには心拍変動がミリ秒単位で入る。これらHKで始まる長い名前はHealthKit関連のものである。