added agegroupcp
This commit is contained in:
@@ -977,6 +977,255 @@ def googlemap_chart(lat,lon,name=""):
|
||||
|
||||
return [script,div]
|
||||
|
||||
def interactive_agegroupcpchart(age,normalized=False):
|
||||
durations = [1,4,30,60]
|
||||
distances = [100,500,1000,2000,5000,6000,10000,21097,42195]
|
||||
|
||||
fhduration = []
|
||||
fhpower = []
|
||||
|
||||
for distance in distances:
|
||||
worldclasspower = metrics.getagegrouprecord(
|
||||
age,
|
||||
sex='female',
|
||||
distance=distance,
|
||||
weightcategory='hwt'
|
||||
)
|
||||
velo = (worldclasspower/2.8)**(1./3.)
|
||||
try:
|
||||
duration = distance/velo
|
||||
fhduration.append(duration)
|
||||
fhpower.append(worldclasspower)
|
||||
except ZeroDivisionError:
|
||||
pass
|
||||
for duration in durations:
|
||||
worldclasspower = metrics.getagegrouprecord(
|
||||
age,
|
||||
sex='female',
|
||||
duration=duration,
|
||||
weightcategory='hwt'
|
||||
)
|
||||
try:
|
||||
velo = (worldclasspower/2.8)**(1./3.)
|
||||
distance = int(60*duration*velo)
|
||||
fhduration.append(60.*duration)
|
||||
fhpower.append(worldclasspower)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
flduration = []
|
||||
flpower = []
|
||||
|
||||
for distance in distances:
|
||||
worldclasspower = metrics.getagegrouprecord(
|
||||
age,
|
||||
sex='female',
|
||||
distance=distance,
|
||||
weightcategory='lwt'
|
||||
)
|
||||
velo = (worldclasspower/2.8)**(1./3.)
|
||||
try:
|
||||
duration = distance/velo
|
||||
flduration.append(duration)
|
||||
flpower.append(worldclasspower)
|
||||
except ZeroDivisionError:
|
||||
pass
|
||||
for duration in durations:
|
||||
worldclasspower = metrics.getagegrouprecord(
|
||||
age,
|
||||
sex='female',
|
||||
duration=duration,
|
||||
weightcategory='lwt'
|
||||
)
|
||||
try:
|
||||
velo = (worldclasspower/2.8)**(1./3.)
|
||||
distance = int(60*duration*velo)
|
||||
flduration.append(60.*duration)
|
||||
flpower.append(worldclasspower)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
mlduration = []
|
||||
mlpower = []
|
||||
|
||||
for distance in distances:
|
||||
worldclasspower = metrics.getagegrouprecord(
|
||||
age,
|
||||
sex='male',
|
||||
distance=distance,
|
||||
weightcategory='lwt'
|
||||
)
|
||||
velo = (worldclasspower/2.8)**(1./3.)
|
||||
try:
|
||||
duration = distance/velo
|
||||
mlduration.append(duration)
|
||||
mlpower.append(worldclasspower)
|
||||
except ZeroDivisionError:
|
||||
pass
|
||||
for duration in durations:
|
||||
worldclasspower = metrics.getagegrouprecord(
|
||||
age,
|
||||
sex='male',
|
||||
duration=duration,
|
||||
weightcategory='lwt'
|
||||
)
|
||||
try:
|
||||
velo = (worldclasspower/2.8)**(1./3.)
|
||||
distance = int(60*duration*velo)
|
||||
mlduration.append(60.*duration)
|
||||
mlpower.append(worldclasspower)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
|
||||
mhduration = []
|
||||
mhpower = []
|
||||
|
||||
for distance in distances:
|
||||
worldclasspower = metrics.getagegrouprecord(
|
||||
age,
|
||||
sex='male',
|
||||
distance=distance,
|
||||
weightcategory='hwt'
|
||||
)
|
||||
velo = (worldclasspower/2.8)**(1./3.)
|
||||
try:
|
||||
duration = distance/velo
|
||||
mhduration.append(duration)
|
||||
mhpower.append(worldclasspower)
|
||||
except ZeroDivisionError:
|
||||
pass
|
||||
for duration in durations:
|
||||
worldclasspower = metrics.getagegrouprecord(
|
||||
age,
|
||||
sex='male',
|
||||
duration=duration,
|
||||
weightcategory='hwt'
|
||||
)
|
||||
try:
|
||||
velo = (worldclasspower/2.8)**(1./3.)
|
||||
distance = int(60*duration*velo)
|
||||
mhduration.append(60.*duration)
|
||||
mhpower.append(worldclasspower)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
fitfunc = lambda pars,x: pars[0]/(1+(x/pars[2])) + pars[1]/(1+(x/pars[3]))
|
||||
errfunc = lambda pars,x,y: fitfunc(pars,x)-y
|
||||
|
||||
p0 = [500,350,10,8000]
|
||||
|
||||
# fitting WC data to three parameter CP model
|
||||
if len(fhduration)>=4:
|
||||
p1fh, success = optimize.leastsq(errfunc, p0[:],
|
||||
args = (fhduration,fhpower))
|
||||
else:
|
||||
p1fh = None
|
||||
|
||||
# fitting WC data to three parameter CP model
|
||||
if len(flduration)>=4:
|
||||
p1fl, success = optimize.leastsq(errfunc, p0[:],
|
||||
args = (flduration,flpower))
|
||||
else:
|
||||
p1fl = None
|
||||
|
||||
# fitting WC data to three parameter CP model
|
||||
if len(mlduration)>=4:
|
||||
p1ml, success = optimize.leastsq(errfunc, p0[:],
|
||||
args = (mlduration,mlpower))
|
||||
else:
|
||||
p1ml = None
|
||||
|
||||
if len(mhduration)>=4:
|
||||
p1mh, success = optimize.leastsq(errfunc, p0[:],
|
||||
args = (mhduration,mhpower))
|
||||
else:
|
||||
p1mh = None
|
||||
|
||||
fitt = pd.Series(10**(4*np.arange(100)/100.))
|
||||
|
||||
fitpowerfh = fitfunc(p1fh,fitt)
|
||||
fitpowerfl = fitfunc(p1fl,fitt)
|
||||
fitpowerml = fitfunc(p1ml,fitt)
|
||||
fitpowermh = fitfunc(p1mh,fitt)
|
||||
|
||||
if normalized:
|
||||
facfh = fitfunc(p1fh,60)
|
||||
facfl = fitfunc(p1fl,60)
|
||||
facml = fitfunc(p1ml,60)
|
||||
facmh = fitfunc(p1mh,60)
|
||||
fitpowerfh /= facfh
|
||||
fitpowerfl /= facfl
|
||||
fitpowermh /= facmh
|
||||
fitpowerml /= facml
|
||||
fhpower /= facfh
|
||||
flpower /= facfl
|
||||
mlpower /= facml
|
||||
mhpower /= facmh
|
||||
|
||||
|
||||
|
||||
source = ColumnDataSource(
|
||||
data = dict(
|
||||
duration = fitt,
|
||||
fitpowerfh = fitpowerfh,
|
||||
fitpowerfl = fitpowerfl,
|
||||
fitpowerml = fitpowerml,
|
||||
fitpowermh = fitpowermh,
|
||||
flduration = flduration,
|
||||
flpower = flpower,
|
||||
fhduration = fhduration,
|
||||
fhpower = fhpower,
|
||||
mlduration = mlduration,
|
||||
mlpower = mlpower,
|
||||
mhduration = mhduration,
|
||||
mhpower = mhpower,
|
||||
)
|
||||
)
|
||||
|
||||
x_axis_type = 'log'
|
||||
y_axis_type = 'linear'
|
||||
|
||||
plot = Figure(plot_width=900,x_axis_type=x_axis_type)
|
||||
|
||||
plot.line('duration','fitpowerfh',source=source,
|
||||
legend='Female HW',color='blue')
|
||||
plot.line('duration','fitpowerfl',source=source,
|
||||
legend='Female LW',color='red')
|
||||
|
||||
plot.line('duration','fitpowerml',source=source,
|
||||
legend='Male LW',color='green')
|
||||
|
||||
plot.line('duration','fitpowermh',source=source,
|
||||
legend='Male HW',color='orange')
|
||||
|
||||
|
||||
plot.circle('flduration','flpower',source=source,
|
||||
fill_color='red',size=15)
|
||||
|
||||
plot.circle('fhduration','fhpower',source=source,
|
||||
fill_color='blue',size=15)
|
||||
|
||||
plot.circle('mlduration','mlpower',source=source,
|
||||
fill_color='green',size=15)
|
||||
|
||||
plot.circle('mhduration','mhpower',source=source,
|
||||
fill_color='orange',size=15)
|
||||
|
||||
plot.title.text = 'age '+str(age)
|
||||
|
||||
plot.xaxis.axis_label = "Duration (seconds)"
|
||||
if normalized:
|
||||
plot.yaxis.axis_label = "Power (normalized)"
|
||||
else:
|
||||
plot.yaxis.axis_label = "Power (W)"
|
||||
|
||||
script,div = components(plot)
|
||||
|
||||
return script,div
|
||||
|
||||
|
||||
def interactive_otwcpchart(powerdf,promember=0):
|
||||
powerdf = powerdf[~(powerdf == 0).any(axis=1)]
|
||||
|
||||
47
rowers/templates/agegroupcp.html
Normal file
47
rowers/templates/agegroupcp.html
Normal file
@@ -0,0 +1,47 @@
|
||||
{% extends "base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load rowerfilters %}
|
||||
|
||||
{% block title %}Rowsandall {% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
|
||||
<script async="true" type="text/javascript">
|
||||
Bokeh.set_log_level("info");
|
||||
</script>
|
||||
|
||||
{{ interactiveplot |safe }}
|
||||
|
||||
<script>
|
||||
// Set things up to resize the plot on a window resize. You can play with
|
||||
// the arguments of resize_width_height() to change the plot's behavior.
|
||||
var plot_resize_setup = function () {
|
||||
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
|
||||
var plot = Bokeh.index[plotid];
|
||||
var plotresizer = function() {
|
||||
// arguments: use width, use height, maintain aspect ratio
|
||||
plot.resize_width_height(true, false, false);
|
||||
};
|
||||
window.addEventListener('resize', plotresizer);
|
||||
plotresizer();
|
||||
};
|
||||
window.addEventListener('load', plot_resize_setup);
|
||||
</script>
|
||||
<style>
|
||||
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
|
||||
html, body {height: 100%; margin:5px;}
|
||||
</style>
|
||||
|
||||
|
||||
<div id="workouts" class="grid_12 alpha">
|
||||
|
||||
|
||||
<h1>Interactive Plot</h1>
|
||||
|
||||
|
||||
{{ the_div|safe }}
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@@ -121,6 +121,8 @@ urlpatterns = [
|
||||
url(r'^400/$', TemplateView.as_view(template_name='400.html'),name='400'),
|
||||
url(r'^403/$', TemplateView.as_view(template_name='403.html'),name='403'),
|
||||
url(r'^imports/$', TemplateView.as_view(template_name='imports.html'), name='imports'),
|
||||
url(r'^agegroupcp/(?P<age>\d+)$',views.agegroupcpview),
|
||||
url(r'^agegroupcp/(?P<age>\d+)/(?P<normalize>\d+)$',views.agegroupcpview),
|
||||
url(r'^agegrouprecords/(?P<sex>\w+.*)/(?P<weightcategory>\w+.*)/(?P<distance>\d+)m$',
|
||||
views.agegrouprecordview),
|
||||
url(r'^agegrouprecords/(?P<sex>\w+.*)/(?P<weightcategory>\w+.*)/(?P<duration>\d+)min$',
|
||||
|
||||
@@ -11287,6 +11287,18 @@ def team_members_stats_view(request,id):
|
||||
|
||||
from rowers.models import C2WorldClassAgePerformance
|
||||
|
||||
def agegroupcpview(request,age,normalize=0):
|
||||
script,div = interactive_agegroupcpchart(age,normalized=normalize)
|
||||
|
||||
response = render(request,'agegroupcp.html',
|
||||
{
|
||||
'interactiveplot':script,
|
||||
'the_div':div,
|
||||
}
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
def agegrouprecordview(request,sex='male',weightcategory='hwt',
|
||||
distance=2000,duration=None):
|
||||
if not duration:
|
||||
|
||||
Reference in New Issue
Block a user