added agegroupcp
This commit is contained in:
@@ -977,6 +977,255 @@ def googlemap_chart(lat,lon,name=""):
|
|||||||
|
|
||||||
return [script,div]
|
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):
|
def interactive_otwcpchart(powerdf,promember=0):
|
||||||
powerdf = powerdf[~(powerdf == 0).any(axis=1)]
|
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'^400/$', TemplateView.as_view(template_name='400.html'),name='400'),
|
||||||
url(r'^403/$', TemplateView.as_view(template_name='403.html'),name='403'),
|
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'^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$',
|
url(r'^agegrouprecords/(?P<sex>\w+.*)/(?P<weightcategory>\w+.*)/(?P<distance>\d+)m$',
|
||||||
views.agegrouprecordview),
|
views.agegrouprecordview),
|
||||||
url(r'^agegrouprecords/(?P<sex>\w+.*)/(?P<weightcategory>\w+.*)/(?P<duration>\d+)min$',
|
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
|
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',
|
def agegrouprecordview(request,sex='male',weightcategory='hwt',
|
||||||
distance=2000,duration=None):
|
distance=2000,duration=None):
|
||||||
if not duration:
|
if not duration:
|
||||||
|
|||||||
Reference in New Issue
Block a user