NK Tools Force Curve
This commit is contained in:
@@ -125,7 +125,177 @@ def tailwind(bearing,vwind,winddir):
|
||||
from rowers.dataprep import nicepaceformat,niceformat
|
||||
from rowers.dataprep import timedeltaconv
|
||||
|
||||
def interactive_forcecurve(theworkouts):
|
||||
TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,resize,crosshair'
|
||||
|
||||
ids = [int(w.id) for w in theworkouts]
|
||||
|
||||
boattype = theworkouts[0].boattype
|
||||
|
||||
columns = ['catch','slip','wash','finish','averageforce',
|
||||
'peakforceangle','peakforce','spm','distance']
|
||||
|
||||
rowdata = dataprep.getsmallrowdata_db(columns,ids=ids)
|
||||
|
||||
catchav = rowdata['catch'].mean()
|
||||
finishav = rowdata['finish'].mean()
|
||||
washav = rowdata['wash'].mean()
|
||||
slipav = rowdata['slip'].mean()
|
||||
peakforceav = rowdata['peakforce'].mean()
|
||||
averageforceav = rowdata['averageforce'].mean()
|
||||
peakforceangleav = rowdata['peakforceangle'].mean()
|
||||
|
||||
x = [catchav,
|
||||
catchav+slipav,
|
||||
peakforceangleav,
|
||||
finishav-washav,
|
||||
finishav]
|
||||
|
||||
thresholdforce = 100 if 'x' in boattype else 200
|
||||
thresholdforce /= 4.45 # N to lbs
|
||||
y = [0,thresholdforce,
|
||||
peakforceav,
|
||||
thresholdforce,0]
|
||||
|
||||
source = ColumnDataSource(
|
||||
data = dict(
|
||||
x = x,
|
||||
y = y,
|
||||
))
|
||||
|
||||
|
||||
source2 = ColumnDataSource(
|
||||
rowdata
|
||||
)
|
||||
|
||||
plot = Figure(tools=TOOLS,
|
||||
toolbar_sticky=False)
|
||||
|
||||
avf = Span(location=averageforceav,dimension='width',line_color='blue',
|
||||
line_dash=[6,6],line_width=2)
|
||||
|
||||
plot.line('x','y',source=source,color="red")
|
||||
|
||||
plot.add_layout(avf)
|
||||
|
||||
plot.xaxis.axis_label = "Angle"
|
||||
plot.yaxis.axis_label = "Force (lbs)"
|
||||
plot.title.text = theworkouts[0].name
|
||||
plot.title.text_font_size=value("1.0em")
|
||||
|
||||
yrange1 = Range1d(start=0,end=200)
|
||||
plot.y_range = yrange1
|
||||
|
||||
xrange1 = Range1d(start=yaxmaxima['catch'],end=yaxmaxima['finish'])
|
||||
plot.x_range = xrange1
|
||||
|
||||
callback = CustomJS(args = dict(
|
||||
source=source,
|
||||
source2=source2,
|
||||
avf=avf,
|
||||
), code="""
|
||||
var data = source.data
|
||||
var data2 = source2.data
|
||||
|
||||
var x = data['x']
|
||||
var y = data['y']
|
||||
var spm1 = data2['spm']
|
||||
var distance1 = data2['distance']
|
||||
|
||||
var thresholdforce = y[1]
|
||||
|
||||
var c = source2.data['catch']
|
||||
var finish = data2['finish']
|
||||
var slip = data2['slip']
|
||||
var wash = data2['wash']
|
||||
var peakforceangle = data2['peakforceangle']
|
||||
var peakforce = data2['peakforce']
|
||||
var averageforce = data2['averageforce']
|
||||
|
||||
var minspm = minspm.value
|
||||
var maxspm = maxspm.value
|
||||
var mindist = mindist.value
|
||||
var maxdist = maxdist.value
|
||||
|
||||
var catchav = 0
|
||||
var finishav = 0
|
||||
var slipav = 0
|
||||
var washav = 0
|
||||
var peakforceangleav = 0
|
||||
var averageforceav = 0
|
||||
var peakforceav = 0
|
||||
var count = 0
|
||||
|
||||
|
||||
for (i=0; i<c.length; i++) {
|
||||
if (spm1[i]>=minspm && spm1[i]<=maxspm) {
|
||||
if (distance1[i]>=mindist && distance1[i]<=maxdist) {
|
||||
catchav += c[i]
|
||||
finishav += finish[i]
|
||||
slipav += slip[i]
|
||||
washav += wash[i]
|
||||
peakforceangleav += peakforceangle[i]
|
||||
averageforceav += averageforce[i]
|
||||
peakforceav += peakforce[i]
|
||||
count += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
catchav /= count
|
||||
finishav /= count
|
||||
slipav /= count
|
||||
washav /= count
|
||||
peakforceangleav /= count
|
||||
peakforceav /= count
|
||||
averageforceav /= count
|
||||
|
||||
data['x'] = [catchav,catchav+slipav,peakforceangleav,finishav-washav,finishav]
|
||||
data['y'] = [0,thresholdforce,peakforceav,thresholdforce,0]
|
||||
|
||||
avf.location = averageforceav
|
||||
|
||||
source.trigger('change');
|
||||
""")
|
||||
|
||||
slider_spm_min = Slider(start=15.0, end=55,value=15.0, step=.1,
|
||||
title="Min SPM",callback=callback)
|
||||
callback.args["minspm"] = slider_spm_min
|
||||
|
||||
|
||||
slider_spm_max = Slider(start=15.0, end=55,value=55.0, step=.1,
|
||||
title="Max SPM",callback=callback)
|
||||
callback.args["maxspm"] = slider_spm_max
|
||||
|
||||
distmax = 100+100*int(rowdata['distance'].max()/100.)
|
||||
|
||||
slider_dist_min = Slider(start=0,end=distmax,value=0,step=1,
|
||||
title="Min Distance",callback=callback)
|
||||
callback.args["mindist"] = slider_dist_min
|
||||
|
||||
slider_dist_max = Slider(start=0,end=distmax,value=distmax,
|
||||
step=1,
|
||||
title="Max Distance",callback=callback)
|
||||
callback.args["maxdist"] = slider_dist_max
|
||||
|
||||
layout = layoutrow([layoutcolumn([slider_spm_min,
|
||||
slider_spm_max,
|
||||
slider_dist_min,
|
||||
slider_dist_max,
|
||||
],
|
||||
),
|
||||
plot])
|
||||
|
||||
script, div = components(layout)
|
||||
js_resources = INLINE.render_js()
|
||||
css_resources = INLINE.render_css()
|
||||
|
||||
|
||||
|
||||
return [script,div,js_resources,css_resources]
|
||||
|
||||
|
||||
|
||||
def interactive_histoall(theworkouts):
|
||||
TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,resize,crosshair'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user