From 4dd42d43c74c80db236cea490060adba943c8f59 Mon Sep 17 00:00:00 2001 From: sanderroosendaal Date: Tue, 1 Nov 2016 09:48:03 +0100 Subject: [PATCH] Rewrote interactiveplots to use timedelta everywhere for time and pace --- rowers/interactiveplots.py | 667 +++++++-------------------------- rowers/templates/about_us.html | 1 + rowers/tests.py | 16 +- rowers/urls.py | 6 +- rowers/views.py | 85 ----- 5 files changed, 145 insertions(+), 630 deletions(-) diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py index 806c1125..8bb0f5f0 100644 --- a/rowers/interactiveplots.py +++ b/rowers/interactiveplots.py @@ -96,41 +96,15 @@ def nicepaceformat(values): return out -def get_datetimes(seconds,tzinfo=0,datevalues=0): - out = [] - for second in seconds: - if (second<=0) or (second>1e9): - days = 0 - hours = 0 - minutes=0 - sec=0 - microsecond = 0 - elif math.isnan(second): - days = 0 - hours = 0 - minutes=0 - sec=0 - microsecond = 0 - else: - days = int(second/(24.*3600.)) % (24*3600) - hours = int((second-24.*3600.*days)/3600.) % 24 +def timedeltaconv(x): + if x<=0 or x>1e9: + x=0 - minutes = int((second-3600.*(hours+24.*days))/60.) % 60 - sec = int(second-3600.*(hours+24.*days)-60.*minutes) % 60 - microsecond = int(1.0e6*(second-3600.*(hours+24.*days)-60.*minutes-sec)) - dt = datetime.timedelta(hours=hours,minutes=minutes, - seconds=sec,microseconds=microsecond) - - - if datevalues==1: - t = datetime.datetime(2016,5,1)+dt - dt = t - - out.append(dt) + dt = datetime.timedelta(seconds=x) + return dt - return out def interactive_histoall(theworkouts): TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,resize,crosshair' @@ -236,6 +210,7 @@ def googlemap_chart(lat,lon,name=""): def interactive_cpchart(thedistances,thesecs,theavpower, theworkouts,promember=0): + message = 0 # plot tools if (promember==1): @@ -247,20 +222,24 @@ def interactive_cpchart(thedistances,thesecs,theavpower, x_axis_type = 'log' y_axis_type = 'linear' - velo = thedistances/thesecs - p = 500./velo + thesecs = pd.Series(thesecs) + + velo = thedistances/thesecs + p = pd.Series(500./velo) + + p2 = p.apply(lambda x: timedeltaconv(x)) - p2 = get_datetimes(p,datevalues=1) - p2a = get_datetimes(p) - source = ColumnDataSource( data = dict( dist = thedistances, duration = thesecs, spm = 0*theavpower, - tim = niceformat(get_datetimes(thesecs,tzinfo=1)), + tim = niceformat( + thesecs.apply(lambda x: timedeltaconv(x)) + ), + power = theavpower, - pace = nicepaceformat(p2a), + pace = nicepaceformat(p2), ) ) @@ -271,15 +250,14 @@ def interactive_cpchart(thedistances,thesecs,theavpower, paulslope = 5.0/np.log10(2.0) paulintercept = p[0]-paulslope*np.log10(thedistances[0]) - fitx = np.arange(100)*2*max(np.log10(thedistances))/100. + fitx = pd.Series(np.arange(100)*2*max(np.log10(thedistances))/100.) fitp = paulslope*fitx+paulintercept fitvelo = 500./fitp fitpower = 2.8*(fitvelo**3) fitt = 10**fitx/fitvelo - fitp2 = get_datetimes(fitp,datevalues=1) - fitp2a = get_datetimes(fitp,datevalues=0) + fitp2 = fitp.apply(lambda x: timedeltaconv(x)) sourcepaul = ColumnDataSource( @@ -288,31 +266,13 @@ def interactive_cpchart(thedistances,thesecs,theavpower, duration = fitt, power = fitpower, spm = 0*fitpower, - tim = niceformat(get_datetimes(fitt,tzinfo=1)), - pace = nicepaceformat(fitp2a), + tim = niceformat( + fitt.apply(lambda x: timedeltaconv(x)) + ), + pace = nicepaceformat(fitp2), ) ) - # fitting the data to simple CP model -# simpleslope, simpleintercept,r,p,stderr = linregress(1./thesecs,theavpower) - -# fitx = 1.e-4+np.arange(10000)/10000. -# fitpower = simpleslope*fitx+simpleintercept -# fitvelo = (fitpower/2.8)**(1./3.) -# fitt = 1./fitx -# fitdist = fitt*fitvelo -# fitp = 500./fitvelo -# fitp2 = get_datetimes(fitp) - -# sourcesimple = ColumnDataSource( -# data = dict( -# dist = fitdist, -# duration = fitt, -# power = fitpower, -# tim = niceformat(get_datetimes(fitt)), -# pace = nicepaceformat(fitp2), -# ) -# ) # fitting the data to three parameter CP model fitfunc = lambda pars,x: pars[0]/(1+(x/pars[2])) + pars[1]/(1+(x/pars[3])) @@ -328,7 +288,7 @@ def interactive_cpchart(thedistances,thesecs,theavpower, p1 = [p0[0]/factor,p0[1]/factor,p0[2],p0[3]] - fitt = 10**(4*np.arange(100)/100.) + fitt = pd.Series(10**(4*np.arange(100)/100.)) fitpower = fitfunc(p1,fitt) @@ -339,17 +299,18 @@ def interactive_cpchart(thedistances,thesecs,theavpower, fitvelo = (fitpower/2.8)**(1./3.) fitdist = fitt*fitvelo fitp = 500./fitvelo - fitp2 = get_datetimes(fitp,datevalues=1) - fitp2a = get_datetimes(fitp,datevalues=0) + fitp2 = fitp.apply(lambda x: timedeltaconv(x)) sourcecomplex = ColumnDataSource( data = dict( dist = fitdist, duration = fitt, - tim = niceformat(get_datetimes(fitt,tzinfo=1)), + tim = niceformat( + fitt.apply(lambda x: timedeltaconv(x)) + ), spm = 0*fitpower, power = fitpower, - pace = nicepaceformat(fitp2a), + pace = nicepaceformat(fitp2), ) ) @@ -378,16 +339,17 @@ def interactive_cpchart(thedistances,thesecs,theavpower, p = 500./velo - p2 = get_datetimes(p,datevalues=1) - p2a = get_datetimes(p,datevalues=0) + p2 = p.apply(lambda x: timedeltaconv(x)) source2 = ColumnDataSource( data = dict( duration = cpdata['Delta'], power = cpdata['CP'], - tim = niceformat(get_datetimes(cpdata['Delta'],tzinfo=1)), + tim = niceformat( + cpdata['Delta'].apply(lambda x: timedeltaconv(x)) + ), dist = cpdata['Distance'], - pace = nicepaceformat(p2a), + pace = nicepaceformat(p2), ) ) @@ -395,22 +357,6 @@ def interactive_cpchart(thedistances,thesecs,theavpower, fill_color='blue',size=3, legend = 'Power from segments') -# for workout in theworkouts: -# f1 = workout.csvfilename -# rowdata = rdata(f1) -# cpdata = rowdata.getcp() - -# source2 = ColumnDataSource( -# data = dict( -# duration = cpdata['Delta'], -# power = cpdata['CP'], -# dist = cpdata['Distance'], -# ) -# ) - -# plot.circle('duration','power',source=source2,fill_color='blue',size=3) - - hover = plot.select(dict(type=HoverTool)) hover.tooltips = OrderedDict([ @@ -426,22 +372,8 @@ def interactive_cpchart(thedistances,thesecs,theavpower, plot.x_range = Range1d(1,2*max(thesecs)) plot.legend.orientation = "vertical" -# plot.extra_y_ranges = {"distance": Range1d(start=0, -# end=1.1*max(thedistances))} -# plot.circle('duration','dist',source=source,fill_color='white',size=15, -# legend='Distance', -# y_range_name="distance") -# plot.line('duration','dist',source=sourcepaul,y_range_name="distance") -# plot.line('duration','dist',source=sourcesimple,legend="Simple CP model", -# color='red',y_range_name="distance") -# plot.line('duration','dist',source=sourcecomplex,legend="Simple CP model", -# color='green',y_range_name="distance") -# plot.add_layout(LinearAxis(y_range_name="distance", -# axis_label="Distance (m)"),'right') plot.line('duration','power',source=sourcepaul,legend="Paul's Law") -# plot.line('duration','power',source=sourcesimple,legend="Simple CP model", -# color='red') plot.line('duration','power',source=sourcecomplex,legend="CP Model", color='green') @@ -626,7 +558,7 @@ def interactive_chart(id=0,promember=0): return "","CSV Data File Not Found" t = rowdata.df.ix[:,'TimeStamp (sec)'] - t = t-rowdata.df.ix[0,'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. @@ -646,13 +578,10 @@ def interactive_chart(id=0,promember=0): - - t2 = get_datetimes(t,tzinfo=1) + t2 = t.apply(lambda x: timedeltaconv(x)) - # p[p>3000] = 3000. - p2 = get_datetimes(p,datevalues=1) - p2a = get_datetimes(p,datevalues=0) + p2 = p.apply(lambda x: timedeltaconv(x)) source = ColumnDataSource( data = dict( @@ -660,7 +589,7 @@ def interactive_chart(id=0,promember=0): y=hr, y2=p2, tf = niceformat(t2), - pace = nicepaceformat(p2a), + pace = nicepaceformat(p2), heartrate = hr, spm=spm, spmc=np.rint(10*spm)/10., @@ -674,10 +603,8 @@ def interactive_chart(id=0,promember=0): plot_width=400, plot_height=400, toolbar_sticky=False, -# toolbar_location="below", tools=TOOLS) - # plot.line(t2,p2,legend="Pace") plot.line('x','y2',source=source,legend="Pace") plot.title.text = row.name plot.title.text_font_size=value("1.0em") @@ -695,14 +622,14 @@ def interactive_chart(id=0,promember=0): seconds = ["%S"], minutes = ["%M"] ) - ymax = datetime.datetime(2016,5,1,0,1,30) - ymin = datetime.datetime(2016,5,1,0,2,30) + ymax = 90. + ymin = 150. if row.workouttype == 'water': - ymax = datetime.datetime(2016,5,1,0,1,30) - ymin = datetime.datetime(2016,5,1,0,3,30) + ymax = 90. + ymin = 210. - plot.y_range = Range1d(ymin,ymax) + plot.y_range = Range1d(1.e3*ymin,1.e3*ymax) hover = plot.select(dict(type=HoverTool)) @@ -719,7 +646,6 @@ def interactive_chart(id=0,promember=0): hover.mode = 'mouse' plot.extra_y_ranges = {"hr": Range1d(start=100,end=200)} - # plot.line(t2,hr,color="red",y_range_name="hr",legend="Heart Rate") plot.line('x','y',source=source,color="red", y_range_name="hr", legend="Heart Rate") plot.add_layout(LinearAxis(y_range_name="hr",axis_label="HR"),'right') @@ -781,7 +707,7 @@ def interactive_cum_flex_chart(theworkouts,promember=0, yaxminima = { 'hr':100, 'spm':15, - 'pace': datetime.datetime(2016,5,1,0,3,30), + 'pace': 1.0e3*210, 'power': 0, 'averageforce': 0, 'peakforce': 0, @@ -793,7 +719,7 @@ def interactive_cum_flex_chart(theworkouts,promember=0, yaxmaxima = { 'hr':200, 'spm':45, - 'pace':datetime.datetime(2016,5,1,0,1,30), + 'pace':1.0e3*90, 'power': 600, 'averageforce':200, 'peakforce':400, @@ -851,9 +777,9 @@ def interactive_cum_flex_chart(theworkouts,promember=0, if xparam=='time': xaxmax = x1.max() xaxmin = x1.min() - xaxmax = get_datetimes([xaxmax],tzinfo=1)[0] - xaxmin = get_datetimes([xaxmin],tzinfo=1)[0] - x1 = get_datetimes(x1,tzinfo=1) + xaxmax = 1.0e3*xaxmax + xaxmin = 1.0e3*xaxmin + x1 = x1.apply(lambda x: timedeltaconv(x)) elif xparam=='distance': xaxmax = x1.max() xaxmin = x1.min() @@ -871,9 +797,9 @@ def interactive_cum_flex_chart(theworkouts,promember=0, y2mean = y2.mean() if xparam != 'time': - xvals = xaxmin+np.arange(100)*(xaxmax-xaxmin)/100. + xvals = pd.Series(xaxmin+np.arange(100)*(xaxmax-xaxmin)/100.) else: - xvals = np.arange(100) + xvals = pd.Series(np.arange(100)) x_axis_type = 'linear' y_axis_type = 'linear' @@ -882,9 +808,7 @@ def interactive_cum_flex_chart(theworkouts,promember=0, if yparam1 == 'pace': y_axis_type = 'datetime' - y1 = get_datetimes(y1,datevalues=1) - ymax = datetime.datetime(2016,5,1,0,1,30) - ymin = datetime.datetime(2016,5,1,0,2,30) + y1 = y1.apply(lambda x: timedeltaconv(x)) time = thedata.ix[:,csvcolumns['time']] @@ -929,8 +853,12 @@ def interactive_cum_flex_chart(theworkouts,promember=0, x1=x1, y1=y1, y2=y2, - time=niceformat(get_datetimes(time,tzinfo=1)), - pace=nicepaceformat(get_datetimes(pace)), + time=niceformat( + time.apply(lambda x: timedeltaconv(x)) + ), + pace=nicepaceformat( + pace.apply(lambda x: timedeltaconv(x)) + ), hr = hr, spm = spm, spmc=np.rint(10*spm)/10., @@ -944,8 +872,12 @@ def interactive_cum_flex_chart(theworkouts,promember=0, x1=x1, y1=y1, y2=y2, - time=niceformat(get_datetimes(time,tzinfo=1)), - pace=nicepaceformat(get_datetimes(pace)), + time=niceformat( + time.apply(lambda x: timedeltaconv(x)) + ), + pace=nicepaceformat( + pace.apply(lambda x: timedeltaconv(x)) + ), hr = hr, spm = spm, spmc=np.rint(10*spm)/10., @@ -972,8 +904,8 @@ def interactive_cum_flex_chart(theworkouts,promember=0, plot.x_range = xrange1 if xparam == 'time': - #xrange1 = Range1d(start=xaxmin,end=xaxmax) - #plot.x_range = xrange1 + xrange1 = Range1d(start=xaxmin,end=xaxmax) + plot.x_range = xrange1 plot.xaxis[0].formatter = DatetimeTickFormatter( hours = ["%H"], minutes = ["%M"], @@ -986,7 +918,6 @@ def interactive_cum_flex_chart(theworkouts,promember=0, if yparam1 == 'pace': - plot.y_range = Range1d(ymin,ymax) plot.yaxis[0].formatter = DatetimeTickFormatter( seconds = ["%S"], minutes = ["%M"] @@ -1138,321 +1069,6 @@ def interactive_cum_flex_chart(theworkouts,promember=0, -def interactive_flex_chart(id=0,promember=0, - xparam='time', - yparam1='pace', - yparam2='hr', - plottype='line', - workstrokesonly=False): - - 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', - '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)', - 'driveenergy': 'Work per Stroke (J)', - 'drivespeed': 'Drive Speed (m/s)', - 'None': '', - } - - yaxminima = { - 'hr':100, - 'spm':15, - 'pace': datetime.datetime(2016,5,1,0,3,30), - 'power': 0, - 'averageforce': 0, - 'peakforce': 0, - 'drivelength':0.5, - 'driveenergy': 0, - 'drivespeed': 0, - } - - yaxmaxima = { - 'hr':200, - 'spm':45, - 'pace':datetime.datetime(2016,5,1,0,1,30), - 'power': 600, - 'averageforce':200, - 'peakforce':400, - 'drivelength':2.0, - 'driveenergy': 1000, - '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) - if rowdata == 0: - return "","CSV Data File Not Found" - - workoutstateswork = [1,4,5,8,9,6,7] - workoutstatesrest = [3] - workoutstatetransition = [0,2,10,11,12,13] - - if workstrokesonly: - try: - rowdata.df = rowdata.df[~rowdata.df[' WorkoutState'].isin(workoutstatesrest)] - except KeyError: - pass - - - rowdata.df['driveenergy'] = rowdata.df[' DriveLength (meters)']*rowdata.df[' AverageDriveForce (lbs)']*4.44822 - - f = rowdata.df['TimeStamp (sec)'].diff().mean() - windowsize = 2*(int(10./(f)))+1 - if windowsize <= 3: - windowsize = 5 - - spm = rowdata.df.ix[:,csvcolumns['spm']] - hr = rowdata.df.ix[:,csvcolumns['hr']] - - - if windowsize > 3: - spm = savgol_filter(spm,windowsize,3) - hr = savgol_filter(hr,windowsize,3) - - rowdata.df[' Cadence (stokes/min)'] = spm - rowdata.df[' HRCur (bpm)'] = hr - - drivelength = rowdata.df[' DriveLength (meters)'] - if windowsize > 3: - drivelength = savgol_filter(drivelength,windowsize,3) - - rowdata.df[' DriveLength (meters)'] = drivelength - - rowdata.df['drivespeed'] = drivelength/rowdata.df[' DriveTime (ms)']*1.0e3 - - # get user - # u = User.objects.get(id=row.user.id) - - x1 = rowdata.df.ix[:,csvcolumns[xparam]] - - y1 = rowdata.df.ix[:,csvcolumns[yparam1]] - - - if yparam2 != 'None': - y2 = rowdata.df.ix[:,csvcolumns[yparam2]] - else: - y2 = y1 - - if xparam=='time': - - xaxmax = x1.max() - xaxmin = x1.min() - xaxmax = get_datetimes([xaxmax],tzinfo=1)[0] - xaxmin = get_datetimes([xaxmin],tzinfo=1)[0] - x1 = get_datetimes(x1,tzinfo=1) - - if xparam=='distance': - xaxmax = x1.max() - xaxmin = x1.min() - - # average values - y1mean = y1.median()+0.0*np.arange(100) - y2mean = y2.median()+0.0*np.arange(100) - if xparam != 'time': - x1mean = x1.median()+0.0*np.arange(100) - else: - x1mean = 0+0.0*np.arange(100) - - - - if xparam != 'time' and xparam != 'distance' and yparam1 != 'pace': - xvals = yaxminima[xparam]+np.arange(100)*(yaxmaxima[xparam]-yaxminima[xparam])/100. - y1vals = yaxminima[yparam1]+np.arange(100)*(yaxmaxima[yparam1]-yaxminima[yparam1])/100. - else: - xvals = np.arange(100) - y1vals = np.arange(100) - - - - # constant power plot - if yparam1 == 'driveenergy': - if xparam == 'spm': - yconstantpower = y1.median()*x1.median()/xvals - - - - - x_axis_type = 'linear' - y_axis_type = 'linear' - if xparam == 'time': - x_axis_type = 'datetime' - - if yparam1 == 'pace': - y_axis_type = 'datetime' - y1 = get_datetimes(y1,datevalues=1) - ymax = datetime.datetime(2016,5,1,0,1,30) - ymin = datetime.datetime(2016,5,1,0,2,30) - - if row.workouttype == 'water': - ymax = datetime.datetime(2016,5,1,0,1,30) - ymin = datetime.datetime(2016,5,1,0,3,30) - - time = rowdata.df.ix[:,csvcolumns['time']] - time = time-time[time.index[0]] - - hr = rowdata.df.ix[:,csvcolumns['hr']] - - - pace = rowdata.df.ix[:,csvcolumns['pace']] - - distance = rowdata.df.ix[:,csvcolumns['distance']] - - power = rowdata.df.ix[:,csvcolumns['power']] - - # Add hover to this comma-separated string and see what changes - if (promember==1): - TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,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_sticky=False, - plot_width=900, - ) - - - source = ColumnDataSource( - data = dict( - x1=x1, - y1=y1, - y2=y2, - time=niceformat(get_datetimes(time,tzinfo=1)), - pace=nicepaceformat(get_datetimes(pace)), - hr = hr, - spm = spm, - spmc=np.rint(10*spm)/10., - distance=distance, - power=power, - xvals=xvals, - y1mean=y1mean, - x1mean=x1mean, - y1vals=y1vals, - ) - ) - - - # average values - plot.line('xvals','y1mean',color="black",source=source) - plot.line('x1mean','y1vals',color="black",source=source) - if yparam1 == 'driveenergy': - if xparam == 'spm': - plot.line(xvals,yconstantpower,color="green",legend="Constant Power") - - if plottype=='line': - plot.line('x1','y1',source=source,legend=axlabels[yparam1]) - elif plottype=='scatter': -# plot.circle('x1','y1',source=source,legend=yparam1,size=3) - plot.scatter('x1','y1',source=source,legend=axlabels[yparam1],fill_alpha=0.4, - line_color=None) - - plot.title.text = row.name - plot.title.text_font_size=value("1.0em") - plot.xaxis.axis_label = axlabels[xparam] - plot.yaxis.axis_label = axlabels[yparam1] - - - yrange1 = Range1d(start=yaxminima[yparam1],end=yaxmaxima[yparam1]) - plot.y_range = yrange1 - - if (xparam != 'time') and (xparam != 'distance'): - xrange1 = Range1d(start=yaxminima[xparam],end=yaxmaxima[xparam]) - plot.x_range = xrange1 - - if xparam == 'time': - #xrange1 = Range1d(start=xaxmin,end=xaxmax) - #plot.x_range = xrange1 - plot.xaxis[0].formatter = DatetimeTickFormatter( - hours = ["%H"], - minutes = ["%M"], - seconds = ["%S"], - days = ["0"], - months = [""], - years = [""] - ) - - - if yparam1 == 'pace': - plot.y_range = Range1d(ymin,ymax) - plot.yaxis[0].formatter = DatetimeTickFormatter( - seconds = ["%S"], - minutes = ["%M"] - ) - - if yparam2 != 'None': - yrange2 = Range1d(start=yaxminima[yparam2],end=yaxmaxima[yparam2]) - plot.extra_y_ranges = {"yax2": yrange2} - plot.line(xvals,y2mean,color="black",y_range_name="yax2") - - if plottype=='line': - plot.line('x1','y2',color="red",y_range_name="yax2", - legend=axlabels[yparam2], - source=source) - - elif plottype=='scatter': -# plot.circle(x1,y2,color="red",y_range_name="yax2",legend=yparam2, -# source=source,size=3) - plot.scatter('x1','y2',source=source,legend=axlabels[yparam2] - ,fill_alpha=0.4, - line_color=None,color="red",y_range_name="yax2") - - plot.add_layout(LinearAxis(y_range_name="yax2", - axis_label=axlabels[yparam2]),'right') - - - hover = plot.select(dict(type=HoverTool)) - - - hover.tooltips = OrderedDict([ - ('Time','@time'), - ('Distance','@distance{int}'), - ('Pace','@pace'), - ('HR','@hr'), - ('SPM','@spmc{1.1}'), - ('Power','@power{int}'), - ]) - - hover.mode = 'mouse' - - - - script, div = components(plot) - - return [script,div] - - def interactive_flex_chart2(id=0,promember=0, xparam='time', yparam1='pace', @@ -1492,7 +1108,7 @@ def interactive_flex_chart2(id=0,promember=0, yaxminima = { 'hr':100, 'spm':15, - 'pace': datetime.timedelta(minutes=1,seconds=40), + 'pace': 1.0e3*210, 'power': 0, 'averageforce': 0, 'peakforce': 0, @@ -1504,7 +1120,7 @@ def interactive_flex_chart2(id=0,promember=0, yaxmaxima = { 'hr':200, 'spm':45, - 'pace':datetime.timedelta(minutes=3,seconds=30), + 'pace': 1.0e3*90, 'power': 600, 'averageforce':200, 'peakforce':400, @@ -1580,11 +1196,9 @@ def interactive_flex_chart2(id=0,promember=0, y2 = y1 if xparam=='time': - xaxmax = x1.max() - xaxmin = x1.min() - xaxmax = get_datetimes([xaxmax],tzinfo=1)[0] - xaxmin = get_datetimes([xaxmin],tzinfo=1)[0] - x1 = get_datetimes(x1,tzinfo=1) + xaxmax = 1.0e3*x1.max() + xaxmin = 1.0e3*x1.min() + x1 = x1.apply(lambda x: timedeltaconv(x)) elif xparam=='distance': xaxmax = x1.max() xaxmin = x1.min() @@ -1610,9 +1224,6 @@ def interactive_flex_chart2(id=0,promember=0, if yparam1 == 'driveenergy': if xparam == 'spm': yconstantpower = y1.median()*x1.median()/xvals - - - x_axis_type = 'linear' y_axis_type = 'linear' @@ -1621,13 +1232,9 @@ def interactive_flex_chart2(id=0,promember=0, if yparam1 == 'pace': y_axis_type = 'datetime' - y1 = get_datetimes(y1,datevalues=1) - ymax = datetime.datetime(2016,5,1,0,1,30) - ymin = datetime.datetime(2016,5,1,0,2,30) + y1mean = 1.0e3*y1mean + y1 = y1.apply(lambda x: timedeltaconv(x)) - if row.workouttype == 'water': - ymax = datetime.datetime(2016,5,1,0,1,30) - ymin = datetime.datetime(2016,5,1,0,3,30) time = rowdata.df.ix[:,csvcolumns['time']] time = time-time[time.index[0]] @@ -1647,14 +1254,17 @@ def interactive_flex_chart2(id=0,promember=0, x1=x1, y1=y1, y2=y2, - time=niceformat(get_datetimes(time,tzinfo=1)), - pace=nicepaceformat(get_datetimes(pace)), + time=niceformat( + time.apply(lambda x: timedeltaconv(x)) + ), + pace=nicepaceformat( + pace.apply(lambda x: timedeltaconv(x)) + ), hr = hr, spm = spm, spmc=np.rint(10*spm)/10., distance=distance, power=power, -# xvals=xvals, y1mean=[y1mean,y1mean], y2mean=[y2mean,y2mean], x1mean=[x1mean,x1mean], @@ -1667,14 +1277,17 @@ def interactive_flex_chart2(id=0,promember=0, x1=x1, y1=y1, y2=y2, - time=niceformat(get_datetimes(time,tzinfo=1)), - pace=nicepaceformat(get_datetimes(pace)), + time=niceformat( + time.apply(lambda x: timedeltaconv(x)) + ), + pace=nicepaceformat( + pace.apply(lambda x: timedeltaconv(x)) + ), hr = hr, spm = spm, spmc=np.rint(10*spm)/10., distance=distance, power=power, -# xvals=xvals, y1mean=[y1mean,y1mean], y2mean=[y2mean,y2mean], x1mean=[x1mean,x1mean], @@ -1694,8 +1307,8 @@ def interactive_flex_chart2(id=0,promember=0, plot = Figure(x_axis_type=x_axis_type,y_axis_type=y_axis_type, tools=TOOLS, toolbar_sticky=False, -# plot_width=900, ) + x1means = Span(location=x1mean,dimension='height',line_color='green', line_dash=[6,6], line_width=2) @@ -1718,7 +1331,6 @@ def interactive_flex_chart2(id=0,promember=0, if plottype=='line': plot.line('x1','y1',source=source2,legend=axlabels[yparam1]) elif plottype=='scatter': -# plot.circle('x1','y1',source=source2,legend=yparam1,size=3) plot.scatter('x1','y1',source=source2,legend=axlabels[yparam1],fill_alpha=0.4, line_color=None) @@ -1729,17 +1341,16 @@ def interactive_flex_chart2(id=0,promember=0, - if (yparam1 != 'pace'): - yrange1 = Range1d(start=yaxminima[yparam1],end=yaxmaxima[yparam1]) - plot.y_range = yrange1 + yrange1 = Range1d(start=yaxminima[yparam1],end=yaxmaxima[yparam1]) + plot.y_range = yrange1 if (xparam != 'time') and (xparam != 'distance'): xrange1 = Range1d(start=yaxminima[xparam],end=yaxmaxima[xparam]) plot.x_range = xrange1 if xparam == 'time': - #xrange1 = Range1d(start=xaxmin,end=xaxmax) - #plot.x_range = xrange1 + xrange1 = Range1d(start=xaxmin,end=xaxmax) + plot.x_range = xrange1 plot.xaxis[0].formatter = DatetimeTickFormatter( hours = ["%H"], minutes = ["%M"], @@ -1751,13 +1362,12 @@ def interactive_flex_chart2(id=0,promember=0, if yparam1 == 'pace': - plot.y_range = Range1d(ymin,ymax) plot.yaxis[0].formatter = DatetimeTickFormatter( seconds = ["%S"], minutes = ["%M"] ) - if yparam2 != 'None' and yparam2 != 'pace': + if yparam2 != 'None': yrange2 = Range1d(start=yaxminima[yparam2],end=yaxmaxima[yparam2]) plot.extra_y_ranges = {"yax2": yrange2} @@ -1767,8 +1377,6 @@ def interactive_flex_chart2(id=0,promember=0, source=source2) elif plottype=='scatter': -# plot.circle(x1,y2,color="red",y_range_name="yax2",legend=yparam2, -# source=source,size=3) plot.scatter('x1','y2',source=source2,legend=axlabels[yparam2] ,fill_alpha=0.4, line_color=None,color="red",y_range_name="yax2") @@ -1974,14 +1582,13 @@ def interactive_bar_chart(id=0,promember=0): else: TOOLS = 'pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' - t2 = get_datetimes(t,tzinfo=1) - p2 = get_datetimes(p,datevalues=1) - p2a = get_datetimes(p,datevalues=0) + t2 = t.apply(lambda x: timedeltaconv(x)) + p2 = p.apply(lambda x: timedeltaconv(x)) source = ColumnDataSource( data = dict( x=t2, - x_right = get_datetimes(t+time_increments,tzinfo=1), + x_right = (t+time_increments).apply(lambda x:timedeltaconv(x)), hr=hr, hr_ut2=hr_ut2, hr_ut1=hr_ut1, @@ -1992,7 +1599,7 @@ def interactive_bar_chart(id=0,promember=0): hr_bottom = 0.0*hr, y2=p2, tf = niceformat(t2), - pace = nicepaceformat(p2a), + pace = nicepaceformat(p2), heartrate = hr, spmc=np.rint(10*spm)/10., spm=spm, @@ -2016,18 +1623,19 @@ def interactive_bar_chart(id=0,promember=0): days = ["0"], months = [""], years = [""] -) + ) plot.yaxis[0].formatter = DatetimeTickFormatter( - seconds = ["%S"], - minutes = ["%M"], -) - ymax = datetime.datetime(2016,5,1,0,1,30) - ymin = datetime.datetime(2016,5,1,0,2,30) + hours = "", + seconds = ["%S"], + minutes = ["%M"], + ) + ymax = 1.0e3*90 + ymin = 1.0e3*180 if row.workouttype == 'water': - ymax = datetime.datetime(2016,5,1,0,1,30) - ymin = datetime.datetime(2016,5,1,0,3,30) + ymax = 1.0e3*90 + ymin = 1.0e3*210 plot.y_range = Range1d(ymin,ymax) @@ -2174,8 +1782,8 @@ def interactive_comparison_chart(id1=0,id2=0,xparam='distance',yparam='spm', if xparam=='time': x1 = x1-x1[0] x2 = x2-x2[0] - x1 = get_datetimes(x1,tzinfo=1) - x2 = get_datetimes(x2,tzinfo=1) + x1 = x1.apply(lambda x: timedeltaconv(x)) + x2 = x2.apply(lambda x: timedeltaconv(x)) x_axis_type = 'linear' y_axis_type = 'linear' @@ -2184,14 +1792,14 @@ def interactive_comparison_chart(id1=0,id2=0,xparam='distance',yparam='spm', if yparam == 'pace': y_axis_type = 'datetime' - y1 = get_datetimes(y1,datevalues=1) - y2 = get_datetimes(y2,datevalues=1) - ymax = datetime.datetime(2016,5,1,0,1,30) - ymin = datetime.datetime(2016,5,1,0,2,30) + y1 = y1.apply(lambda x: timedeltaconv(x)) + y2 = y2.apply(lambda x: timedeltaconv(x)) + ymax = 1.0e3*90 + ymin = 1.0e3*180 if row1.workouttype == 'water': - ymax = datetime.datetime(2016,5,1,0,1,30) - ymin = datetime.datetime(2016,5,1,0,3,30) + ymax = 1.0e3*90 + ymin = 1.0e3*210 time1 = rowdata1.df.ix[:,csvcolumns['time']] time2 = rowdata2.df.ix[:,csvcolumns['time']] @@ -2223,10 +1831,20 @@ def interactive_comparison_chart(id1=0,id2=0,xparam='distance',yparam='spm', x2=x2, y1=y1, y2=y2, - time1=niceformat(get_datetimes(time1,tzinfo=1)), - time2=niceformat(get_datetimes(time2,tzinfo=1)), - pace1=nicepaceformat(get_datetimes(pace1)), - pace2=nicepaceformat(get_datetimes(pace2)), + time1=niceformat( + time1.apply(lambda x: timedeltaconv(x)) + ), + + time2=niceformat( + time2.apply(lambda x: timedeltaconv(x)) + ), + pace1=nicepaceformat( + pace1.apply(lambda x: timedeltaconv(x)) + ), + + pace2=nicepaceformat( + pace2.apply(lambda x: timedeltaconv(x)) + ), hr1 = hr1, hr2 = hr2, spm1 = spm1, @@ -2244,29 +1862,18 @@ def interactive_comparison_chart(id1=0,id2=0,xparam='distance',yparam='spm', plot = Figure(x_axis_type=x_axis_type,y_axis_type=y_axis_type, tools=TOOLS, plot_width=920, - # toolbar_location="above", toolbar_sticky=False) - # plot.multi_line([x1,x2],[y1,y2],color=["blue","red"]) if plottype=='line': plot.line('x1','y1',source=source,color="blue",legend=row1.name) plot.line('x2','y2',source=source,color="red",legend=row2.name) elif plottype=='scatter': -# plot.circle('x1','y1',source=source,color="blue",legend=row1.name,size=3) -# plot.circle('x2','y2',source=source,color="red",legend=row2.name,size=3) plot.scatter('x1','y1',source=source,legend=row1.name,fill_alpha=0.4, line_color=None) plot.scatter('x2','y2',source=source,legend=row2.name,fill_alpha=0.4, line_color=None,color="red") - - - - - # plot.scatter('x1','y1',source=source,color="blue") - # plot.scatter('x2','y2',source=source,color="red") - plot.legend.location = "bottom_right" plot.title.text = row1.name+' vs '+row2.name @@ -2286,14 +1893,13 @@ def interactive_comparison_chart(id1=0,id2=0,xparam='distance',yparam='spm', if yparam == 'pace': - plot.y_range = Range1d(ymin,ymax) plot.yaxis[0].formatter = DatetimeTickFormatter( seconds = ["%S"], minutes = ["%M"] ) + plot.y_range = Range1d(ymin,ymax) - #hover = [t for t in plot.tools if isinstance(t, HoverTool)][0] hover = plot.select(dict(type=HoverTool)) @@ -2373,13 +1979,10 @@ def interactive_otw_advanced_pace_chart(id=0,promember=0): drivelength = savgol_filter(drivelength,windowsize,3) rowdata.df[' DriveLength (meters)'] = drivelength - t2 = get_datetimes(t,tzinfo=1) - p2 = get_datetimes(p,datevalues=1) - p2a = get_datetimes(p,datevalues=0) - nowindp2 = get_datetimes(nowindpace,datevalues=1) - nowindp2a = get_datetimes(nowindpace,datevalues=0) - ergpace2 = get_datetimes(ergpace,datevalues=1) - ergpace2a = get_datetimes(ergpace,datevalues=0) + t2 = t.apply(lambda x: timedeltaconv(x)) + p2 = p.apply(lambda x: timedeltaconv(x)) + nowindp2 = nowindpace.apply(lambda x: timedeltaconv(x)) + ergpace2 = ergpace.apply(lambda x: timedeltaconv(x)) # Add hover to this comma-separated string and see what changes if (promember==1): @@ -2394,9 +1997,9 @@ def interactive_otw_advanced_pace_chart(id=0,promember=0): nowindp2 = nowindp2, ergpace2 = ergpace2, tf = niceformat(t2), - pace = nicepaceformat(p2a), - ergpace = nicepaceformat(ergpace2a), - nowindpace = nicepaceformat(nowindp2a), + pace = nicepaceformat(p2), + ergpace = nicepaceformat(ergpace2), + nowindpace = nicepaceformat(nowindp2), heartrate = hr, spm=spm, spmc=np.rint(10*spm)/10., @@ -2425,8 +2028,8 @@ def interactive_otw_advanced_pace_chart(id=0,promember=0): minutes = ["%M"] ) - ymax = datetime.datetime(2016,5,1,0,1,30) - ymin = datetime.datetime(2016,5,1,0,3,30) + ymax = 1.0e3*90 + ymin = 1.0e3*210 plot.y_range = Range1d(ymin,ymax) diff --git a/rowers/templates/about_us.html b/rowers/templates/about_us.html index f7626823..0ecb3514 100644 --- a/rowers/templates/about_us.html +++ b/rowers/templates/about_us.html @@ -107,6 +107,7 @@ You will be taken to the secure PayPal payment site.