iPhoneの「ヘルスケア」アプリを開き,右上の自分のアイコンをタップし,「すべてのヘルスケアデータを書き出す」をタップする。共有方法としては,最近はAirDropでMacに送っている。
以前にこのページで紹介していたのは「"ファイル"に保存」でiCloud Driveに保存する方法であった。iPhoneがWi-Fiでインターネットに接続していなければ同期しないかもしれないので注意。MacのFinderでiCloud Driveにアクセスし,「書き出したデータ.zip」というファイルをカレントディレクトリに持ってきて(あるいは以下のZipファイル名としてフルパスで '/Users/自分の名前/Library/Mobile Documents/com~apple~CloudDocs/書き出したデータ.zip'
を指定して),次のスクリプトを実行する。
読む方法は,まずzipを展開してから
import xml.etree.ElementTree as ET
tree = ET.parse("apple_health_export/export.xml")
としてもよいが,展開せずに済ませるには次のようにする:
#! /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(x=df.index, y=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)
(あれれ,2020年秋からちょっと高心拍数が増えているぞ?)[ 追記: に watchOS 7.0 が来ている。このバージョンから睡眠の判断ができるようになったなどの変化があり,それによって測定値が変化した可能性が Changes in Apple Health Export という記事で論じられている。]
もしプログラム上で日時を制限したいなら,例えば次のようにすればよい:
df = df[df.index >= pd.Timestamp("2021-01-01 00:00:00")]
ほかにも,例えば HKQuantityTypeIdentifierHeartRateVariabilitySDNN
というタイプには心拍変動がミリ秒単位で入る。これらHKで始まる長い名前はHealthKit関連のものである。
上と同様にして睡眠開始時刻・終了時刻が取得できる:
for x in root.findall('Record'):
if (x.get('type') == 'HKCategoryTypeIdentifierSleepAnalysis' and
x.get('value') == 'HKCategoryValueSleepAnalysisAsleep'):
print(x.get('startDate')[:19], x.get('endDate')[:19], sep=',')
こちらは夜間はApple Watchをつけていないことが多いので十分なデータが取れていない。