Private
Public Access
1
0

Make plotintervals more rational (dataprep) - continue at cum_flex

This commit is contained in:
sanderroosendaal
2016-11-01 17:43:46 +01:00
parent a892188e85
commit 01ea80c539
3 changed files with 1424 additions and 1467 deletions

File diff suppressed because it is too large Load Diff

142
rowers/dataprep.py Normal file
View File

@@ -0,0 +1,142 @@
from rowers.models import Workout, User, Rower
from rowingdata import rowingdata as rrdata
from rowingdata import rower as rrower
from rowingdata import main as rmain
from pandas import DataFrame,Series
import pandas as pd
import numpy as np
from scipy.signal import savgol_filter
import datetime
def niceformat(values):
out = []
for v in values:
formattedv = strfdelta(v)
out.append(formattedv)
return out
def strfdelta(tdelta):
try:
minutes,seconds = divmod(tdelta.seconds,60)
tenths = int(tdelta.microseconds/1e5)
except AttributeError:
minutes,seconds = divmod(tdelta.view(np.int64),60e9)
seconds,rest = divmod(seconds,1e9)
tenths = int(rest/1e8)
res = "{minutes:0>2}:{seconds:0>2}.{tenths:0>1}".format(
minutes=minutes,
seconds=seconds,
tenths=tenths,
)
return res
def nicepaceformat(values):
out = []
for v in values:
formattedv = strfdelta(v)
out.append(formattedv)
return out
def timedeltaconv(x):
dt = datetime.timedelta(seconds=x)
return dt
def rdata(file,rower=rrower()):
try:
res = rrdata(file,rower=rower)
except IOError:
res = 0
return res
def getrowdata(id=0):
# check if valid ID exists (workout exists)
row = Workout.objects.get(id=id)
f1 = row.csvfilename
# get user
r = row.user
u = r.user
rr = rrower(hrmax=r.max,hrut2=r.ut2,
hrut1=r.ut1,hrat=r.at,
hrtr=r.tr,hran=r.an)
rowdata = rdata(f1,rower=rr)
return rowdata,row
def dataprep(rowdatadf):
rowdatadf.set_index([range(len(rowdatadf))],inplace=True)
t = rowdatadf.ix[:,'TimeStamp (sec)']
t = pd.Series(t-rowdatadf.ix[0,'TimeStamp (sec)'])
row_index = rowdatadf.ix[:,' Stroke500mPace (sec/500m)'] > 3000
rowdatadf.loc[row_index,' Stroke500mPace (sec/500m)'] = 3000.
p = rowdatadf.ix[:,' Stroke500mPace (sec/500m)']
hr = rowdatadf.ix[:,' HRCur (bpm)']
spm = rowdatadf.ix[:,' Cadence (stokes/min)']
cumdist = rowdatadf.ix[:,'cum_dist']
power = rowdatadf.ix[:,' Power (watts)']
averageforce = rowdatadf.ix[:,' AverageDriveForce (lbs)']
drivelength = rowdatadf.ix[:,' DriveLength (meters)']
peakforce = rowdatadf.ix[:,' PeakDriveForce (lbs)']
f = rowdatadf['TimeStamp (sec)'].diff().mean()
windowsize = 2*(int(10./(f)))+1
if windowsize <= 3:
windowsize = 5
if windowsize > 3:
spm = savgol_filter(spm,windowsize,3)
hr = savgol_filter(hr,windowsize,3)
drivelength = savgol_filter(drivelength,windowsize,3)
t2 = t.fillna(method='ffill').apply(lambda x: timedeltaconv(x))
p2 = p.fillna(method='ffill').apply(lambda x: timedeltaconv(x))
drivespeed = drivelength/rowdatadf[' DriveTime (ms)']*1.0e3
driveenergy = drivelength*averageforce*4.44822
distance = rowdatadf.ix[:,'cum_dist']
data = DataFrame(
dict(
time = t2,
hr = hr,
pace = p2,
spm = spm,
cumdist = cumdist,
ftime = niceformat(t2),
fpace = nicepaceformat(p2),
driveenergy=driveenergy,
power=power,
averageforce=averageforce,
drivelength=drivelength,
peakforce=peakforce,
distance=distance,
drivespeed=drivespeed
)
)
return data

View File

@@ -4,8 +4,6 @@ from rowingdata import main as rmain
from rowingdata import cumcpdata,histodata
from rowingdata import rowingdata as rrdata
from rowingdata import TCXParser,RowProParser,ErgDataParser
from rowingdata import painsledDesktopParser,speedcoachParser,ErgStickParser
from bokeh.plotting import figure, ColumnDataSource, Figure,curdoc
from bokeh.models import CustomJS,Slider
@@ -45,14 +43,8 @@ from scipy.signal import savgol_filter
import stravastuff
def rdata(file,rower=rrower()):
try:
res = rrdata(file,rower=rower)
except IOError:
res = 0
return res
from rowers.dataprep import rdata
import rowers.dataprep as dataprep
def tailwind(bearing,vwind,winddir):
""" Calculates head-on head/tailwind in direction of rowing
@@ -68,42 +60,9 @@ def tailwind(bearing,vwind,winddir):
return vtail
def niceformat(values):
out = []
for v in values:
formattedv = strfdelta(v)
out.append(formattedv)
return out
def strfdelta(tdelta):
minutes,seconds = divmod(tdelta.seconds,60)
tenths = int(tdelta.microseconds/1e5)
res = "{minutes:0>2}:{seconds:0>2}.{tenths:0>1}".format(
minutes=minutes,
seconds=seconds,
tenths=tenths,
)
return res
def nicepaceformat(values):
out = []
for v in values:
formattedv = strfdelta(v)
out.append(formattedv)
return out
def timedeltaconv(x):
# if x<=0 or x>1e9:
# x=0
dt = datetime.timedelta(seconds=x)
return dt
from rowers.dataprep import nicepaceformat,niceformat
from rowers.dataprep import timedeltaconv
def interactive_histoall(theworkouts):
@@ -535,66 +494,14 @@ def interactive_chart(id=0,promember=0):
else:
TOOLS = 'pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair'
# check if valid ID exists (workout exists)
row = Workout.objects.get(id=id)
# g = GraphImage.objects.filter(workout=row).order_by("-creationdatetime")
f1 = row.csvfilename
# create interactive plot
# get user
# u = User.objects.get(id=row.user.id)
r = row.user
u = r.user
rr = rrower(hrmax=r.max,hrut2=r.ut2,
hrut1=r.ut1,hrat=r.at,
hrtr=r.tr,hran=r.an)
rowdata = rdata(f1,rower=rr)
rowdata,row = dataprep.getrowdata(id=id)
if rowdata == 0:
return "","CSV Data File Not Found"
t = rowdata.df.ix[:,'TimeStamp (sec)']
t = pd.Series(t-rowdata.df.ix[0,'TimeStamp (sec)'])
row_index = rowdata.df.ix[:,' Stroke500mPace (sec/500m)'] > 3000
rowdata.df.loc[row_index,' Stroke500mPace (sec/500m)'] = 3000.
p = rowdata.df.ix[:,' Stroke500mPace (sec/500m)']
hr = rowdata.df.ix[:,' HRCur (bpm)']
spm = rowdata.df.ix[:,' Cadence (stokes/min)']
cumdist = rowdata.df.ix[:,'cum_dist']
f = rowdata.df['TimeStamp (sec)'].diff().mean()
windowsize = 2*(int(10./(f)))+1
if windowsize <= 3:
windowsize = 5
if windowsize > 3:
spm = savgol_filter(spm,windowsize,3)
t2 = t.fillna(method='ffill').apply(lambda x: timedeltaconv(x))
p2 = p.fillna(method='ffill').apply(lambda x: timedeltaconv(x))
datadf = dataprep.dataprep(rowdata.df)
source = ColumnDataSource(
data = dict(
x=t2,
y=hr,
y2=p2,
tf = niceformat(t2),
pace = nicepaceformat(p2),
heartrate = hr,
spm=spm,
spmc=np.rint(10*spm)/10.,
cumdist=cumdist,
)
datadf
)
@@ -605,7 +512,7 @@ def interactive_chart(id=0,promember=0):
toolbar_sticky=False,
tools=TOOLS)
plot.line('x','y2',source=source,legend="Pace")
plot.line('time','pace',source=source,legend="Pace")
plot.title.text = row.name
plot.title.text_font_size=value("1.0em")
plot.xaxis.axis_label = "Time"
@@ -636,17 +543,17 @@ def interactive_chart(id=0,promember=0):
hover.tooltips = OrderedDict([
('Time','@tf'),
('Pace','@pace'),
('HR','@heartrate'),
('SPM','@spmc{1.1}'),
('Time','@ftime'),
('Pace','@fpace'),
('HR','@hr'),
('SPM','@spm{1.1}'),
('Distance','@cumdist{1.1}'),
])
hover.mode = 'mouse'
plot.extra_y_ranges = {"hr": Range1d(start=100,end=200)}
plot.line('x','y',source=source,color="red",
plot.line('time','hr',source=source,color="red",
y_range_name="hr", legend="Heart Rate")
plot.add_layout(LinearAxis(y_range_name="hr",axis_label="HR"),'right')
@@ -672,19 +579,6 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
thedata = pd.concat(therows)
csvcolumns = {
'time': 'TimeStamp (sec)',
'distance': 'cum_dist',
'hr': ' HRCur (bpm)',
'spm': ' Cadence (stokes/min)',
'pace': ' Stroke500mPace (sec/500m)',
'power': ' Power (watts)',
'averageforce': ' AverageDriveForce (lbs)',
'drivelength': ' DriveLength (meters)',
'peakforce': ' PeakDriveForce (lbs)',
'driveenergy': 'driveenergy',
'drivespeed': 'drivespeed',
}
axlabels = {
'time': 'Time',
@@ -729,47 +623,29 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
}
thedata['driveenergy'] = thedata[' DriveLength (meters)']*thedata[' AverageDriveForce (lbs)']*4.44822
datadf = dataprep.dataprep(thedata)
# thedata['driveenergy'] = thedata[' DriveLength (meters)']*thedata[' AverageDriveForce (lbs)']*4.44822
# throw out zeros from dataframe
thedata = thedata[thedata[csvcolumns[yparam1]] > 0]
thedata = thedata[thedata[csvcolumns[xparam]] > 0]
#thedata = thedata[thedata[csvcolumns[yparam1]] > 0]
#thedata = thedata[thedata[csvcolumns[xparam]] > 0]
datadf = datadf[datadf[yparam1] > 0]
datadf = datadf[datadf[xparam] > 0]
if yparam2 != 'None':
thedata = thedata[thedata[csvcolumns[yparam2]] > 0]
#thedata = thedata[thedata[csvcolumns[yparam2]] > 0]
datadf = datadf[thedata[yparam2] > 0]
# check if dataframe not empty
if thedata.empty:
if datadf.empty:
return ['','<p>No non-zero data in selection</p>','','']
spm = thedata.ix[:,csvcolumns['spm']]
x1 = datadf.ix[:,xparam]
f = thedata['TimeStamp (sec)'].diff().mean()
if not np.isnan(f):
windowsize = 2*(int(10./(f)))+1
else:
windowsize = 5
if windowsize <= 3:
windowsize = 5
if windowsize > 3:
spm = savgol_filter(spm,windowsize,3)
thedata[' Cadence (stokes/min)'] = spm
drivelength = thedata[' DriveLength (meters)']
if windowsize > 3:
drivelength = savgol_filter(drivelength,windowsize,3)
thedata[' DriveLength (meters)'] = drivelength
thedata['drivespeed'] = drivelength/thedata[' DriveTime (ms)']*1.0e3
x1 = thedata.ix[:,csvcolumns[xparam]]
y1 = thedata.ix[:,csvcolumns[yparam1]]
y1 = datadf.ix[:,yparam1]
if yparam2 != 'None':
y2 = thedata.ix[:,csvcolumns[yparam2]]
y2 = datadf.ix[:,yparam2]
else:
y2 = y1
@@ -811,18 +687,14 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
y1 = y1.fillna(method='ffill').apply(lambda x: timedeltaconv(x))
time = thedata.ix[:,csvcolumns['time']]
hr = thedata.ix[:,csvcolumns['hr']]
if windowsize > 3:
hr = savgol_filter(hr,windowsize,3)
pace = thedata.ix[:,csvcolumns['pace']]
distance = thedata.ix[:,csvcolumns['distance']]
power = thedata.ix[:,csvcolumns['power']]
time = datadf.ix[:,'time']
hr = datadf.ix[:,'hr']
pace = datadf.ix[:,'pace']
distance = datadf.ix[:,'distance']
power = datadf.ix[:,'power']
ftime = datadf.ix[:,'ftime']
fpace = datadf.ix[:,'fpace']
spm = datadf.ix[:,'spm']
# Add hover to this comma-separated string and see what changes
@@ -853,34 +725,25 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
x1=x1,
y1=y1,
y2=y2,
time=niceformat(
time.fillna(method='ffill').apply(lambda x: timedeltaconv(x))
),
pace=nicepaceformat(
pace.fillna(method='ffill').apply(lambda x: timedeltaconv(x))
),
time=ftime,
pace=fpace,
hr = hr,
spm = spm,
spmc=np.rint(10*spm)/10.,
distance=distance,
power=power,
)
)
source2 = ColumnDataSource(
data = dict(
x1=x1,
y1=y1,
y2=y2,
time=niceformat(
time.fillna(method='ffill').apply(lambda x: timedeltaconv(x))
),
pace=nicepaceformat(
pace.fillna(method='ffill').apply(lambda x: timedeltaconv(x))
),
time=ftime,
pace=fpace,
hr = hr,
spm = spm,
spmc=np.rint(10*spm)/10.,
distance=distance,
power=power,
)
@@ -947,7 +810,7 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
('Time','@time'),
('Pace','@pace'),
('HR','@hr'),
('SPM','@spmc{1.1}'),
('SPM','@spm{1.1}'),
('Power','@power{int}'),
])
@@ -966,7 +829,6 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
var time1 = data['time']
var pace1 = data['pace']
var hr1 = data['hr']
var spmc1 = data['spmc']
var distance1 = data['distance']
var power1 = data['power']
@@ -985,7 +847,6 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
data2['time'] = []
data2['pace'] = []
data2['hr'] = []
data2['spmc'] = []
data2['distance'] = []
data2['power'] = []
data2['x1mean'] = []
@@ -1005,7 +866,6 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
data2['time'].push(time1[i])
data2['pace'].push(pace1[i])
data2['hr'].push(hr1[i])
data2['spmc'].push(spmc1[i])
data2['distance'].push(distance1[i])
data2['power'].push(power1[i])
@@ -1129,20 +989,7 @@ def interactive_flex_chart2(id=0,promember=0,
'drivespeed':4,
}
# check if valid ID exists (workout exists)
row = Workout.objects.get(id=id)
# g = GraphImage.objects.filter(workout=row).order_by("-creationdatetime")
f1 = row.csvfilename
r = row.user
u = r.user
rr = rrower(hrmax=r.max,hrut2=r.ut2,
hrut1=r.ut1,hrat=r.at,
hrtr=r.tr,hran=r.an)
rowdata = rdata(f1,rower=rr)
rowdata,row = dataprep.getrowdata(id=id)
if rowdata == 0:
return "","CSV Data File Not Found"
@@ -1521,22 +1368,7 @@ def interactive_flex_chart2(id=0,promember=0,
def interactive_bar_chart(id=0,promember=0):
# check if valid ID exists (workout exists)
row = Workout.objects.get(id=id)
f1 = row.csvfilename
# create interactive plot
plot = Figure(plot_width=400,plot_height=300)
# get user
# u = User.objects.get(id=row.user.id)
r = row.user
u = r.user
rr = rrower(hrmax=r.max,hrut2=r.ut2,
hrut1=r.ut1,hrat=r.at,
hrtr=r.tr,hran=r.an)
rowdata = rdata(f1,rower=rr)
rowdata,row = dataprep.getrowdata(id=id)
if rowdata == 0:
return "","CSV Data File Not Found"
@@ -1716,18 +1548,11 @@ def interactive_comparison_chart(id1=0,id2=0,xparam='distance',yparam='spm',
# check if valid ID exists (workout exists)
row1 = Workout.objects.get(id=id1)
row2 = Workout.objects.get(id=id2)
f1 = row1.csvfilename
f2 = row2.csvfilename
rowdata1 = rdata(f1)
rowdata1,row1 = dataprep.getrowdata(id=id1)
rowdata2,row2 = dataprep.getrowdata(id=id1)
if rowdata1 == 0:
return "","CSV Data File Not Found"
rowdata2 = rdata(f2)
if rowdata2 == 0:
return "","CSV Data File Not Found"
@@ -1924,17 +1749,7 @@ def interactive_comparison_chart(id1=0,id2=0,xparam='distance',yparam='spm',
def interactive_otw_advanced_pace_chart(id=0,promember=0):
# check if valid ID exists (workout exists)
row = Workout.objects.get(id=id)
f1 = row.csvfilename
# get user
# u = User.objects.get(id=row.user.id)
r = row.user
u = r.user
rowdata = rdata(f1)
rowdata,row = dataprep.getrowdata(id=id)
if rowdata == 0:
return "","CSV Data File Not Found"