Private
Public Access
1
0

first holoview chart

This commit is contained in:
Sander Roosendaal
2019-02-26 22:11:28 +01:00
parent 5ba0aee1dd
commit f538dc849e
13 changed files with 250 additions and 64 deletions

View File

@@ -0,0 +1,6 @@
{
"cells": [],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -20,11 +20,6 @@ from bokeh.palettes import Dark2_8 as palette
import itertools import itertools
from bokeh.plotting import figure, ColumnDataSource, Figure,curdoc from bokeh.plotting import figure, ColumnDataSource, Figure,curdoc
from bokeh.models import CustomJS,Slider, TextInput,BoxAnnotation from bokeh.models import CustomJS,Slider, TextInput,BoxAnnotation
try:
from bokeh.charts import Histogram,HeatMap,Area,BoxPlot,Bar
from bokeh.charts.attributes import CatAttr
except:
pass
from bokeh.resources import CDN,INLINE from bokeh.resources import CDN,INLINE
from bokeh.embed import components from bokeh.embed import components
@@ -60,6 +55,7 @@ import math
import numpy as np import numpy as np
import pandas as pd import pandas as pd
import holoviews as hv import holoviews as hv
from holoviews import opts
from pytz import timezone as tz,utc from pytz import timezone as tz,utc
from django.utils.timezone import get_current_timezone from django.utils.timezone import get_current_timezone
from django.utils.timezone import activate from django.utils.timezone import activate
@@ -85,17 +81,6 @@ from rowers.utils import lbstoN
from rowers.datautils import p0 from rowers.datautils import p0
import rowers.datautils as datautils import rowers.datautils as datautils
watermarkurl = "/static/img/logo7.png"
watermarksource = ColumnDataSource(dict(
url = [watermarkurl],))
watermarkrange = Range1d(start=0,end=1)
watermarkalpha = 0.6
watermarkx = 0.99
watermarky = 0.01
watermarkw = 184
watermarkh = 35
watermarkanchor = 'bottom_right'
def errorbar(fig, x, y, source=ColumnDataSource(), def errorbar(fig, x, y, source=ColumnDataSource(),
xerr=False, yerr=False, color='black', xerr=False, yerr=False, color='black',
@@ -204,6 +189,17 @@ def interactive_boxchart(datadf,fieldname,extratitle=''):
# add watermark # add watermark
watermarkurl = "/static/img/logo7.png"
watermarksource = ColumnDataSource(dict(
url = [watermarkurl],))
watermarkrange = Range1d(start=0,end=1)
watermarkalpha = 0.6
watermarkx = 0.99
watermarky = 0.01
watermarkw = 184
watermarkh = 35
watermarkanchor = 'bottom_right'
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
plot.extra_x_ranges = {"watermark": watermarkrange} plot.extra_x_ranges = {"watermark": watermarkrange}
@@ -320,21 +316,43 @@ def interactive_activitychart(workouts,startdate,enddate,stack='type'):
df.sort_values('date_sorting',inplace=True) df.sort_values('date_sorting',inplace=True)
df.to_csv('~/s/data.csv') hv.extension('bokeh')
p = hv.Bars(df,values='duration', table = hv.Table(df,[('date','Date'),('type','Workout Type')],[('duration','Duration')])
# label = CatAttr(columns=['date'], sort=False),
xlabel='Date', bars=table.to.bars(['date','type'],['duration'])
ylabel='Time', bars.opts(
title='Activity {d1} to {d2}'.format( opts.Bars(color=hv.Cycle('Category20'), show_legend=True, stacked=True,
tools=['hover'], width=600, xrotation=90))
p = hv.render(bars)
p.title.text = 'Activity {d1} to {d2}'.format(
d1 = startdate.strftime("%Y-%m-%d"), d1 = startdate.strftime("%Y-%m-%d"),
d2 = enddate.strftime("%Y-%m-%d"), d2 = enddate.strftime("%Y-%m-%d"),
), )
stack=stack, p.plot_width=350
plot_width=350, p.plot_height=250
plot_height=250, p.toolbar_location = None
toolbar_location = None,
)
# p = hv.Bars(df,values='duration',
# label = CatAttr(columns=['date'], sort=False),
# xlabel='Date',
# ylabel='Time',
# title='Activity {d1} to {d2}'.format(
# d1 = startdate.strftime("%Y-%m-%d"),
# d2 = enddate.strftime("%Y-%m-%d"),
# ),
# stack=stack,
# plot_width=350,
# plot_height=250,
# toolbar_location = None,
# )
# for legend in p.legend: # for legend in p.legend:
@@ -354,13 +372,7 @@ def interactive_activitychart(workouts,startdate,enddate,stack='type'):
#p.yaxis.axis_label = 'Minutes' #p.yaxis.axis_label = 'Minutes'
try: script,div = components(p)
p = renderer.get_plot(p).state
script, div = components(p)
except:
script = ''
div = ''
return script,div return script,div
def interactive_forcecurve(theworkouts,workstrokesonly=False): def interactive_forcecurve(theworkouts,workstrokesonly=False):
@@ -454,6 +466,17 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False):
toolbar_sticky=False) toolbar_sticky=False)
# add watermark # add watermark
watermarkurl = "/static/img/logo7.png"
watermarksource = ColumnDataSource(dict(
url = [watermarkurl],))
watermarkrange = Range1d(start=0,end=1)
watermarkalpha = 0.6
watermarkx = 0.99
watermarky = 0.01
watermarkw = 184
watermarkh = 35
watermarkanchor = 'bottom_right'
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
plot.extra_x_ranges = {"watermark": watermarkrange} plot.extra_x_ranges = {"watermark": watermarkrange}
plot.sizing_mode = 'scale_width' plot.sizing_mode = 'scale_width'
@@ -764,6 +787,17 @@ def fitnessmetric_chart(fitnessmetrics,user,workoutmode='rower'):
x_axis_type='datetime') x_axis_type='datetime')
# add watermark # add watermark
watermarkurl = "/static/img/logo7.png"
watermarksource = ColumnDataSource(dict(
url = [watermarkurl],))
watermarkrange = Range1d(start=0,end=1)
watermarkalpha = 0.6
watermarkx = 0.99
watermarky = 0.01
watermarkw = 184
watermarkh = 35
watermarkanchor = 'bottom_right'
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
plot.extra_x_ranges = {"watermark": watermarkrange} plot.extra_x_ranges = {"watermark": watermarkrange}
@@ -850,6 +884,17 @@ def interactive_histoall(theworkouts):
) )
# add watermark # add watermark
watermarkurl = "/static/img/logo7.png"
watermarksource = ColumnDataSource(dict(
url = [watermarkurl],))
watermarkrange = Range1d(start=0,end=1)
watermarkalpha = 0.6
watermarkx = 0.99
watermarky = 0.01
watermarkw = 184
watermarkh = 35
watermarkanchor = 'bottom_right'
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
plot.extra_x_ranges = {"watermark": watermarkrange} plot.extra_x_ranges = {"watermark": watermarkrange}
@@ -1599,6 +1644,17 @@ def interactive_otwcpchart(powerdf,promember=0,rowername=""):
toolbar_sticky=False) toolbar_sticky=False)
# add watermark # add watermark
watermarkurl = "/static/img/logo7.png"
watermarksource = ColumnDataSource(dict(
url = [watermarkurl],))
watermarkrange = Range1d(start=0,end=1)
watermarkalpha = 0.6
watermarkx = 0.99
watermarky = 0.01
watermarkw = 184
watermarkh = 35
watermarkanchor = 'bottom_right'
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
plot.sizing_mode = 'scale_width' plot.sizing_mode = 'scale_width'
@@ -1888,6 +1944,17 @@ def interactive_cpchart(rower,thedistances,thesecs,theavpower,
toolbar_sticky=False) toolbar_sticky=False)
# add watermark # add watermark
watermarkurl = "/static/img/logo7.png"
watermarksource = ColumnDataSource(dict(
url = [watermarkurl],))
watermarkrange = Range1d(start=0,end=1)
watermarkalpha = 0.6
watermarkx = 0.99
watermarky = 0.01
watermarkw = 184
watermarkh = 35
watermarkanchor = 'bottom_right'
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
plot.sizing_mode = 'scale_width' plot.sizing_mode = 'scale_width'
@@ -2195,6 +2262,17 @@ def interactive_chart(id=0,promember=0,intervaldata = {}):
tools=TOOLS) tools=TOOLS)
# add watermark # add watermark
watermarkurl = "/static/img/logo7.png"
watermarksource = ColumnDataSource(dict(
url = [watermarkurl],))
watermarkrange = Range1d(start=0,end=1)
watermarkalpha = 0.6
watermarkx = 0.99
watermarky = 0.01
watermarkw = 184
watermarkh = 35
watermarkanchor = 'bottom_right'
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
plot.extra_x_ranges = {"watermark": watermarkrange} plot.extra_x_ranges = {"watermark": watermarkrange}
@@ -2388,6 +2466,17 @@ def interactive_multiflex(datadf,xparam,yparam,groupby,extratitle='',
toolbar_sticky=False,plot_width=920) toolbar_sticky=False,plot_width=920)
# add watermark # add watermark
watermarkurl = "/static/img/logo7.png"
watermarksource = ColumnDataSource(dict(
url = [watermarkurl],))
watermarkrange = Range1d(start=0,end=1)
watermarkalpha = 0.6
watermarkx = 0.99
watermarky = 0.01
watermarkw = 184
watermarkh = 35
watermarkanchor = 'bottom_right'
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
plot.extra_x_ranges = {"watermark": watermarkrange} plot.extra_x_ranges = {"watermark": watermarkrange}
@@ -2617,6 +2706,17 @@ def interactive_cum_flex_chart2(theworkouts,promember=0,
toolbar_sticky=False) toolbar_sticky=False)
# add watermark # add watermark
watermarkurl = "/static/img/logo7.png"
watermarksource = ColumnDataSource(dict(
url = [watermarkurl],))
watermarkrange = Range1d(start=0,end=1)
watermarkalpha = 0.6
watermarkx = 0.99
watermarky = 0.01
watermarkw = 184
watermarkh = 35
watermarkanchor = 'bottom_right'
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
plot.extra_x_ranges = {"watermark": watermarkrange} plot.extra_x_ranges = {"watermark": watermarkrange}
plot.sizing_mode = 'scale_width' plot.sizing_mode = 'scale_width'
@@ -2847,6 +2947,19 @@ def interactive_flex_chart2(id=0,promember=0,
plottype='line', plottype='line',
workstrokesonly=False): workstrokesonly=False):
watermarkurl = "/static/img/logo7.png"
watermarksource = ColumnDataSource(dict(
url = [watermarkurl],))
watermarkrange = Range1d(start=0,end=1)
watermarkalpha = 0.6
watermarkx = 0.99
watermarky = 0.01
watermarkw = 184
watermarkh = 35
watermarkanchor = 'bottom_right'
#rowdata,row = dataprep.getrowdata_db(id=id) #rowdata,row = dataprep.getrowdata_db(id=id)
columns = [xparam,yparam1,yparam2, columns = [xparam,yparam1,yparam2,
'ftime','distance','fpace', 'ftime','distance','fpace',
@@ -3036,6 +3149,17 @@ def interactive_flex_chart2(id=0,promember=0,
# add watermark # add watermark
watermarkurl = "/static/img/logo7.png"
watermarksource = ColumnDataSource(dict(
url = [watermarkurl],))
watermarkrange = Range1d(start=0,end=1)
watermarkalpha = 0.6
watermarkx = 0.99
watermarky = 0.01
watermarkw = 184
watermarkh = 35
watermarkanchor = 'bottom_right'
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
plot.extra_x_ranges = {"watermark": watermarkrange} plot.extra_x_ranges = {"watermark": watermarkrange}
plot.sizing_mode = 'scale_width' plot.sizing_mode = 'scale_width'
@@ -3647,6 +3771,17 @@ def interactive_bar_chart(id=0,promember=0):
tools=TOOLS) tools=TOOLS)
# add watermark # add watermark
watermarkurl = "/static/img/logo7.png"
watermarksource = ColumnDataSource(dict(
url = [watermarkurl],))
watermarkrange = Range1d(start=0,end=1)
watermarkalpha = 0.6
watermarkx = 0.99
watermarky = 0.01
watermarkw = 184
watermarkh = 35
watermarkanchor = 'bottom_right'
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
plot.extra_x_ranges = {"watermark": watermarkrange} plot.extra_x_ranges = {"watermark": watermarkrange}
plot.sizing_mode = 'scale_width' plot.sizing_mode = 'scale_width'
@@ -3816,6 +3951,17 @@ def interactive_multiple_compare_chart(ids,xparam,yparam,plottype='line',
toolbar_sticky=False) toolbar_sticky=False)
# add watermark # add watermark
watermarkurl = "/static/img/logo7.png"
watermarksource = ColumnDataSource(dict(
url = [watermarkurl],))
watermarkrange = Range1d(start=0,end=1)
watermarkalpha = 0.6
watermarkx = 0.99
watermarky = 0.01
watermarkw = 184
watermarkh = 35
watermarkanchor = 'bottom_right'
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
plot.extra_x_ranges = {"watermark": watermarkrange} plot.extra_x_ranges = {"watermark": watermarkrange}
plot.sizing_mode = 'scale_width' plot.sizing_mode = 'scale_width'
@@ -4068,6 +4214,17 @@ def interactive_comparison_chart(id1=0,id2=0,xparam='distance',yparam='spm',
toolbar_sticky=False) toolbar_sticky=False)
# add watermark # add watermark
watermarkurl = "/static/img/logo7.png"
watermarksource = ColumnDataSource(dict(
url = [watermarkurl],))
watermarkrange = Range1d(start=0,end=1)
watermarkalpha = 0.6
watermarkx = 0.99
watermarky = 0.01
watermarkw = 184
watermarkh = 35
watermarkanchor = 'bottom_right'
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
plot.extra_x_ranges = {"watermark": watermarkrange} plot.extra_x_ranges = {"watermark": watermarkrange}
plot.sizing_mode = 'scale_width' plot.sizing_mode = 'scale_width'
@@ -4199,6 +4356,17 @@ def interactive_otw_advanced_pace_chart(id=0,promember=0):
toolbar_sticky=False) toolbar_sticky=False)
# add watermark # add watermark
watermarkurl = "/static/img/logo7.png"
watermarksource = ColumnDataSource(dict(
url = [watermarkurl],))
watermarkrange = Range1d(start=0,end=1)
watermarkalpha = 0.6
watermarkx = 0.99
watermarky = 0.01
watermarkw = 184
watermarkh = 35
watermarkanchor = 'bottom_right'
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
plot.extra_x_ranges = {"watermark": watermarkrange} plot.extra_x_ranges = {"watermark": watermarkrange}
plot.sizing_mode = 'scale_width' plot.sizing_mode = 'scale_width'

View File

@@ -57,7 +57,7 @@ def processattachment(rower, fileobj, title, uploadoptions,testing=False):
except AttributeError: except AttributeError:
filename = fileobj[6:] filename = fileobj[6:]
if testing: if testing:
print 'Attribute Error', filename print('Attribute Error', filename)
# test if file exists and is not empty # test if file exists and is not empty
@@ -66,11 +66,11 @@ def processattachment(rower, fileobj, title, uploadoptions,testing=False):
line = fop.readline() line = fop.readline()
except (IOError, UnicodeEncodeError): except (IOError, UnicodeEncodeError):
if testing: if testing:
print 'IOError',filename,'media/'+filename print('IOError',filename,'media/'+filename)
return 0 return 0
if testing: if testing:
print 'Creating workout from email' print('Creating workout from email')
# set user # set user
if rower.user.is_staff and 'username' in uploadoptions: if rower.user.is_staff and 'username' in uploadoptions:
@@ -102,7 +102,7 @@ def processattachment(rower, fileobj, title, uploadoptions,testing=False):
pass pass
if testing: if testing:
print 'Workout id = {workoutid}'.format(workoutid=workoutid) print('Workout id = {workoutid}'.format(workoutid=workoutid))
if workoutid[0]: if workoutid[0]:
link = settings.SITE_URL+reverse( link = settings.SITE_URL+reverse(
@@ -242,17 +242,17 @@ class Command(BaseCommand):
testing=testing testing=testing
) )
except: except:
print "Bad ZIP file" print("Bad ZIP file")
print attachment.document.name print(attachment.document.name)
else: else:
# move attachment and make workout # move attachment and make workout
if testing: if testing:
try: try:
print name print(name)
except UnicodeEncodeError: except UnicodeEncodeError:
print "Unicode Error" print("Unicode Error")
try: try:
print attachment.document print(attachment.document)
except UnicodeEncodeError: except UnicodeEncodeError:
pass pass

View File

@@ -73,7 +73,10 @@ def get_token(code):
secret=POLAR_CLIENT_SECRET secret=POLAR_CLIENT_SECRET
) )
headers = { 'Authorization': 'Basic %s' % base64.b64encode(auth_string) } try:
headers = { 'Authorization': 'Basic %s' % base64.b64encode(auth_string) }
except TypeError:
headers = { 'Authorization': 'Basic %s' % base64.b64encode(bytes(auth_string,'utf-8')) }
response = requests.post("https://polarremote.com/v2/oauth2/token", response = requests.post("https://polarremote.com/v2/oauth2/token",
data=post_data, data=post_data,
@@ -116,7 +119,10 @@ def get_polar_notifications():
secret=POLAR_CLIENT_SECRET secret=POLAR_CLIENT_SECRET
) )
headers = { 'Authorization': 'Basic %s' % base64.b64encode(auth_string) } try:
headers = { 'Authorization': 'Basic %s' % base64.b64encode(auth_string) }
except TypeError:
headers = { 'Authorization': 'Basic %s' % base64.b64encode(bytes(auth_string,'utf-8')) }
response = requests.get(url, headers=headers) response = requests.get(url, headers=headers)

View File

@@ -1657,7 +1657,10 @@ def handle_makeplot(f1, f2, t, hrdata, plotnr, imagename,
except IOError: except IOError:
row = rdata(f2 + '.gz', rower=rr) row = rdata(f2 + '.gz', rower=rr)
haspower = row.df[' Power (watts)'].mean() > 50 try:
haspower = row.df[' Power (watts)'].mean() > 50
except TypeError:
haspower = True
nr_rows = len(row.df) nr_rows = len(row.df)
if (plotnr in [1, 2, 4, 5, 8, 11, 9, 12]) and (nr_rows > 1200): if (plotnr in [1, 2, 4, 5, 8, 11, 9, 12]) and (nr_rows > 1200):

View File

@@ -11,8 +11,8 @@
{{ js_res | safe }} {{ js_res | safe }}
{{ css_res| safe }} {{ css_res| safe }}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script type="text/javascript" src="/static/js/bokeh-widgets-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>

View File

@@ -59,7 +59,7 @@
<ul class="main-content"> <ul class="main-content">
<li class="grid_2" style="min-height:200px;"> <li class="grid_2" style="min-height:200px;">
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script src="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>

View File

@@ -259,7 +259,7 @@ class SessionLinkTest(TestCase):
plannedsessionstuple = [] plannedsessionstuple = []
for ps in pss: for ps in pss:
sessiontpl = (ps.id,ps.__unicode__()) sessiontpl = (ps.id,ps.__str__())
plannedsessionstuple.append(sessiontpl) plannedsessionstuple.append(sessiontpl)
plannedsessionstuple = tuple(plannedsessionstuple) plannedsessionstuple = tuple(plannedsessionstuple)
@@ -270,7 +270,7 @@ class SessionLinkTest(TestCase):
choices = [] choices = []
for w in self.user_workouts: for w in self.user_workouts:
wtpl = (w.id,w.__unicode__()) wtpl = (w.id,w.__str__())
choices.append(wtpl) choices.append(wtpl)
workoutdata['choices'] = tuple(choices) workoutdata['choices'] = tuple(choices)

Binary file not shown.

View File

@@ -125,7 +125,7 @@ def uploadactivity(access_token,filename,description='',
name='Rowsandall.com workout'): name='Rowsandall.com workout'):
data_gz = BytesIO() data_gz = BytesIO()
with file(filename,'rb') as inF: with open(filename,'rb') as inF:
s = inF.read() s = inF.read()
with gzip.GzipFile(fileobj=data_gz,mode="w") as gzf: with gzip.GzipFile(fileobj=data_gz,mode="w") as gzf:
gzf.write(s) gzf.write(s)

View File

@@ -3442,7 +3442,7 @@ def cumstats(request,theuser=0,
fielddict.pop('workoutstate') fielddict.pop('workoutstate')
fielddict.pop('workoutid') fielddict.pop('workoutid')
for field,verbosename in fielddict.iteritems(): for field,verbosename in fielddict.items():
thedict = { thedict = {
'mean':datadf[field].mean(), 'mean':datadf[field].mean(),
'min': datadf[field].min(), 'min': datadf[field].min(),
@@ -3459,9 +3459,9 @@ def cumstats(request,theuser=0,
cor = datadf.corr(method='spearman') cor = datadf.corr(method='spearman')
cor.fillna(value=0,inplace=True) cor.fillna(value=0,inplace=True)
cordict = {} cordict = {}
for field1,verbosename in fielddict.iteritems(): for field1,verbosename in fielddict.items():
thedict = {} thedict = {}
for field2,verbosename in fielddict.iteritems(): for field2,verbosename in fielddict.items():
try: try:
thedict[field2] = cor.loc[field1,field2] thedict[field2] = cor.loc[field1,field2]
except KeyError: except KeyError:

View File

@@ -4586,10 +4586,13 @@ def workout_split_view(request,id=0):
url = reverse('workouts_view') url = reverse('workouts_view')
rowname = row.name rowname = row.name
if isinstance(rowname,unicode): try:
rowname = rowname.encode('utf8') if isinstance(rowname,unicode):
elif isinstance(rowname, str): rowname = rowname.encode('utf8')
rowname = rowname.decode('utf8') elif isinstance(rowname, str):
rowname = rowname.decode('utf8')
except:
pass
qdict = {'q':rowname} qdict = {'q':rowname}
url+='?'+urllib.urlencode(qdict) url+='?'+urllib.urlencode(qdict)

View File

@@ -29,8 +29,8 @@
<script src="/static/cookielaw/js/cookielaw.js"></script> <script src="/static/cookielaw/js/cookielaw.js"></script>
{% analytical_head_top %} {% analytical_head_top %}
<link rel="stylesheet" href="/static/css/bokeh-0.12.3.min.css" type="text/css" /> <link rel="stylesheet" href="http://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.css" type="text/css" />
<link rel="stylesheet" href="/static/css/bokeh-widgets-0.12.3.min.css" type="text/css" /> <link rel="stylesheet" href="http://cdn.pydata.org/bokeh/release/bokeh-widgets-1.0.4.min.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="/static/admin/css/forms.css"/> <link rel="stylesheet" type="text/css" href="/static/admin/css/forms.css"/>
<link rel="stylesheet" type="text/css" href="/static/admin/css/widgets.css"/> <link rel="stylesheet" type="text/css" href="/static/admin/css/widgets.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" > <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" >