diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py index d697eba6..3e5a8bf9 100644 --- a/rowers/interactiveplots.py +++ b/rowers/interactiveplots.py @@ -405,42 +405,91 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False): try: catchav = rowdata['catch'].mean() + catch25 = rowdata['catch'].quantile(q=0.25) + catch75 = rowdata['catch'].quantile(q=0.75) + catch01 = rowdata['catch'].quantile(q=0.05) + catch99 = rowdata['catch'].quantile(q=0.95) except KeyError: catchav = 0 + catch25 = 0 + catch75 = 0 + catch01 = 0 + catch99 = 0 try: finishav = rowdata['finish'].mean() + finish25 = rowdata['finish'].quantile(q=0.25) + finish75 = rowdata['finish'].quantile(q=0.75) + finish01 = rowdata['finish'].quantile(q=0.05) + finish99 = rowdata['finish'].quantile(q=0.95) except KeyError: finishav = 0 + finish25 = 0 + finish75 = 0 + finish01 = 0 + finish99 = 0 + try: - washav = rowdata['wash'].mean() + washav = (rowdata['finish']-rowdata['wash']).mean() + wash25 = (rowdata['finish']-rowdata['wash']).quantile(q=0.25) + wash75 = (rowdata['finish']-rowdata['wash']).quantile(q=0.75) + wash01 = (rowdata['finish']-rowdata['wash']).quantile(q=0.05) + wash99 = (rowdata['finish']-rowdata['wash']).quantile(q=0.95) except KeyError: washav = 0 + wash25 = 0 + wash75 = 0 + wash01 = 0 + wash99 = 0 try: - slipav = rowdata['slip'].mean() + slipav = (rowdata['slip']+rowdata['catch']).mean() + slip25 = (rowdata['slip']+rowdata['catch']).quantile(q=0.25) + slip75 = (rowdata['slip']+rowdata['catch']).quantile(q=0.75) + slip01 = (rowdata['slip']+rowdata['catch']).quantile(q=0.05) + slip99 = (rowdata['slip']+rowdata['catch']).quantile(q=0.95) except KeyError: slipav = 0 - + slip25 = 0 + slip75 = 0 + slip01 = 0 + slip99 = 0 + try: peakforceav = rowdata['peakforce'].mean() + peakforce25 = rowdata['peakforce'].quantile(q=0.25) + peakforce75 = rowdata['peakforce'].quantile(q=0.75) + peakforce01 = rowdata['peakforce'].quantile(q=0.05) + peakforce99 = rowdata['peakforce'].quantile(q=0.95) except KeyError: peakforceav = 0 + peakforce25 = 0 + peakforce75 = 0 + peakforce01 = 0 + peakforce99 = 0 try: averageforceav = rowdata['averageforce'].mean() except KeyError: averageforceav = 0 - + try: peakforceangleav = rowdata['peakforceangle'].mean() + peakforceangle25 = rowdata['peakforceangle'].quantile(q=0.25) + peakforceangle75 = rowdata['peakforceangle'].quantile(q=0.75) + peakforceangle01 = rowdata['peakforceangle'].quantile(q=0.05) + peakforceangle99 = rowdata['peakforceangle'].quantile(q=0.95) except KeyError: peakforceangleav = 0 - + peakforceangle25 = 0 + peakforceangle75 = 0 + peakforceangle01 = 0 + peakforceangle99 = 0 + x = [catchav, - catchav+slipav, + slipav, peakforceangleav, - finishav-washav, + washav, finishav] thresholdforce = 100 if 'x' in boattype else 200 @@ -449,12 +498,70 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False): peakforceav, thresholdforce,0] + x2575 = [catch25, + slip25, + peakforceangleav, + wash75, + finish75, + finish25, + wash25, + peakforceangleav, + slip75] + + y2575 = [0, + thresholdforce, + peakforce75, + thresholdforce, + 0, + 0, + thresholdforce, + peakforce25, + 0] + + + + x0199 = [catch01, + slip01, + peakforceangleav, + wash99, + finish99, + finish01, + wash01, + peakforceangleav, + slip99] + + y0199 = [0, + thresholdforce, + peakforce99, + thresholdforce, + 0, + 0, + thresholdforce, + peakforce01, + 0] + + source = ColumnDataSource( data = dict( x = x, y = y, )) + sourcerange = ColumnDataSource( + data = dict( + x2575=x2575, + y2575=y2575, + x0199=x0199, + y0199=y0199, + )) + + sourceslipwash = ColumnDataSource( + data = dict( + xslip = [slipav,washav], + yslip = [thresholdforce,thresholdforce] + ) + ) + source2 = ColumnDataSource( rowdata @@ -493,7 +600,10 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False): avf = Span(location=averageforceav,dimension='width',line_color='blue', line_dash=[6,6],line_width=2) + plot.patch('x0199','y0199',source=sourcerange,color="red",alpha=0.05) + plot.patch('x2575','y2575',source=sourcerange,color="red",alpha=0.2) plot.line('x','y',source=source,color="red") + plot.circle('xslip','yslip',source=sourceslipwash,color="red") plot.add_layout(avf) @@ -533,14 +643,14 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False): ) sliplabel = Label(x=370,y=280,x_units='screen',y_units='screen', - text="Slip: {slipav:6.2f}".format(slipav=slipav), + text="Slip: {slipav:6.2f}".format(slipav=slipav-catchav), background_fill_alpha=0.7, background_fill_color='white', text_color='red', ) washlabel = Label(x=360,y=250,x_units='screen',y_units='screen', - text="Wash: {washav:6.2f}".format(washav=washav), + text="Wash: {washav:6.2f}".format(washav=finishav-washav), background_fill_alpha=0.7, background_fill_color='white', text_color='red', @@ -585,6 +695,7 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False): callback = CustomJS(args = dict( source=source, source2=source2, + sourceslipwash=sourceslipwash, avf=avf, avflabel=avflabel, catchlabel=catchlabel, @@ -598,9 +709,13 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False): ), code=""" var data = source.data var data2 = source2.data + var dataslipwash = sourceslipwash.data var x = data['x'] var y = data['y'] + + var xslip = dataslipwash['xslip'] + var spm1 = data2['spm'] var distance1 = data2['distance'] var driveenergy1 = data2['driveenergy'] @@ -665,6 +780,9 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False): data['x'] = [catchav,catchav+slipav,peakforceangleav,finishav-washav,finishav] data['y'] = [0,thresholdforce,peakforceav,thresholdforce,0] + dataslipwash['xslip'] = [catchav+slipav,finishav-washav] + dataslipwash['yslip'] = [thresholdforce,thresholdforce] + avf.location = averageforceav avflabel.text = 'Favg: '+averageforceav.toFixed(2) catchlabel.text = 'Catch: '+catchav.toFixed(2) @@ -677,6 +795,7 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False): // source.trigger('change'); source.change.emit(); + sourceslipwash.change.emit() """) annotation = TextInput(title="Type your plot notes here", value="", diff --git a/rowers/tests/testdata/testdata.csv.gz b/rowers/tests/testdata/testdata.csv.gz index 46cdd11e..d29dbd37 100644 Binary files a/rowers/tests/testdata/testdata.csv.gz and b/rowers/tests/testdata/testdata.csv.gz differ