multi plot sort of functions
This commit is contained in:
@@ -8,6 +8,8 @@ from rowingdata import rowingdata as rrdata
|
|||||||
|
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
|
from bokeh.palettes import Dark2_8 as palette
|
||||||
|
import itertools
|
||||||
from bokeh.plotting import figure, ColumnDataSource, Figure,curdoc
|
from bokeh.plotting import figure, ColumnDataSource, Figure,curdoc
|
||||||
from bokeh.models import CustomJS,Slider
|
from bokeh.models import CustomJS,Slider
|
||||||
from bokeh.charts import Histogram,HeatMap
|
from bokeh.charts import Histogram,HeatMap
|
||||||
@@ -1579,7 +1581,8 @@ def interactive_bar_chart(id=0,promember=0):
|
|||||||
|
|
||||||
return [script,div]
|
return [script,div]
|
||||||
|
|
||||||
def interactive_multiple_compare_chart(ids,xparam,yparam,plottype='line'):
|
def interactive_multiple_compare_chart(ids,xparam,yparam,plottype='line',
|
||||||
|
promember=0):
|
||||||
columns = [xparam,yparam,
|
columns = [xparam,yparam,
|
||||||
'ftime','distance','fpace',
|
'ftime','distance','fpace',
|
||||||
'power','hr','spm',
|
'power','hr','spm',
|
||||||
@@ -1590,9 +1593,9 @@ def interactive_multiple_compare_chart(ids,xparam,yparam,plottype='line'):
|
|||||||
|
|
||||||
yparamname = axlabels[yparam]
|
yparamname = axlabels[yparam]
|
||||||
|
|
||||||
datadf = datadf[datadf[yparam] > 0]
|
#datadf = datadf[datadf[yparam] > 0]
|
||||||
|
|
||||||
datadf = datadf[datadf[xparam] > 0]
|
#datadf = datadf[datadf[xparam] > 0]
|
||||||
|
|
||||||
# check if dataframe not empty
|
# check if dataframe not empty
|
||||||
if datadf.empty:
|
if datadf.empty:
|
||||||
@@ -1617,15 +1620,63 @@ def interactive_multiple_compare_chart(ids,xparam,yparam,plottype='line'):
|
|||||||
else:
|
else:
|
||||||
TOOLS = 'pan,box_zoom,wheel_zoom,reset,tap,crosshair'
|
TOOLS = 'pan,box_zoom,wheel_zoom,reset,tap,crosshair'
|
||||||
|
|
||||||
|
if yparam == 'pace':
|
||||||
|
y_axis_type = 'datetime'
|
||||||
|
yaxmax = 90.
|
||||||
|
yaxmin = 150.
|
||||||
|
|
||||||
|
if xparam == 'time':
|
||||||
|
x_axis_type = 'datetime'
|
||||||
|
|
||||||
|
if xparam != 'time':
|
||||||
|
xvals = xaxmin+np.arange(100)*(xaxmax-xaxmin)/100.
|
||||||
|
else:
|
||||||
|
xvals = np.arange(100)
|
||||||
|
|
||||||
plot = Figure(x_axis_type=x_axis_type,y_axis_type=y_axis_type,
|
plot = Figure(x_axis_type=x_axis_type,y_axis_type=y_axis_type,
|
||||||
tools=TOOLS,
|
tools=TOOLS,
|
||||||
toolbar_location="above",
|
toolbar_location="above",
|
||||||
toolbar_sticky=False)
|
toolbar_sticky=False)
|
||||||
|
|
||||||
|
colors = itertools.cycle(palette)
|
||||||
|
|
||||||
for key,grp in datadf.groupby(['workoutid']):
|
for id,color in itertools.izip(ids,colors):
|
||||||
print key
|
group = datadf[datadf['workoutid']==int(id)].copy()
|
||||||
|
group.sort_values(by='time',ascending=True,inplace=True)
|
||||||
|
group['x'] = group[xparam]
|
||||||
|
group['y'] = group[yparam]
|
||||||
|
source = ColumnDataSource(
|
||||||
|
group
|
||||||
|
)
|
||||||
|
plot.line('x','y',source=source,color=color,legend=str(id))
|
||||||
|
|
||||||
|
plot.legend.location='top_left'
|
||||||
|
plot.xaxis.axis_label = axlabels[xparam]
|
||||||
|
plot.yaxis.axis_label = axlabels[yparam]
|
||||||
|
|
||||||
|
if (xparam != 'time') and (xparam != 'distance') and (xparam != 'cumdist'):
|
||||||
|
xrange1 = Range1d(start=yaxminima[xparam],end=yaxmaxima[xparam])
|
||||||
|
plot.x_range = xrange1
|
||||||
|
|
||||||
|
if xparam == 'time':
|
||||||
|
xrange1 = Range1d(start=xaxmin,end=xaxmax)
|
||||||
|
plot.x_range = xrange1
|
||||||
|
plot.xaxis[0].formatter = DatetimeTickFormatter(
|
||||||
|
hours = ["%H"],
|
||||||
|
minutes = ["%M"],
|
||||||
|
seconds = ["%S"],
|
||||||
|
days = ["0"],
|
||||||
|
months = [""],
|
||||||
|
years = [""]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if yparam == 'pace':
|
||||||
|
plot.yaxis[0].formatter = DatetimeTickFormatter(
|
||||||
|
seconds = ["%S"],
|
||||||
|
minutes = ["%M"]
|
||||||
|
)
|
||||||
|
|
||||||
script, div = components(plot)
|
script, div = components(plot)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
49
rowers/templates/multicompare.html
Normal file
49
rowers/templates/multicompare.html
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block title %}View Comparison {% 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 Comparison</h1>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="theplot" class="grid_12 alpha flexplot">
|
||||||
|
{{ the_div|safe }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@@ -2046,6 +2046,13 @@ def team_comparison_select(request,
|
|||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
def multi_compare_view(request):
|
def multi_compare_view(request):
|
||||||
|
promember=0
|
||||||
|
if not request.user.is_anonymous():
|
||||||
|
r = Rower.objects.get(user=request.user)
|
||||||
|
result = request.user.is_authenticated() and ispromember(request.user)
|
||||||
|
if result:
|
||||||
|
promember=1
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = WorkoutMultipleCompareForm(request.POST)
|
form = WorkoutMultipleCompareForm(request.POST)
|
||||||
chartform = ChartParamChoiceForm(request.POST)
|
chartform = ChartParamChoiceForm(request.POST)
|
||||||
@@ -2055,8 +2062,15 @@ def multi_compare_view(request):
|
|||||||
xparam = chartform.cleaned_data['xparam']
|
xparam = chartform.cleaned_data['xparam']
|
||||||
yparam = chartform.cleaned_data['yparam']
|
yparam = chartform.cleaned_data['yparam']
|
||||||
ids = [w.id for w in workouts]
|
ids = [w.id for w in workouts]
|
||||||
res = interactive_multiple_compare_chart(ids,xparam,yparam)
|
res = interactive_multiple_compare_chart(ids,xparam,yparam,
|
||||||
return HttpResponse("Form is valid")
|
promember=promember)
|
||||||
|
script = res[0]
|
||||||
|
div = res[1]
|
||||||
|
return render(request,'multicompare.html',
|
||||||
|
{'interactiveplot':script,
|
||||||
|
'the_div':div,
|
||||||
|
'promember':promember,
|
||||||
|
})
|
||||||
else:
|
else:
|
||||||
return HttpResponse("Form is not valid")
|
return HttpResponse("Form is not valid")
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user