move jawbone into my. from private provider
This commit is contained in:
parent
809281d5d7
commit
cd804091c3
4 changed files with 22 additions and 14 deletions
146
my/jawbone/plots.py
Executable file
146
my/jawbone/plots.py
Executable file
|
@ -0,0 +1,146 @@
|
|||
#!/usr/bin/env python3
|
||||
# TODO
|
||||
from pathlib import Path
|
||||
# from kython.plotting import *
|
||||
from csv import DictReader
|
||||
from itertools import islice
|
||||
|
||||
from typing import Dict, Any, NamedTuple, Dict
|
||||
|
||||
# sleep = []
|
||||
# with open('2017.csv', 'r') as fo:
|
||||
# reader = DictReader(fo)
|
||||
# for line in islice(reader, 0, 10):
|
||||
# sleep
|
||||
# print(line)
|
||||
|
||||
import numpy as np # type: ignore
|
||||
import matplotlib.pyplot as plt # type: ignore
|
||||
from numpy import genfromtxt # type: ignore
|
||||
import matplotlib.pylab as pylab # type: ignore
|
||||
|
||||
pylab.rcParams['figure.figsize'] = (32.0, 24.0)
|
||||
pylab.rcParams['font.size'] = 10
|
||||
|
||||
jawboneDataFeatures = Path(__file__).parent / 'features.csv' # Data File Path
|
||||
featureDesc: Dict[str, str] = {}
|
||||
for x in genfromtxt(jawboneDataFeatures, dtype='unicode', delimiter=','):
|
||||
featureDesc[x[0]] = x[1]
|
||||
|
||||
def _safe_float(s: str):
|
||||
if len(s) == 0:
|
||||
return None
|
||||
return float(s)
|
||||
|
||||
def _safe_int(s: str):
|
||||
if len(s) == 0:
|
||||
return None
|
||||
return int(float(s)) # TODO meh
|
||||
|
||||
def _safe_mins(s: float):
|
||||
if s is None:
|
||||
return None
|
||||
return s / 60
|
||||
|
||||
class SleepData(NamedTuple):
|
||||
date: str
|
||||
asleep_time: float
|
||||
awake_time: float
|
||||
total: float
|
||||
awake: float # 'awake for' from app, time awake duing sleep (seconds)
|
||||
awakenings: int
|
||||
light: float # 'light sleep' from app (seconds)
|
||||
deep: float # 'deep sleep' from app (sec)
|
||||
quality: float # ???
|
||||
|
||||
@classmethod
|
||||
def from_jawbone_dict(cls, d: Dict[str, Any]):
|
||||
return cls(
|
||||
date=d['DATE'],
|
||||
asleep_time=_safe_mins(_safe_float(d['s_asleep_time'])),
|
||||
awake_time=_safe_mins(_safe_float(d['s_awake_time'])),
|
||||
total=_safe_mins(_safe_float(d['s_duration'])),
|
||||
light=_safe_mins(_safe_float(d['s_light'])),
|
||||
deep =_safe_mins(_safe_float(d['s_deep'])),
|
||||
awake=_safe_mins(_safe_float(d['s_awake'])),
|
||||
awakenings=_safe_int(d['s_awakenings']),
|
||||
quality=_safe_float(d['s_quality']),
|
||||
)
|
||||
|
||||
def is_bad(self):
|
||||
return self.deep is None and self.light is None
|
||||
|
||||
# @property
|
||||
# def total(self) -> float:
|
||||
# return self.light + self.deep
|
||||
|
||||
|
||||
|
||||
def iter_useful(data_file: str):
|
||||
from csv import DictReader
|
||||
with open(data_file) as fo:
|
||||
reader = DictReader(fo)
|
||||
for d in reader:
|
||||
dt = SleepData.from_jawbone_dict(d)
|
||||
if not dt.is_bad():
|
||||
yield dt
|
||||
|
||||
# TODO <<< hmm. these files do contain deep and light sleep??
|
||||
# also steps stats??
|
||||
from my_configuration import paths
|
||||
|
||||
p = paths.jawbone.export_dir / 'old_csv'
|
||||
# TODO with_my?
|
||||
files = [
|
||||
p / "2015.csv",
|
||||
p / "2016.csv",
|
||||
p / "2017.csv",
|
||||
]
|
||||
|
||||
from kython import concat, parse_date
|
||||
useful = concat(*(list(iter_useful(str(f))) for f in files))
|
||||
|
||||
# for u in useful:
|
||||
# print(f"{u.total} {u.asleep_time} {u.awake_time}")
|
||||
# # pprint(u.total)
|
||||
# pprint(u)
|
||||
# pprint("---")
|
||||
|
||||
dates = [parse_date(u.date, yearfirst=True, dayfirst=False) for u in useful]
|
||||
# TODO filter outliers?
|
||||
|
||||
# TODO don't need this anymore? it's gonna be in dashboards package
|
||||
from kython.plotting import plot_timestamped
|
||||
for attr, lims, mavg, fig in [ # type: ignore
|
||||
('light', (0, 400), 5, None),
|
||||
('deep', (0, 600), 5, None),
|
||||
('total', (200, 600), 5, None),
|
||||
('awake_time', (0, 1200), None, 1),
|
||||
('asleep_time', (-100, 1000), None, 1),
|
||||
# ('awakenings', (0, 5)),
|
||||
]:
|
||||
dates_wkd = [d for d in dates if d.weekday() < 5]
|
||||
dates_wke = [d for d in dates if d.weekday() >= 5]
|
||||
for dts, dn in [
|
||||
(dates, 'total'),
|
||||
(dates_wkd, 'weekday'),
|
||||
(dates_wke, 'weekend')
|
||||
]:
|
||||
mavgs = []
|
||||
if mavg is not None:
|
||||
mavgs.append((mavg, 'green'))
|
||||
fig = plot_timestamped(
|
||||
dts, # type: ignore
|
||||
[getattr(u, attr) for u in useful],
|
||||
marker='.',
|
||||
ratio=(16, 4),
|
||||
mavgs=mavgs,
|
||||
ylimits=lims,
|
||||
ytick_size=60,
|
||||
# figure=1,
|
||||
)
|
||||
plt.savefig(f'{attr}_{dn}.png')
|
||||
|
||||
# TODO use proper names?
|
||||
# plt.savefig('res.png')
|
||||
# fig.show()
|
Loading…
Add table
Add a link
Reference in a new issue