Atlas lets you explore your Apple Health data.
Install Atlas using pip
:
pip install atlas-db
Upgrade Atlas using pip
:
pip install atlas-db --upgrade
Uninstall Expanse (old name) using pipx
:
pipx uninstall expanse
Note
Here is a Quarto notebook with example code and SQL queries.
The notebook uses Vega-Altair and Clickhouse (chDB) to explore Apple Health time series data in a .parquet file. The .parquet file was generated by Atlas from an Apple Health export.xml file.
First we create the .parquet
file from the export.xml
file.
atlas parquet export.xml -o ah.parquet
We can explore the data in many ways.
It is just a table/dataframe/parquet file with 5 columns.
But here we'll use clickhouse local
:
clickhouse local
Let's take a look at the table.
DESCRIBE TABLE `ah.parquet`
┌─name────┬─type────────────────────┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─┐
│ type │ Nullable(String) │ │ │ │ │ │
│ start │ Nullable(DateTime64(6)) │ │ │ │ │ │
│ end │ Nullable(DateTime64(6)) │ │ │ │ │ │
│ created │ Nullable(DateTime64(6)) │ │ │ │ │ │
│ value │ Nullable(String) │ │ │ │ │ │
└─────────┴─────────────────────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────┘
What kind of "types" do we have and how many?
SELECT
type,
COUNT(*) AS count
FROM `ah.parquet`
GROUP BY type
ORDER BY count DESC
┌─type───────────────────────────┬──count─┐
│ ActiveEnergyBurned │ 879902 │
│ HeartRate │ 451854 │
│ BasalEnergyBurned │ 289031 │
│ DistanceWalkingRunning │ 260500 │
│ StepCount │ 217384 │
│ PhysicalEffort │ 69747 │
│ AppleExerciseTime │ 61363 │
│ AppleStandTime │ 58309 │
│ EnvironmentalAudioExposure │ 44535 │
│ SleepAnalysis │ 36599 │
│ WalkingStepLength │ 28281 │
│ WalkingSpeed │ 28281 │
│ RespiratoryRate │ 27829 │
│ AppleStandHour │ 25877 │
│ FlightsClimbed │ 22690 │
│ WalkingDoubleSupportPercentage │ 21900 │
│ WalkingAsymmetryPercentage │ 13820 │
│ HeartRateVariabilitySDNN │ 11961 │
│ OxygenSaturation │ 4912 │
│ StairDescentSpeed │ 4718 │
│ StairAscentSpeed │ 4249 │
│ DistanceCycling │ 2890 │
│ TimeInDaylight │ 2403 │
│ HeadphoneAudioExposure │ 2323 │
│ RestingHeartRate │ 1399 │
│ WalkingHeartRateAverage │ 1176 │
│ DistanceSwimming │ 455 │
│ SwimmingStrokeCount │ 455 │
│ AppleSleepingWristTemperature │ 442 │
│ RunningSpeed │ 391 │
│ VO2Max │ 366 │
│ RunningPower │ 173 │
│ DietaryCaffeine │ 171 │
│ AppleWalkingSteadiness │ 138 │
│ SixMinuteWalkTestDistance │ 122 │
│ HeartRateRecoveryOneMinute │ 76 │
│ RunningVerticalOscillation │ 74 │
│ RunningGroundContactTime │ 67 │
│ RunningStrideLength │ 54 │
│ MindfulSession │ 34 │
│ HighHeartRateEvent │ 18 │
│ AudioExposureEvent │ 14 │
│ BodyMass │ 14 │
│ Height │ 5 │
│ Fatigue │ 1 │
│ HKDataTypeSleepDurationGoal │ 1 │
└────────────────────────────────┴────────┘
What's our total step count?
Note
The value
column is type Nullable(String)
so we have to cast toFloat64
to sum up the step values.
SELECT sum(toFloat64(value))
FROM `ah.parquet`
WHERE type = 'StepCount'
┌─sum(toFloat64(value))─┐
│ 30295811 │
└───────────────────────┘
30.295.811 (30.29 million) steps. That's a lot of steps!
- open the Apple Health app on iOS
- tap on your profile picture (or initials) at the top right
- tap on Export All Health Data
- tap on Export
- wait a few seconds to a few minutes (~3min for 10 years of data)
- get the export.zip archive via Airdrop to a Mac (or save to Files)
Note
The export.xml file is in the export.zip archive.
You can expand the export.zip file by double-clicking on it.
This creates a directory named apple_health_export and in it is the export.xml file.
![](https://private-user-images.githubusercontent.com/14825/326262872-c519f3e9-23bf-4f90-909f-30a07b286d57.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzg4MTc3MDEsIm5iZiI6MTczODgxNzQwMSwicGF0aCI6Ii8xNDgyNS8zMjYyNjI4NzItYzUxOWYzZTktMjNiZi00ZjkwLTkwOWYtMzBhMDdiMjg2ZDU3LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMDYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjA2VDA0NTAwMVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTljNjEzMDE4ZGY1YmY5MWVhNzYyOGIzZGZhMjYwOGJjNzcwNDI4MTE4NDcxZmFmNzc0MjAwOTgxMGI1MGZjY2UmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.lyOVp_dskid_2QK4lQPmvgPs7zw5j9jmWQmnKiVbO_A)
![](https://private-user-images.githubusercontent.com/14825/326262881-64409b40-c87f-4bbc-9df8-778d758517fc.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzg4MTc3MDEsIm5iZiI6MTczODgxNzQwMSwicGF0aCI6Ii8xNDgyNS8zMjYyNjI4ODEtNjQ0MDliNDAtYzg3Zi00YmJjLTlkZjgtNzc4ZDc1ODUxN2ZjLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMDYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjA2VDA0NTAwMVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTdkMjM0YmRlODVkMjZlNDk0NjBlMDRjMzhlOWEzNjZiNjc3ZTEwMDY2NzA5YWMwNDEyZTdjZTRiNDI0MzY4MTAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.kFaqKyuFLuw9Tor6K-aXbNWFzL6PqJ11t7LHbimH2jo)
![](https://private-user-images.githubusercontent.com/14825/326262894-0f83fc2d-6728-4023-8074-75517a2af49f.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzg4MTc3MDEsIm5iZiI6MTczODgxNzQwMSwicGF0aCI6Ii8xNDgyNS8zMjYyNjI4OTQtMGY4M2ZjMmQtNjcyOC00MDIzLTgwNzQtNzU1MTdhMmFmNDlmLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMDYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjA2VDA0NTAwMVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTQ3YjgzN2ZlN2RiMTExNTFlMzI2MGFlNjk3M2M4MGFmNjZlZmExNGQwOWQ5NWZkNjRhNmM1YTMwMmJlNWIwNmMmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.uxlDFb4wxeZPGj8y6H_t4Ehn9zXGEXNWJobr4wevGek)
![](https://private-user-images.githubusercontent.com/14825/326262904-35e9d36e-9a7a-46aa-b6da-1420d05b1f20.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzg4MTc3MDEsIm5iZiI6MTczODgxNzQwMSwicGF0aCI6Ii8xNDgyNS8zMjYyNjI5MDQtMzVlOWQzNmUtOWE3YS00NmFhLWI2ZGEtMTQyMGQwNWIxZjIwLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMDYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjA2VDA0NTAwMVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTYxNTE2MDlhODkwNDg1MTUwNzY0NGMxNjFlYzY3Mjk5MGRiOWIwYjEzYjQ0NjFmZTc4Y2ZjYmJhNWFjN2Y3MGEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.RcxqcWv3jcBdwt7fYmzzJArlWCZ5wFJxqgd6R6opLHU)
See: Apple Support on how to export Apple Health and Fitness in XML format
atlas parquet export.xml
- turn export.xml into a simple parquet file