Make plotintervals more rational (dataprep) - continue at cum_flex
This commit is contained in:
File diff suppressed because it is too large
Load Diff
142
rowers/dataprep.py
Normal file
142
rowers/dataprep.py
Normal 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
|
||||
@@ -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"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user