diff --git a/rowers/dataprep.py b/rowers/dataprep.py index 01749000..1e290073 100644 --- a/rowers/dataprep.py +++ b/rowers/dataprep.py @@ -79,6 +79,38 @@ def getrowdata(id=0): return rowdata,row + + +def smalldataprep(therows,xparam,yparam1,yparam2): + df = pd.DataFrame() + if yparam2 == 'None': + yparam2 = 'power' + df[xparam] = [] + df[yparam1] = [] + df[yparam2] = [] + df['distance'] = [] + df['spm'] = [] + for workout in therows: + f1 = workout.csvfilename + + try: + rowdata = dataprep(rrdata(f1).df) + + rowdata = pd.DataFrame({xparam: rowdata[xparam], + yparam1: rowdata[yparam1], + yparam2: rowdata[yparam2], + 'distance': rowdata['distance'], + 'spm': rowdata['spm'], + } + ) + df = pd.concat([df,rowdata],ignore_index=True) + except IOError: + pass + + return df + + + def dataprep(rowdatadf,bands=False,barchart=False,otwpower=False): rowdatadf.set_index([range(len(rowdatadf))],inplace=True) t = rowdatadf.ix[:,'TimeStamp (sec)'] @@ -113,7 +145,10 @@ def dataprep(rowdatadf,bands=False,barchart=False,otwpower=False): drivelength = savgol_filter(drivelength,windowsize,3) forceratio = savgol_filter(forceratio,windowsize,3) - t2 = t.fillna(method='ffill').apply(lambda x: timedeltaconv(x)) + try: + t2 = t.fillna(method='ffill').apply(lambda x: timedeltaconv(x)) + except TypeError: + t2 = 0*t p2 = p.fillna(method='ffill').apply(lambda x: timedeltaconv(x)) diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py index e27a6105..5e358a15 100644 --- a/rowers/interactiveplots.py +++ b/rowers/interactiveplots.py @@ -7,7 +7,7 @@ from rowingdata import rowingdata as rrdata from bokeh.plotting import figure, ColumnDataSource, Figure,curdoc from bokeh.models import CustomJS,Slider -from bokeh.charts import Histogram +from bokeh.charts import Histogram,HeatMap from bokeh.resources import CDN,INLINE from bokeh.embed import components from bokeh.layouts import layout,widgetbox @@ -563,6 +563,305 @@ def interactive_chart(id=0,promember=0): return [script,div] +def interactive_cum_flex_chart2(theworkouts,promember=0, + xparam='spm', + yparam1='power', + yparam2='spm'): + + datadf = dataprep.smalldataprep(theworkouts,xparam,yparam1,yparam2) + + + axlabels = { + 'time': 'Time', + 'distance': 'Distance (m)', + 'hr': 'Heart Rate (bpm)', + 'spm': 'Stroke Rate (spm)', + 'pace': 'Pace (/500m)', + 'power': 'Power (Watt)', + 'averageforce': 'Average Drive Force (lbs)', + 'drivelength': 'Drive Length (m)', + 'peakforce': 'Peak Drive Force (lbs)', + 'forceratio': 'Average/Peak Drive Force Ratio', + 'driveenergy': 'Work per Stroke (J)', + 'drivespeed': 'Drive Speed (m/s)', + 'None': '', + } + + yparamname1 = axlabels[yparam1] + yparamname2 = axlabels[yparam2] + + yaxminima = { + 'hr':100, + 'spm':15, + 'pace': 1.0e3*210, + 'power': 0, + 'averageforce': 0, + 'peakforce': 0, + 'forceratio':0, + 'drivelength':0.5, + 'driveenergy': 0, + 'drivespeed': 0, + } + + yaxmaxima = { + 'hr':200, + 'spm':45, + 'pace':1.0e3*90, + 'power': 600, + 'averageforce':200, + 'peakforce':400, + 'forceratio':1, + 'drivelength':2.0, + 'driveenergy': 1000, + 'drivespeed':4, + } + + + + datadf = datadf[datadf[yparam1] > 0] + + + datadf = datadf[datadf[xparam] > 0] + + if yparam2 != 'None': + datadf = datadf[datadf[yparam2] > 0] + + # check if dataframe not empty + if datadf.empty: + return ['','
No non-zero data in selection
','',''] + + + datadf['x1'] = datadf.ix[:,xparam] + + datadf['y1'] = datadf.ix[:,yparam1] + if yparam2 != 'None': + datadf['y2'] = datadf.ix[:,yparam2] + else: + datadf['y2'] = datadf['y1'] + + + if xparam=='distance': + xaxmax = datadf['x1'].max() + xaxmin = datadf['x1'].min() + else: + xaxmax = yaxmaxima[xparam] + xaxmin = yaxminima[xparam] + + # average values + x1mean = datadf['x1'].mean() + + y1mean = datadf['y1'].mean() + y2mean = datadf['y2'].mean() + + + xvals = pd.Series(xaxmin+np.arange(100)*(xaxmax-xaxmin)/100.) + + x_axis_type = 'linear' + y_axis_type = 'linear' + + datadf['xname'] = xparam + datadf['yname1'] = yparam1 + if yparam2 != 'None': + datadf['yname2'] = yparam2 + else: + datadf['yname2'] = yparam1 + + source = ColumnDataSource( + datadf + ) + + source2 = ColumnDataSource( + datadf.copy() + ) + + # Add hover to this comma-separated string and see what changes + if (promember==1): + TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,resize,crosshair' + else: + TOOLS = 'pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' + + plot = Figure(x_axis_type=x_axis_type,y_axis_type=y_axis_type, + tools=TOOLS, + toolbar_location="above", + toolbar_sticky=False) + + x1means = Span(location=x1mean,dimension='height',line_color='green', + line_dash=[6,6], line_width=2) + + y1means = Span(location=y1mean,dimension='width',line_color='blue', + line_dash=[6,6],line_width=2) + y2means = y1means + + xlabel = Label(x=370,y=130,x_units='screen',y_units='screen', + text=xparam+": {x1mean:6.2f}".format(x1mean=x1mean), + background_fill_alpha=.7, + text_color='green', + ) + + + plot.add_layout(x1means) + plot.add_layout(xlabel) + + plot.add_layout(y1means) + + y1label = Label(x=370,y=100,x_units='screen',y_units='screen', + text=yparam1+": {y1mean:6.2f}".format(y1mean=y1mean), + background_fill_alpha=.7, + text_color='blue', + ) + + plot.add_layout(y1label) + + y2label = y1label + plot.circle('x1','y1',source=source2,fill_alpha=0.3,line_color=None, + legend=yparamname1, + ) + + plot.xaxis.axis_label = axlabels[xparam] + plot.yaxis.axis_label = axlabels[yparam1] + + + yrange1 = Range1d(start=yaxminima[yparam1],end=yaxmaxima[yparam1]) + plot.y_range = yrange1 + + xrange1 = Range1d(start=yaxminima[xparam],end=yaxmaxima[xparam]) + plot.x_range = xrange1 + + + if yparam2 != 'None': + yrange2 = Range1d(start=yaxminima[yparam2],end=yaxmaxima[yparam2]) + plot.extra_y_ranges = {"yax2": yrange2} + + plot.circle('x1','y2',color="red",y_range_name="yax2", + legend=yparamname2, + source=source2,fill_alpha=0.3,line_color=None) + + plot.add_layout(LinearAxis(y_range_name="yax2", + axis_label=axlabels[yparam2]),'right') + + y2means = Span(location=y2mean,dimension='width',line_color='red', + line_dash=[6,6],line_width=2,y_range_name="yax2") + + + plot.add_layout(y2means) + y2label = Label(x=370,y=70,x_units='screen',y_units='screen', + text=yparam2+": {y2mean:6.2f}".format(y2mean=y2mean), + background_fill_alpha=.7, + text_color='red', + ) + if yparam2 != 'pace' and yparam2 != 'time': + plot.add_layout(y2label) + + + callback = CustomJS(args = dict(source=source,source2=source2, + x1means=x1means, + y1means=y1means, + y1label=y1label, + y2label=y2label, + xlabel=xlabel, + y2means=y2means), code=""" + var data = source.data + var data2 = source2.data + var x1 = data['x1'] + var y1 = data['y1'] + var y2 = data['y2'] + var spm1 = data['spm'] + var distance1 = data['distance'] + var xname = data['xname'][0] + var yname1 = data['yname1'][0] + var yname2 = data['yname2'][0] + + var minspm = minspm.value + var maxspm = maxspm.value + var mindist = mindist.value + var maxdist = maxdist.value + var xm = 0 + var ym1 = 0 + var ym2 = 0 + + data2['x1'] = [] + data2['y1'] = [] + data2['y2'] = [] + data2['spm'] = [] + data2['distance'] = [] + data2['x1mean'] = [] + data2['y1mean'] = [] + data2['y2mean'] = [] + data2['xvals'] = [] + data2['y1vals'] = [] + data2['y2vals'] = [] + + for (i=0; i