Private
Public Access
1
0

added agegroupcp

This commit is contained in:
Sander Roosendaal
2017-12-14 16:35:26 +01:00
parent 03eec117a6
commit 7616220da1
4 changed files with 310 additions and 0 deletions

View File

@@ -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)]

View 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 %}

View File

@@ -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$',

View File

@@ -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: