diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py index 68f6d5d2..d7e89e75 100644 --- a/rowers/interactiveplots.py +++ b/rowers/interactiveplots.py @@ -29,7 +29,9 @@ from bokeh.layouts import layout,widgetbox from bokeh.palettes import Category20c,Category10 from bokeh.layouts import row as layoutrow from bokeh.layouts import column as layoutcolumn -from bokeh.models import LinearAxis,LogAxis,Range1d,DatetimeTickFormatter,HoverTool +from bokeh.models import ( + LinearAxis,LogAxis,Range1d,DatetimeTickFormatter,HoverTool,Axis,PrintfTickFormatter + ) #from bokeh.io import output_file, show, vplot from bokeh.models import ( GMapPlot, GMapOptions, ColumnDataSource, Circle, @@ -2896,12 +2898,15 @@ def interactive_otwcpchart(powerdf,promember=0,rowername="",r=None,cpfit='data', deltas = powerdf['Delta'].apply(lambda x: timedeltaconv(x)) powerdf['ftime'] = niceformat(deltas) + powerdf['Deltaminutes'] = powerdf['Delta']/60. source = ColumnDataSource( data = powerdf ) + + # there is no Paul's law for OTW thesecs = powerdf['Delta'] @@ -2933,7 +2938,7 @@ def interactive_otwcpchart(powerdf,promember=0,rowername="",r=None,cpfit='data', data = dict( CP = fitpower, CPmax = ratio*fitpower, - duration = fitt, + duration = fitt/60., ftime = ftime, workout = workouts, ) @@ -2960,6 +2965,8 @@ def interactive_otwcpchart(powerdf,promember=0,rowername="",r=None,cpfit='data', plot.extra_y_ranges = {"watermark": watermarkrange} plot.sizing_mode = 'scale_width' + + plot.image_url([watermarkurl],1.8*max(thesecs),watermarky, watermarkw,watermarkh, global_alpha=watermarkalpha, @@ -2970,18 +2977,22 @@ def interactive_otwcpchart(powerdf,promember=0,rowername="",r=None,cpfit='data', y_range_name = "watermark", ) - plot.circle('Delta','CP',source=source,fill_color='red',size=15, + plot.circle('Deltaminutes','CP',source=source,fill_color='red',size=15, legend='Power Data') - plot.xaxis.axis_label = "Duration (seconds)" + plot.xaxis.axis_label = "Duration (minutes)" plot.yaxis.axis_label = "Power (W)" plot.y_range = Range1d(0,1.5*max(theavpower)) - plot.x_range = Range1d(1,2*max(thesecs)) + plot.x_range = Range1d(0.5*min(thesecs)/60.,2*max(thesecs)/60.) plot.legend.orientation = "vertical" if not title: title = "Critical Power for "+rowername plot.title.text = title + xaxis = plot.select(dict(type=Axis, layout="below"))[0] + xaxis.formatter = PrintfTickFormatter() + + hover = plot.select(dict(type=HoverTool)) hover.tooltips = OrderedDict([ diff --git a/rowers/templates/analysis.html b/rowers/templates/analysis.html index e70e4a42..12a5d364 100644 --- a/rowers/templates/analysis.html +++ b/rowers/templates/analysis.html @@ -84,6 +84,17 @@
Select workouts and make X-Y charts of averages over various metrics
+ +
+ + Analyse power vs piece duration to make predictions. +
- - Analyze your Concept2 ranking pieces over a date range and predict your pace on other pieces. -
-
- - Analyse power vs piece duration to make predictions. -
-Need to monitor a metric? Set up automatic alerting and see the reports for your workouts.
+
+ + Analyze your Concept2 ranking pieces over a date range and predict your pace on other pieces. +