diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py index 1ed3e6ad..0c183790 100644 --- a/rowers/interactiveplots.py +++ b/rowers/interactiveplots.py @@ -25,7 +25,7 @@ import itertools from bokeh.plotting import figure, ColumnDataSource, Figure,curdoc from bokeh.models import CustomJS,Slider, TextInput,BoxAnnotation, Band -from rowers.utils import myqueue +from rowers.utils import myqueue, totaltime_sec_to_string import django_rq queue = django_rq.get_queue('default') queuelow = django_rq.get_queue('low') @@ -105,9 +105,10 @@ from pandas.core.groupby.groupby import DataError def build_goldmedalstandards(workouts,kfitness): dates = [] testpower = [] + testduration = [] fatigues = [] fitnesses = [] - + data = [] goldmedalstandards = [] goldmedaldurations = [] @@ -118,26 +119,35 @@ def build_goldmedalstandards(workouts,kfitness): goldmedalstandards.append(goldmedalstandard) goldmedaldurations.append(goldmedalseconds) - df = pd.DataFrame({'workout':ids,'goldmedalstandard':goldmedalstandards}) + df = pd.DataFrame({ + 'workout':ids, + 'goldmedalstandard':goldmedalstandards, + 'goldmedalduration':goldmedaldurations, + }) for w in workouts: ids = [w.id for w in workouts.filter(date__gte=w.date-datetime.timedelta(days=kfitness), date__lte=w.date)] powerdf = df[df['workout'].isin(ids)] + indexmax = powerdf['goldmedalstandard'].idxmax() powertest = powerdf['goldmedalstandard'].max() + durationtest = powerdf.loc[indexmax,'goldmedalduration'] dates.append(datetime.datetime.combine(w.date,datetime.datetime.min.time())) testpower.append(powertest) + testduration.append(durationtest) + fatigues.append(np.nan) fitnesses.append(np.nan) - return dates, testpower, fatigues, fitnesses + return dates, testpower, testduration, fatigues, fitnesses def get_testpower(workouts,fitnesstestsecs,kfitness): dates = [] testpower = [] + testduration = [] fatigues = [] fitnesses = [] data = [] @@ -195,6 +205,7 @@ def get_testpower(workouts,fitnesstestsecs,kfitness): dates.append(datetime.datetime.combine(w.date,datetime.datetime.min.time())) testpower.append(powertest) + testduration.append(fitnesstestsecs) fatigues.append(np.nan) fitnesses.append(np.nan) @@ -1635,7 +1646,7 @@ def interactive_forcecurve(theworkouts,workstrokesonly=True,plottype='scatter'): return [script,div,js_resources,css_resources] def getfatigues( - fatigues,fitnesses,dates,testpower, + fatigues,fitnesses,dates,testpower,testduration, startdate,enddate,user,metricchoice,kfatigue,kfitness): fatigue = 0 @@ -1688,8 +1699,9 @@ def getfatigues( fitnesses.append(fitness) dates.append(datetime.datetime.combine(date,datetime.datetime.min.time())) testpower.append(np.nan) + testduration.append(np.nan) - return fatigues,fitnesses,dates,testpower,impulses + return fatigues,fitnesses,dates,testpower,testduration,impulses def performance_chart(user,startdate=None,enddate=None,kfitness=42,kfatigue=7, metricchoice='trimp',doform=False,dofatigue=False): @@ -1933,11 +1945,11 @@ def fitnessfit_chart(workouts,user,workoutmode='water',startdate=None, df = pd.DataFrame() if not usegoldmedalstandard: - dates,testpower,fatigues,fitnesses = get_testpower( + dates,testpower,testduration, fatigues,fitnesses = get_testpower( workouts,fitnesstestsecs,kfitness ) else: - dates,testpower,fatigues,fitnesses = build_goldmedalstandards( + dates,testpower, testduration,fatigues,fitnesses = build_goldmedalstandards( workouts,kfitness ) # create CP data @@ -1945,6 +1957,7 @@ def fitnessfit_chart(workouts,user,workoutmode='water',startdate=None, df = pd.DataFrame({ 'date':dates, 'testpower':testpower, + 'testduration':testduration, 'fatigue':fatigues, 'fitness':fitnesses, }) @@ -1965,9 +1978,10 @@ def fitnessfit_chart(workouts,user,workoutmode='water',startdate=None, testpower = df['testpower'].values.tolist() fatigues = df['fatigue'].values.tolist() fitnesses = df['fitness'].values.tolist() + testduration = df['testduration'].values.tolist() - fatigues,fitnesses,dates,testpower,impulses = getfatigues( - fatigues,fitnesses,dates,testpower, + fatigues,fitnesses,dates,testpower,testduration,impulses = getfatigues( + fatigues,fitnesses,dates,testpower,testduration, startdate,enddate,user,metricchoice,kfatigue,kfitness ) @@ -1975,6 +1989,7 @@ def fitnessfit_chart(workouts,user,workoutmode='water',startdate=None, df = pd.DataFrame({ 'date':dates, 'testpower':testpower, + 'testduration':testduration, 'fatigue':fatigues, 'fitness':fitnesses, }) @@ -2000,6 +2015,7 @@ def fitnessfit_chart(workouts,user,workoutmode='water',startdate=None, source = ColumnDataSource( data = dict( testpower = df['testpower'], + testduration = df['testduration'].apply(lambda x:totaltime_sec_to_string(x,shorten=True)), date = df['date'], fdate = df['date'].map(lambda x: x.strftime('%d-%m-%Y')), fitness = df['fitness'], @@ -2109,7 +2125,8 @@ def fitnessfit_chart(workouts,user,workoutmode='water',startdate=None, hover = plot.select(dict(type=HoverTool)) hover.tooltips = OrderedDict([ - (legend_label,'@testpower'), + (legend_label,'@testpower{int}'), + ('Test', '@testduration'), ('Date','@fdate'), (fitlabel,'@fitness'), (fatiguelabel,'@fatigue'), diff --git a/rowers/utils.py b/rowers/utils.py index 954a611a..c7573b69 100644 --- a/rowers/utils.py +++ b/rowers/utils.py @@ -377,6 +377,8 @@ def wavg(group, avg_name, weight_name): return d.mean() def totaltime_sec_to_string(totaltime,shorten=False): + if np.isnan(totaltime): + return '' hours = int(totaltime / 3600.) if hours > 23: message = 'Warning: The workout duration was longer than 23 hours. '