from __future__ import absolute_import from __future__ import division from __future__ import print_function from __future__ import unicode_literals import colorsys from rowers.models import ( Workout, User, Rower, WorkoutForm,RowerForm, GraphImage,GeoPolygon,GeoCourse,GeoPoint ) from rowingdata import rower as rrower from rowingdata import main as rmain from rowingdata import cumcpdata,histodata from rowingdata import rowingdata as rrdata from math import pi from django.utils import timezone from rowingdata import make_cumvalues from bokeh.palettes import Dark2_8 as palette from bokeh.models.glyphs import MultiLine import itertools from bokeh.plotting import figure, ColumnDataSource, Figure,curdoc from bokeh.models import CustomJS,Slider, TextInput,BoxAnnotation from bokeh.resources import CDN,INLINE from bokeh.embed import components from bokeh.layouts import layout,widgetbox from bokeh.palettes import Category20c,Category10 from bokeh.layouts import row as layoutrow from bokeh.layouts import column as layoutcolumn from bokeh.models import LinearAxis,LogAxis,Range1d,DatetimeTickFormatter,HoverTool #from bokeh.io import output_file, show, vplot from bokeh.models import ( GMapPlot, GMapOptions, ColumnDataSource, Circle, DataRange1d, PanTool, WheelZoomTool, BoxSelectTool, SaveTool, # ResizeTool, ResetTool, TapTool,CrosshairTool,BoxZoomTool, Span, Label ) from bokeh.transform import cumsum from bokeh.models.glyphs import ImageURL from bokeh.models import OpenURL, TapTool from rowers.opaque import encoder #from bokeh.models.widgets import Slider, Select, TextInput from bokeh.core.properties import value from collections import OrderedDict from django.conf import settings from rowers.courses import ( course_coord_center,course_coord_maxmin, polygon_coord_center ) from rowers import mytypes from rowers.models import course_spline import datetime import math import numpy as np import pandas as pd import holoviews as hv from holoviews import opts from pytz import timezone as tz,utc from django.utils.timezone import get_current_timezone from django.utils.timezone import activate from django.utils import timezone activate(settings.TIME_ZONE) thetimezone = get_current_timezone() from scipy.stats import linregress,percentileofscore from scipy.spatial import ConvexHull,Delaunay from scipy import optimize from scipy.signal import savgol_filter from scipy.interpolate import griddata import rowers.stravastuff as stravastuff from rowers.dataprep import rdata import rowers.dataprep as dataprep import rowers.metrics as metrics import rowers.c2stuff as c2stuff from rowers.metrics import axes,axlabels,yaxminima,yaxmaxima from rowers.utils import lbstoN from rowers.datautils import p0 import rowers.datautils as datautils def errorbar(fig, x, y, source=ColumnDataSource(), xerr=False, yerr=False, color='black', point_kwargs={}, error_kwargs={}): xvalues = source.data[x] yvalues = source.data[y] xerrvalues = source.data['xerror'] yerrvalues = source.data['yerror'] try: colorvalues = source.data['color'] except KeyError: colorvalues = ["#%02x%02x%02x" % (255,0,0) for x in xvalues] try: a = xvalues[0]+1 if xerr: x_err_x = [] x_err_y = [] err_color = [] for px, py, err, color in zip(xvalues, yvalues, xerrvalues, colorvalues): x_err_x.append((px - err, px + err)) x_err_y.append((py, py)) (r, g, b) = tuple(int(color[i:i+2],16) for i in (1, 3, 5)) h,s,v = colorsys.rgb_to_hsv(r/255., g/255., b/255.) v = v*0.8 r, g, b = colorsys.hsv_to_rgb(h, s, v) color2 = "#%02x%02x%02x" % (int(255.*r), int(255.*g), int(255*b)) err_color.append(color2) fig.multi_line(x_err_x, x_err_y, color=err_color, name='xerr', **error_kwargs) except TypeError: pass try: a = yvalues[0]+1 if yerr: y_err_x = [] y_err_y = [] err_color = [] for px, py, err, color in zip(xvalues, yvalues, yerrvalues, colorvalues): y_err_x.append((px, px)) y_err_y.append((py - err, py + err)) (r, g, b) = tuple(int(color[i:i+2],16) for i in (1, 3, 5)) h,s,v = colorsys.rgb_to_hsv(r/255., g/255., b/255.) v = v*0.8 r, g, b = colorsys.hsv_to_rgb(h, s, v) color2 = "#%02x%02x%02x" % (int(255.*r), int(255.*g), int(255*b)) err_color.append(color2) fig.multi_line(y_err_x, y_err_y, color=err_color, name='yerr',**error_kwargs) except TypeError: pass fig.circle(x, y, source=source, name='data',color=color, **point_kwargs) def tailwind(bearing,vwind,winddir): """ Calculates head-on head/tailwind in direction of rowing positive numbers are tail wind """ b = np.radians(bearing) w = np.radians(winddir) vtail = -vwind*np.cos(w-b) return vtail from rowers.dataprep import nicepaceformat,niceformat from rowers.dataprep import timedeltaconv from math import pi def interactive_hr_piechart(df,rower,title,totalseconds=0): if df.empty: return "","Not enough data to make a chart" df.sort_values(by='hr',inplace=True) df['timehr'] = df['deltat']*df['hr'] sumtimehr = df['deltat'].sum() if totalseconds == 0: totalseconds = sumtimehr qry = 'hr < {ut2}'.format(ut2=rower.ut2) qrydata = df.query(qry) frac_lut2 = totalseconds*qrydata['deltat'].sum()/sumtimehr qry = '{ut2} <= hr < {ut1}'.format(ut1=rower.ut1,ut2=rower.ut2) frac_ut2 = totalseconds*df.query(qry)['deltat'].sum()/sumtimehr qry = '{ut1} <= hr < {at}'.format(ut1=rower.ut1,at=rower.at) frac_ut1 = totalseconds*df.query(qry)['deltat'].sum()/sumtimehr qry = '{at} <= hr < {tr}'.format(at=rower.at,tr=rower.tr) frac_at = totalseconds*df.query(qry)['deltat'].sum()/sumtimehr qry = '{tr} <= hr < {an}'.format(tr=rower.tr,an=rower.an) frac_tr = totalseconds*df.query(qry)['deltat'].sum()/sumtimehr qry = 'hr >= {an}'.format(an=rower.an) frac_an = totalseconds*df.query(qry)['deltat'].sum()/sumtimehr datadict = { ' yaxmaximum: yaxmaximum = data['planned'].max() if yaxmaximum == 0: yaxmaximum = 250 yrange1 = Range1d(start=0,end=1.1*yaxmaximum) tidy_df = data.melt(id_vars=['startdate'],value_vars=['executed','planned']) bars = hv.Bars(tidy_df,['startdate','variable'],['value']) bars.opts( opts.Bars(show_legend=True,tools=['tap','hover'],legend_position='bottom',show_frame=True)) p = hv.render(bars) p.plot_width=550 p.plot_height=350 p.y_range = yrange1 p.toolbar_location = 'above' p.sizing_mode = 'scale_width' script,div = components(p) return script,div def interactive_activitychart(workouts,startdate,enddate,stack='type',toolbar_location=None, yaxis='trimp'): dates = [] dates_sorting = [] types = [] rowers = [] durations = [] rscores = [] trimps = [] links = [] rowersinitials = {} seen = ['seen'] idseen = [] startdate = datetime.datetime(year=startdate.year,month=startdate.month,day=startdate.day) enddate = datetime.datetime(year=enddate.year,month=enddate.month,day=enddate.day) duration = enddate-startdate totaldays = duration.total_seconds()/(24*3600) for w in workouts: aantal=1 initials = w.user.user.first_name[0:aantal]+w.user.user.last_name[0:aantal] if w.user.id not in idseen: while initials in seen: aantal += 1 initials = w.user.user.first_name[0:aantal]+w.user.user.last_name[0:aantal] seen.append(initials) idseen.append(w.user.id) rowersinitials[w.user.id] = initials for w in workouts: dd = w.date.strftime('%m/%d') dd2 = w.date.strftime('%Y/%m/%d') dd3 = w.date.strftime('%Y/%m') du = w.duration.hour*60+w.duration.minute rscore = w.rscore trimp = w.trimp if rscore == 0: rscore = w.hrtss if totaldays<30: dates.append(dd) dates_sorting.append(dd2) else: dates.append(dd3) dates_sorting.append(dd3) durations.append(du) rscores.append(rscore) trimps.append(trimp) links.append( "{siteurl}/rowers/workout/{code}/".format( siteurl = settings.SITE_URL, code = encoder.encode_hex(w.id) ) ) types.append(w.workouttype) try: rowers.append(rowersinitials[w.user.id]) except IndexError: rowers.append(str(w.user)) try: d = utc.localize(startdate) except (ValueError,AttributeError): d = startdate try: enddate = utc.localize(enddate) except (ValueError,AttributeError): pass # add dates with no activity while d<=enddate: dd = d.strftime('%d') if totaldays<30: dates.append(d.strftime('%m/%d')) dates_sorting.append(d.strftime('%Y/%m/%d')) else: dates.append(d.strftime('%Y/%m')) dates_sorting.append(d.strftime('%Y/%m')) durations.append(0) rscores.append(0) trimps.append(0) links.append('') types.append('rower') try: rowers.append(rowers[0]) except IndexError: try: rowers.append(str(workouts[0].user)) except IndexError: rowers.append(' ') d += datetime.timedelta(days=1) thedict = { 'date':dates, 'date_sorting':dates_sorting, 'duration':durations, 'trimp':trimps, 'rscore':rscores, 'type':types, 'rower':rowers, 'link':links, } dim_expr = hv.dim('type').categorize(mytypes.color_map) df = pd.DataFrame(thedict) source = ColumnDataSource(df) df.sort_values('date_sorting',inplace=True) #clrs = hv.Cycle(df['colors'].values) hv.extension('bokeh') if stack == 'type': table = hv.Table(df,[('date','Date'),('type','Workout Type')], [('duration','Minutes'),('rscore','rScore'),('trimp','TRIMP'),('link','link')]) else: table = hv.Table(df,[('date','Date'),('rower','Rower')], [('duration','Minutes'),('rscore','rScore'),('trimp','TRIMP'),('link','link')]) bars=table.to.bars(['date',stack],[yaxis]) bars.opts( opts.Bars(color=hv.Cycle('Category10'), show_legend=True, stacked=True, tools=['tap','hover'], width=550, xrotation=45,padding=(0,(0,.1)), legend_position='bottom',show_frame=True)) p = hv.render(bars) p.title.text = 'Activity {d1} to {d2}'.format( d1 = startdate.strftime("%Y-%m-%d"), d2 = enddate.strftime("%Y-%m-%d"), ) p.plot_width=550 p.plot_height=350 p.toolbar_location = toolbar_location p.y_range.start = 0 p.sizing_mode = 'scale_width' url = "http://rowsandall.com/rowers/workout/@duration/" taptool = p.select(type=TapTool) callback = CustomJS(args={'links':df.link}, code=""" var index = cb_data.source.selected['1d'].indices[0]; console.log(links); console.log(index); console.log(links[index]); window.location.href = links[index] """) taptool.callback = callback script,div = components(p) return script,div def interactive_activitychart2(workouts,startdate,enddate,stack='type',toolbar_location=None, yaxis='duration'): dates = [] dates_sorting = [] types = [] rowers = [] durations = [] rscores = [] trimps = [] links = [] rowersinitials = {} seen = ['seen'] idseen = [] startdate = datetime.datetime(year=startdate.year,month=startdate.month,day=startdate.day) enddate = datetime.datetime(year=enddate.year,month=enddate.month,day=enddate.day) duration = enddate-startdate totaldays = duration.total_seconds()/(24*3600) for w in workouts: aantal=1 initials = w.user.user.first_name[0:aantal]+w.user.user.last_name[0:aantal] if w.user.id not in idseen: while initials in seen: aantal += 1 initials = w.user.user.first_name[0:aantal]+w.user.user.last_name[0:aantal] seen.append(initials) idseen.append(w.user.id) rowersinitials[w.user.id] = initials for w in workouts: dd = w.date.strftime('%m/%d') dd2 = w.date.strftime('%Y/%m/%d') dd3 = w.date.strftime('%Y/%m') du = w.duration.hour*60+w.duration.minute trimp = w.trimp rscore = w.rscore if rscore == 0: rscore = w.hrtss if totaldays<30: dates.append(dd) dates_sorting.append(dd2) else: dates.append(dd3) dates_sorting.append(dd3) durations.append(du) trimps.append(trimp) rscores.append(rscore) links.append( "{siteurl}/rowers/workout/{code}/".format( siteurl = settings.SITE_URL, code = encoder.encode_hex(w.id) ) ) types.append(w.workouttype) try: rowers.append(rowersinitials[w.user.id]) except IndexError: rowers.append(str(w.user)) try: d = utc.localize(startdate) except (ValueError,AttributeError): d = startdate try: enddate = utc.localize(enddate) except (ValueError,AttributeError): pass # add dates with no activity while d<=enddate: dd = d.strftime('%d') if totaldays<30: dates.append(d.strftime('%m/%d')) dates_sorting.append(d.strftime('%Y/%m/%d')) else: dates.append(d.strftime('%Y/%m')) dates_sorting.append(d.strftime('%Y/%m')) durations.append(0) trimps.append(0) rscores.append(0) links.append('') types.append('rower') try: rowers.append(rowers[0]) except IndexError: try: rowers.append(str(workouts[0].user)) except IndexError: rowers.append(' ') d += datetime.timedelta(days=1) thedict = { 'date':dates, 'date_sorting':dates_sorting, 'duration':durations, 'trimp':trimps, 'rscore':rscores, 'type':types, 'rower':rowers, 'link':links, } dim_expr = hv.dim('type').categorize(mytypes.color_map) df = pd.DataFrame(thedict) source = ColumnDataSource(df) df.sort_values('date_sorting',inplace=True) #clrs = hv.Cycle(df['colors'].values) hv.extension('bokeh') table = hv.Table(df,[('date','Date'),('type','Workout Type')], [('duration','Minutes'),('trimp','TRIMP'),('rscore','rScore'),('link','link')]) bars=table.to.bars(['date',stack],[yaxis]) bars.opts( opts.Bars(color=dim_expr, show_legend=True, stacked=True, tools=['tap','hover'], width=550, xrotation=45,padding=(0,(0,.1)), legend_position='bottom',show_frame=True)) p = hv.render(bars) p.title.text = 'Activity {d1} to {d2}'.format( d1 = startdate.strftime("%Y-%m-%d"), d2 = enddate.strftime("%Y-%m-%d"), ) p.plot_width=550 p.plot_height=350 p.toolbar_location = toolbar_location p.sizing_mode = 'scale_width' p.y_range.start = 0 url = "http://rowsandall.com/rowers/workout/@duration/" taptool = p.select(type=TapTool) callback = CustomJS(args={'links':df.link}, code=""" var index = cb_data.source.selected['1d'].indices[0]; console.log(links); console.log(index); console.log(links[index]); window.location.href = links[index] """) taptool.callback = callback script,div = components(p) return script,div def interactive_forcecurve(theworkouts,workstrokesonly=True,plottype='scatter'): TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' ids = [int(w.id) for w in theworkouts] boattype = theworkouts[0].boattype columns = ['catch','slip','wash','finish','averageforce', 'peakforceangle','peakforce','spm','distance', 'workoutstate','driveenergy'] rowdata = dataprep.getsmallrowdata_db(columns,ids=ids, workstrokesonly=workstrokesonly) rowdata.dropna(axis=1,how='all',inplace=True) rowdata.dropna(axis=0,how='any',inplace=True) workoutstateswork = [1,4,5,8,9,6,7] workoutstatesrest = [3] workoutstatetransition = [0,2,10,11,12,13] if workstrokesonly: try: rowdata = rowdata[~rowdata['workoutstate'].isin(workoutstatesrest)] except KeyError: pass if rowdata.empty: return "","No Valid Data Available","","" # quick linear regression # peakforce = slope*peakforceangle + intercept try: slope, intercept, r,p,stderr = linregress(rowdata['peakforceangle'],rowdata['peakforce']) except KeyError: slope = 0 intercept = 0 try: covariancematrix = np.cov(rowdata['peakforceangle'],y=rowdata['peakforce']) eig_vals, eig_vecs = np.linalg.eig(covariancematrix) a = rowdata['peakforceangle']-rowdata['peakforceangle'].median() F = rowdata['peakforce']-rowdata['peakforce'].median() Rinv = eig_vecs R = np.linalg.inv(Rinv) x = R[0,0]*a+R[0,1]*F y = R[1,0]*a+R[1,1]*F x05 = x.quantile(q=0.01) x25 = x.quantile(q=0.15) x75 = x.quantile(q=0.85) x95 = x.quantile(q=0.99) y05 = y.quantile(q=0.01) y25 = y.quantile(q=0.15) y75 = y.quantile(q=0.85) y95 = y.quantile(q=0.99) a25 = Rinv[0,0]*x25 + rowdata['peakforceangle'].median() F25 = Rinv[1,0]*x25 + rowdata['peakforce'].median() a25b = Rinv[0,1]*y25 + rowdata['peakforceangle'].median() F25b = Rinv[1,1]*y25 + rowdata['peakforce'].median() a75 = Rinv[0,0]*x75 + rowdata['peakforceangle'].median() F75 = Rinv[1,0]*x75 + rowdata['peakforce'].median() a75b = Rinv[0,1]*y75 + rowdata['peakforceangle'].median() F75b = Rinv[1,1]*y75 + rowdata['peakforce'].median() a05 = Rinv[0,0]*x05 + rowdata['peakforceangle'].median() F05 = Rinv[1,0]*x05 + rowdata['peakforce'].median() a05b = Rinv[0,1]*y05 + rowdata['peakforceangle'].median() F05b = Rinv[1,1]*y05 + rowdata['peakforce'].median() a95 = Rinv[0,0]*x95 + rowdata['peakforceangle'].median() F95 = Rinv[1,0]*x95 + rowdata['peakforce'].median() a95b = Rinv[0,1]*y95 + rowdata['peakforceangle'].median() F95b = Rinv[1,1]*y95 + rowdata['peakforce'].median() except KeyError: a25 = 0 F25 = 0 a25b = 0 F25b = 0 a75 = 0 F75 = 0 a75b = 0 F75b = 0 a05 = 0 F05 = 0 a05b = 0 F05b = 0 a95 = 0 F95 = 0 a95b = 0 F95b = 0 try: catchav = rowdata['catch'].median() catch25 = rowdata['catch'].quantile(q=0.25) catch75 = rowdata['catch'].quantile(q=0.75) catch05 = rowdata['catch'].quantile(q=0.05) catch95 = rowdata['catch'].quantile(q=0.95) except KeyError: catchav = 0 catch25 = 0 catch75 = 0 catch05 = 0 catch95 = 0 try: finishav = rowdata['finish'].median() finish25 = rowdata['finish'].quantile(q=0.25) finish75 = rowdata['finish'].quantile(q=0.75) finish05 = rowdata['finish'].quantile(q=0.05) finish95 = rowdata['finish'].quantile(q=0.95) except KeyError: finishav = 0 finish25 = 0 finish75 = 0 finish05 = 0 finish95 = 0 try: washav = (rowdata['finish']-rowdata['wash']).median() wash25 = (rowdata['finish']-rowdata['wash']).quantile(q=0.25) wash75 = (rowdata['finish']-rowdata['wash']).quantile(q=0.75) wash05 = (rowdata['finish']-rowdata['wash']).quantile(q=0.05) wash95 = (rowdata['finish']-rowdata['wash']).quantile(q=0.95) except KeyError: washav = 0 wash25 = 0 wash75 = 0 wash05 = 0 wash95 = 0 try: slipav = (rowdata['slip']+rowdata['catch']).median() slip25 = (rowdata['slip']+rowdata['catch']).quantile(q=0.25) slip75 = (rowdata['slip']+rowdata['catch']).quantile(q=0.75) slip05 = (rowdata['slip']+rowdata['catch']).quantile(q=0.05) slip95 = (rowdata['slip']+rowdata['catch']).quantile(q=0.95) except KeyError: slipav = 0 slip25 = 0 slip75 = 0 slip05 = 0 slip95 = 0 try: peakforceav = rowdata['peakforce'].median() peakforce25 = rowdata['peakforce'].quantile(q=0.25) peakforce75 = rowdata['peakforce'].quantile(q=0.75) peakforce05 = rowdata['peakforce'].quantile(q=0.05) peakforce95 = rowdata['peakforce'].quantile(q=0.95) except KeyError: peakforceav = 0 peakforce25 = 0 peakforce75 = 0 peakforce05 = 0 peakforce95 = 0 try: averageforceav = rowdata['averageforce'].median() except KeyError: averageforceav = 0 try: peakforceangleav = rowdata['peakforceangle'].median() peakforceangle05 = rowdata['peakforceangle'].quantile(q=0.05) peakforceangle25 = rowdata['peakforceangle'].quantile(q=0.25) peakforceangle75 = rowdata['peakforceangle'].quantile(q=0.75) peakforceangle95 = rowdata['peakforceangle'].quantile(q=0.95) except KeyError: peakforceangleav = 0 peakforceangle25 = 0 peakforceangle75 = 0 peakforceangle05 = 0 peakforceangle95 = 0 #thresholdforce /= 4.45 # N to lbs thresholdforce = 100 if 'x' in boattype else 200 points2575 = [ (catch25,0), #0 (slip25,thresholdforce), #1 (a75,F75),#4 (a25b,F25b), #9 (a25,F25), #2 (wash75,thresholdforce), #5 (finish75,0), #6 (finish25,0), #7 (wash25,thresholdforce), #8 (a75b,F75b), #3 (slip75,thresholdforce), #10 (catch75,0), #11 ] points0595 = [ (catch05,0), #0 (slip05,thresholdforce), #1 (a95,F95),#4 (a05b,F05b), #9 (a05,F05), #2 (wash95,thresholdforce), #5 (finish95,0), #6 (finish05,0), #7 (wash05,thresholdforce), #8 (a95b,F95b), #3 (slip95,thresholdforce), #10 (catch95,0), #11 ] angles2575 = [] forces2575 = [] for x,y in points2575: angles2575.append(x) forces2575.append(y) angles0595 = [] forces0595 = [] for x,y in points0595: angles0595.append(x) forces0595.append(y) x = [catchav, slipav, peakforceangleav, washav, finishav] y = [0,thresholdforce, peakforceav, thresholdforce,0] source = ColumnDataSource( data = dict( x = x, y = y, )) sourceslipwash = ColumnDataSource( data = dict( xslip = [slipav,washav], yslip = [thresholdforce,thresholdforce] ) ) sourcetrend = ColumnDataSource( data = dict( x = [peakforceangle25,peakforceangle75], y = [peakforce25,peakforce75] ) ) sourcefit = ColumnDataSource( data = dict( x = np.array([peakforceangle25,peakforceangle75]), y = slope*np.array([peakforceangle25,peakforceangle75])+intercept ) ) source2 = ColumnDataSource( rowdata ) if plottype == 'scatter': try: sourcepoints = ColumnDataSource( data = dict( peakforceangle = rowdata['peakforceangle'], peakforce = rowdata['peakforce'] ) ) except KeyError: sourcepoints = ColumnDataSource( data = dict( peakforceangle = [], peakforce = [] ) ) else: sourcepoints = ColumnDataSource( data = dict( peakforceangle = [], peakforce = [] )) sourcerange = ColumnDataSource( data = dict( x2575 = angles2575, y2575 = forces2575, x0595 = angles0595, y0595 = forces0595, ) ) plot = Figure(tools=TOOLS, toolbar_sticky=False,toolbar_location="above") # 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_x_ranges = {"watermark": watermarkrange} plot.sizing_mode = 'scale_width' plot.image_url([watermarkurl],watermarkx,watermarky, watermarkw,watermarkh, global_alpha=watermarkalpha, w_units='screen', h_units='screen', anchor=watermarkanchor, dilate=True, x_range_name = "watermark", y_range_name = "watermark", ) avf = Span(location=averageforceav,dimension='width',line_color='blue', line_dash=[6,6],line_width=2) plot.patch('x0595','y0595',source=sourcerange,color="red",alpha=0.05) plot.patch('x2575','y2575',source=sourcerange,color="red",alpha=0.2) plot.line('x','y',source=source,color="red") plot.circle('xslip','yslip',source=sourceslipwash,color="red") plot.circle('peakforceangle','peakforce',source=sourcepoints,color='black',alpha=0.1) if plottype == 'line': multilinedatax = [] multilinedatay = [] for i in range(len(rowdata)): try: x = [ rowdata['catch'].values[i], rowdata['slip'].values[i]+rowdata['catch'].values[i], rowdata['peakforceangle'].values[i], rowdata['finish'].values[i]-rowdata['wash'].values[i], rowdata['finish'].values[i] ] y = [ 0, thresholdforce, rowdata['peakforce'].values[i], thresholdforce, 0] except KeyError: x = [0,0] y = [0,0] multilinedatax.append(x) multilinedatay.append(y) sourcemultiline = ColumnDataSource(dict( x=multilinedatax, y=multilinedatay, )) sourcemultiline2 = ColumnDataSource(dict( x=multilinedatax, y=multilinedatay, )) glyph = MultiLine(xs='x',ys='y',line_color='black',line_alpha=0.05) plot.add_glyph(sourcemultiline,glyph) else: sourcemultiline = ColumnDataSource(dict( x=[],y=[])) sourcemultiline2 = ColumnDataSource(dict( x=[],y=[])) plot.line('x','y',source=source,color="red") plot.add_layout(avf) peakflabel = Label(x=410,y=460,x_units='screen',y_units='screen', text="Fpeak: {peakforceav:6.2f}".format(peakforceav=peakforceav), background_fill_alpha=.7, background_fill_color='white', text_color='blue', ) avflabel = Label(x=420,y=430,x_units='screen',y_units='screen', text="Favg: {averageforceav:6.2f}".format(averageforceav=averageforceav), background_fill_alpha=.7, background_fill_color='white', text_color='blue', ) catchlabel = Label(x=415,y=400,x_units='screen',y_units='screen', text="Catch: {catchav:6.2f}".format(catchav=catchav), background_fill_alpha=0.7, background_fill_color='white', text_color='red', ) peakforceanglelabel = Label(x=375,y=370,x_units='screen',y_units='screen', text="Peak angle: {peakforceangleav:6.2f}".format(peakforceangleav=peakforceangleav), background_fill_alpha=0.7, background_fill_color='white', text_color='red', ) finishlabel = Label(x=410,y=340,x_units='screen',y_units='screen', text="Finish: {finishav:6.2f}".format(finishav=finishav), background_fill_alpha=0.7, background_fill_color='white', text_color='red', ) sliplabel = Label(x=425,y=310,x_units='screen',y_units='screen', text="Slip: {slipav:6.2f}".format(slipav=slipav-catchav), background_fill_alpha=0.7, background_fill_color='white', text_color='red', ) washlabel = Label(x=415,y=280,x_units='screen',y_units='screen', text="Wash: {washav:6.2f}".format(washav=finishav-washav), background_fill_alpha=0.7, background_fill_color='white', text_color='red', ) lengthlabel = Label(x=405,y=250, x_units='screen',y_units='screen', text="Length: {length:6.2f}".format(length=finishav-catchav), background_fill_alpha=0.7, background_fill_color='white', text_color='green' ) efflengthlabel = Label(x=340,y=220, x_units='screen',y_units='screen', text="Effective Length: {length:6.2f}".format(length=washav-slipav), background_fill_alpha=0.7, background_fill_color='white', text_color='green' ) annolabel = Label(x=50,y=450,x_units='screen',y_units='screen', text='', background_fill_alpha=0.7, background_fill_color='white', text_color='black', ) sliderlabel = Label(x=10,y=470,x_units='screen',y_units='screen', text='', background_fill_alpha=0.7, background_fill_color='white', text_color='black',text_font_size='10pt', ) plot.add_layout(peakflabel) plot.add_layout(peakforceanglelabel) plot.add_layout(avflabel) plot.add_layout(catchlabel) plot.add_layout(sliplabel) plot.add_layout(washlabel) plot.add_layout(finishlabel) plot.add_layout(annolabel) plot.add_layout(sliderlabel) plot.add_layout(lengthlabel) plot.add_layout(efflengthlabel) plot.xaxis.axis_label = "Angle" plot.yaxis.axis_label = "Force (N)" plot.title.text = theworkouts[0].name plot.title.text_font_size=value("1.0em") yrange1 = Range1d(start=0,end=900) plot.y_range = yrange1 xrange1 = Range1d(start=yaxmaxima['catch'],end=yaxmaxima['finish']) plot.x_range = xrange1 callback = CustomJS(args = dict( source=source, source2=source2, sourceslipwash=sourceslipwash, sourcepoints=sourcepoints, avf=avf, avflabel=avflabel, catchlabel=catchlabel, finishlabel=finishlabel, sliplabel=sliplabel, washlabel=washlabel, peakflabel=peakflabel, peakforceanglelabel=peakforceanglelabel, annolabel=annolabel, sliderlabel=sliderlabel, lengthlabel=lengthlabel, efflengthlabel=efflengthlabel, plottype=plottype, sourcemultiline=sourcemultiline, sourcemultiline2=sourcemultiline2 ), code=""" var data = source.data var data2 = source2.data var dataslipwash = sourceslipwash.data var datapoints = sourcepoints.data var multilines = sourcemultiline.data var multilines2 = sourcemultiline2.data var plottype = plottype var multilinesx = multilines2['x'] var multilinesy = multilines2['y'] var x = data['x'] var y = data['y'] var xslip = dataslipwash['xslip'] var spm1 = data2['spm'] var distance1 = data2['distance'] var driveenergy1 = data2['driveenergy'] var thresholdforce = y[1] var c = source2.data['catch'] var finish = data2['finish'] var slip = data2['slip'] var wash = data2['wash'] var peakforceangle = data2['peakforceangle'] var peakforce = data2['peakforce'] var averageforce = data2['averageforce'] var peakforcepoints = datapoints['peakforce'] var peakforceanglepoints = datapoints['peakforceangle'] var annotation = annotation.value var minspm = minspm.value var maxspm = maxspm.value var mindist = mindist.value var maxdist = maxdist.value var minwork = minwork.value var maxwork = maxwork.value sliderlabel.text = 'SPM: '+minspm.toFixed(0)+'-'+maxspm.toFixed(0) sliderlabel.text += ', Dist: '+mindist.toFixed(0)+'-'+maxdist.toFixed(0) sliderlabel.text += ', WpS: '+minwork.toFixed(0)+'-'+maxwork.toFixed(0) var catchav = 0 var finishav = 0 var slipav = 0 var washav = 0 var peakforceangleav = 0 var averageforceav = 0 var peakforceav = 0 var count = 0 datapoints['peakforceangle'] = [] datapoints['peakforce'] = [] multilines['x'] = [] multilines['y'] = [] for (i=0; i=minspm && spm1[i]<=maxspm) { if (distance1[i]>=mindist && distance1[i]<=maxdist) { if (driveenergy1[i]>=minwork && driveenergy1[i]<=maxwork) { if (plottype=='scatter') { datapoints['peakforceangle'].push(peakforceangle[i]) datapoints['peakforce'].push(peakforce[i]) } if (plottype=='line') { multilines['x'].push(multilinesx[i]) multilines['y'].push(multilinesy[i]) } catchav += c[i] finishav += finish[i] slipav += slip[i] washav += wash[i] peakforceangleav += peakforceangle[i] averageforceav += averageforce[i] peakforceav += peakforce[i] count += 1 } } } } catchav /= count finishav /= count slipav /= count washav /= count peakforceangleav /= count peakforceav /= count averageforceav /= count data['x'] = [catchav,catchav+slipav,peakforceangleav,finishav-washav,finishav] data['y'] = [0,thresholdforce,peakforceav,thresholdforce,0] dataslipwash['xslip'] = [catchav+slipav,finishav-washav] dataslipwash['yslip'] = [thresholdforce,thresholdforce] var length = finishav-catchav var efflength = length-slipav-washav avf.location = averageforceav avflabel.text = 'Favg: '+averageforceav.toFixed(2) catchlabel.text = 'Catch: '+catchav.toFixed(2) finishlabel.text = 'Finish: '+finishav.toFixed(2) sliplabel.text = 'Slip: '+slipav.toFixed(2) washlabel.text = 'Wash: '+washav.toFixed(2) peakflabel.text = 'Fpeak: '+peakforceav.toFixed(2) peakforceanglelabel.text = 'Peak angle: '+peakforceangleav.toFixed(2) annolabel.text = annotation lengthlabel.text = 'Length: '+length.toFixed(2) efflengthlabel.text = 'Effective Length: '+efflength.toFixed(2) console.log(count); console.log(multilines['x'].length); console.log(multilines['y'].length); // source.trigger('change'); source.change.emit(); sourceslipwash.change.emit() sourcepoints.change.emit(); sourcemultiline.change.emit(); """) annotation = TextInput(title="Type your plot notes here", value="", callback=callback) callback.args["annotation"] = annotation slider_spm_min = Slider(start=15.0, end=55,value=15.0, step=.1, title="Min SPM",callback=callback) callback.args["minspm"] = slider_spm_min slider_spm_max = Slider(start=15.0, end=55,value=55.0, step=.1, title="Max SPM",callback=callback) callback.args["maxspm"] = slider_spm_max slider_work_min = Slider(start=0, end=1500,value=0, step=10, title="Min Work per Stroke",callback=callback) callback.args["minwork"] = slider_work_min slider_work_max = Slider(start=0, end=1500,value=1500, step=10, title="Max Work per Stroke",callback=callback) callback.args["maxwork"] = slider_work_max distmax = 100+100*int(rowdata['distance'].max()/100.) slider_dist_min = Slider(start=0,end=distmax,value=0,step=50, title="Min Distance",callback=callback) callback.args["mindist"] = slider_dist_min slider_dist_max = Slider(start=0,end=distmax,value=distmax, step=50, title="Max Distance",callback=callback) callback.args["maxdist"] = slider_dist_max layout = layoutrow([layoutcolumn([annotation, slider_spm_min, slider_spm_max, slider_dist_min, slider_dist_max, slider_work_min, slider_work_max, ], ), plot]) layout.sizing_mode = 'scale_width' script, div = components(layout) js_resources = INLINE.render_js() css_resources = INLINE.render_css() return [script,div,js_resources,css_resources] def fitnessmetric_chart(fitnessmetrics,user,workoutmode='rower',startdate=None, enddate=None): power4min = [int(m.PowerFourMin) for m in fitnessmetrics] power2k = [int(m.PowerTwoK) for m in fitnessmetrics] power1hr = [int(m.PowerOneHour) for m in fitnessmetrics] dates = [m.date for m in fitnessmetrics] mode = [m.workoutmode for m in fitnessmetrics] if len(power4min) == 0: return ['',''] df = pd.DataFrame( {'power4min':power4min, 'power2k':power2k, 'power1hr':power1hr, 'date':dates, 'dates':dates, 'mode':mode }) delta = df['power4min'].astype('int').diff() mask = delta == 0 df.loc[mask,'power4min'] = np.nan df.dropna(inplace=True,axis=0,how='any') df = df[df['power2k']>0] try: df = df[df['mode']==workoutmode] except TypeError: df = pd.DataFrame() if df.empty: return ["","no data"] groups = df.groupby(by='date').max() power4min = groups['power4min'] date = groups['dates'] power2k = groups['power2k'] power1hr = groups['power1hr'] source = ColumnDataSource( data = dict( power4min = power4min, power2k = power2k, date = date, power1hr = power1hr, fdate=groups['dates'].map(lambda x: x.strftime('%Y-%m-%d')) ) ) # fit resampled = groups.set_index('dates') resampled.index = pd.to_datetime(resampled.index) resampled = resampled.resample('D').interpolate( method='linear',order=2) power4min = resampled['power4min'] date = resampled.index.values power2k = resampled['power2k'] power1hr = resampled['power1hr'] source2 = ColumnDataSource( data = dict( power4min = power4min, power2k = power2k, date = date, power1hr = power1hr, fdate=resampled.index.map(lambda x: x.strftime('%d-%m-%Y')) ) ) TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' plot = Figure(tools=TOOLS,toolbar_location="above", toolbar_sticky=False,width=900, x_axis_type='datetime') # 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_x_ranges = {"watermark": watermarkrange} plot.image_url([watermarkurl],watermarkx,watermarky, watermarkw,watermarkh, global_alpha=watermarkalpha, w_units='screen', h_units='screen', anchor=watermarkanchor, dilate=True, x_range_name = "watermark", y_range_name = "watermark", ) plot.circle('date','power2k',source=source,fill_color='red',size=10, legend='2k power') plot.circle('date','power1hr',source=source,fill_color='blue',size=10, legend='1 hr power') plot.circle('date','power4min',source=source,fill_color='green',size=10, legend='4 min power') plot.line('date','power4min',source=source2,color='green') plot.line('date','power2k',source=source2,color='red') plot.line('date','power1hr',source=source2,color='blue') plot.xaxis.axis_label = 'Date' plot.yaxis.axis_label = 'Power (W)' plot.xaxis.formatter = DatetimeTickFormatter( days=["%d %B %Y"], months=["%d %B %Y"], years=["%d %B %Y"], ) plot.xaxis.major_label_orientation = pi/4 plot.sizing_mode = 'scale_width' plot.y_range = Range1d(0,1.5*max(power4min)) if not startdate: startdate = min(date) if not enddate: enddate = max(date) plot.x_range = Range1d( startdate,enddate, ) plot.title.text = 'Power levels ('+workoutmode+') from workouts '+user.first_name hover = plot.select(dict(type=HoverTool)) hover.tooltips = OrderedDict([ ('Power 4 minutes','@power4min'), ('Power 2000 m','@power2k'), ('Power 1 hour','@power1hr'), ('Date','@fdate'), ]) script,div = components(plot) return [script,div] def interactive_histoall(theworkouts,histoparam,includereststrokes, spmmin=0,spmmax=55, workmin=0,workmax=1500): TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' ids = [int(w.id) for w in theworkouts] workstrokesonly = not includereststrokes rowdata = dataprep.getsmallrowdata_db([histoparam],ids=ids,doclean=True,workstrokesonly=workstrokesonly) rowdata.dropna(axis=0,how='any',inplace=True) rowdata = dataprep.filter_df(rowdata,'spm',spmmin,largerthan=True) rowdata = dataprep.filter_df(rowdata,'spm',spmmax,largerthan=False) rowdata = dataprep.filter_df(rowdata,'driveenergy',workmin,largerthan=True) rowdata = dataprep.filter_df(rowdata,'driveenergy',workmax,largerthan=False) if rowdata.empty: return "","No Valid Data Available" try: histopwr = rowdata[histoparam].values except KeyError: return "","No data" if len(histopwr) == 0: return "","No valid data available" # throw out nans histopwr = histopwr[~np.isinf(histopwr)] histopwr = histopwr[histopwr > yaxminima[histoparam]] histopwr = histopwr[histopwr < yaxmaxima[histoparam]] plot = Figure(tools=TOOLS,plot_width=900, toolbar_sticky=False, toolbar_location="above" ) # 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_x_ranges = {"watermark": watermarkrange} plot.image_url([watermarkurl],watermarkx,watermarky, watermarkw,watermarkh, global_alpha=watermarkalpha, w_units='screen', h_units='screen', anchor=watermarkanchor, dilate=True, x_range_name = "watermark", y_range_name = "watermark", ) hist,edges = np.histogram(histopwr,bins=150) histsum = np.cumsum(hist) histsum = 100.*histsum/max(histsum) hist_norm = 100.*hist/float(hist.sum()) source = ColumnDataSource( data = dict( left = edges[:-1], right = edges[1:], histsum = histsum, hist_norm = hist_norm, ) ) # plot.quad(top='hist_norm',bottom=0,left=edges[:-1],right=edges[1:]) plot.quad(top='hist_norm',bottom=0,left='left',right='right',source=source) plot.xaxis.axis_label = axlabels[histoparam] plot.yaxis.axis_label = "% of strokes" plot.y_range = Range1d(0,1.05*max(hist_norm)) hover = plot.select(dict(type=HoverTool)) hover.tooltips = OrderedDict([ (axlabels[histoparam],'@left{int}'), ('% of strokes','@hist_norm'), ('Cumulative %','@histsum{int}'), ]) hover.mode = 'mouse' plot.extra_y_ranges["fraction"] = Range1d(start=0,end=105) plot.line('right','histsum',source=source,color="red", y_range_name="fraction") plot.add_layout(LinearAxis(y_range_name="fraction", axis_label="Cumulative % of strokes"),'right') plot.sizing_mode = 'scale_width' annolabel = Label(x=50,y=450,x_units='screen',y_units='screen', text='', background_fill_alpha=0.7, background_fill_color='white', text_color='black', ) plot.add_layout(annolabel) callback = CustomJS(args = dict( annolabel=annolabel, ), code=""" var annotation = annotation.value annolabel.text = annotation """) annotation = TextInput(title="Type your plot notes here", value="", callback=callback) callback.args["annotation"] = annotation layout = layoutcolumn([annotation,plot]) try: script, div = components(layout) except ValueError: script = '' div = '' return [script,div] def course_map(course): latmean,lonmean,coordinates = course_coord_center(course) lat_min, lat_max, long_min, long_max = course_coord_maxmin(course) coordinates = course_spline(coordinates) scoordinates = "[" for index,row in coordinates.iterrows(): scoordinates += """[{x},{y}], """.format( x=row['latitude'], y=row['longitude'] ) scoordinates +="]" polygons = GeoPolygon.objects.filter(course=course).order_by("order_in_course") plabels = '' for p in polygons: coords = polygon_coord_center(p) plabels += """ var marker = L.marker([{latbegin}, {longbegin}]).addTo(mymap); marker.bindPopup("{name}"); """.format( latbegin = coords[0], longbegin = coords[1], name = p.name ) pcoordinates = """[ """ for p in polygons: pcoordinates += """[ [""" points = GeoPoint.objects.filter(polygon=p).order_by("order_in_poly") for pt in points: pcoordinates += "[{x},{y}],".format( x = pt.latitude, y = pt.longitude ) # remove last comma pcoordinates = pcoordinates[:-1] pcoordinates += """] ], """ pcoordinates += """ ]""" script = """ """.format( latmean=latmean, lonmean=lonmean, scoordinates=scoordinates, pcoordinates=pcoordinates, plabels = plabels ) div = """
""" return script,div def leaflet_chart(lat,lon,name=""): if lat.empty or lon.empty: return [0,"invalid coordinate data"] # Throw out 0,0 df = pd.DataFrame({ 'lat':lat, 'lon':lon }) df = df.replace(0,np.nan) df = df.loc[(df!=0).any(axis=1)] df.fillna(method='bfill',axis=0,inplace=True) df.fillna(method='ffill',axis=0,inplace=True) lat = df['lat'] lon = df['lon'] if lat.empty or lon.empty: return [0,"invalid coordinate data"] latmean = lat.mean() lonmean = lon.mean() latbegin = lat[lat.index[0]] longbegin = lon[lon.index[0]] latend = lat[lat.index[-1]] longend = lon[lon.index[-1]] coordinates = zip(lat,lon) scoordinates = "[" for x,y in coordinates: scoordinates += """[{x},{y}], """.format( x=x, y=y ) scoordinates += "]" script = """ """.format( latmean=latmean, lonmean=lonmean, latbegin = latbegin, latend=latend, longbegin=longbegin, longend=longend, scoordinates=scoordinates, ) div = """

 

""" return script,div def leaflet_chart_compare(course,workoutids,labeldict={},startenddict={}): data = [] for id in workoutids: if id != 0 and id is not None: try: w = Workout.objects.get(id=id) rowdata = rdata(w.csvfilename) time = rowdata.df['TimeStamp (sec)'] df = pd.DataFrame({ 'workoutid':id, 'lat':rowdata.df[' latitude'], 'lon':rowdata.df[' longitude'], 'time':time-time[0], }) data.append(df) except (Workout.DoesNotExist,KeyError): pass df = pd.concat(data,axis=0) latmean,lonmean,coordinates = course_coord_center(course) lat_min, lat_max, long_min, long_max = course_coord_maxmin(course) coordinates = course_spline(coordinates) polygons = GeoPolygon.objects.filter(course=course).order_by("order_in_course") plabels = '' for p in polygons: coords = polygon_coord_center(p) plabels += """ var marker = L.marker([{latbegin}, {longbegin}]).addTo(mymap); marker.bindPopup("{name}"); """.format( latbegin = coords[0], longbegin = coords[1], name = p.name ) pcoordinates = """[ """ for p in polygons: pcoordinates += """[ [""" points = GeoPoint.objects.filter(polygon=p).order_by("order_in_poly") for pt in points: pcoordinates += "[{x},{y}],".format( x = pt.latitude, y = pt.longitude ) # remove last comma pcoordinates = pcoordinates[:-1] pcoordinates += """] ], """ pcoordinates += """ ]""" # Throw out 0,0 df = df.replace(0,np.nan) df = df.loc[(df!=0).any(axis=1)] df.fillna(method='bfill',axis=0,inplace=True) df.fillna(method='ffill',axis=0,inplace=True) lat = df['lat'] lon = df['lon'] if lat.empty or lon.empty: return [0,"invalid coordinate data"] latbegin = lat.values[0] longbegin = lon.values[0] latend = lat.values[-1] longend = lon.values[-1] colors = itertools.cycle(palette) try: items = itertools.izip(workoutids,colors) except AttributeError: items = zip(workoutids,colors) script = """ """ div = """

 

""" return script,div def leaflet_chart2(lat,lon,name=""): if lat.empty or lon.empty: return [0,"invalid coordinate data"] # Throw out 0,0 df = pd.DataFrame({ 'lat':lat, 'lon':lon }) df = df.replace(0,np.nan) df = df.loc[(df!=0).any(axis=1)] df.fillna(method='bfill',axis=0,inplace=True) df.fillna(method='ffill',axis=0,inplace=True) lat = df['lat'] lon = df['lon'] if lat.empty or lon.empty: return [0,"invalid coordinate data"] latmean = lat.mean() lonmean = lon.mean() latbegin = lat[lat.index[0]] longbegin = lon[lon.index[0]] latend = lat[lat.index[-1]] longend = lon[lon.index[-1]] coordinates = zip(lat,lon) scoordinates = "[" for x,y in coordinates: scoordinates += """[{x},{y}], """.format( x=x, y=y ) scoordinates += "]" script = """ """.format( latmean=latmean, lonmean=lonmean, latbegin = latbegin, latend=latend, longbegin=longbegin, longend=longend, scoordinates=scoordinates, ) div = """

 

""" return script,div def leaflet_chart_video(lat,lon,name=""): if not len(lat) or not len(lon): return [0,"invalid coordinate data"] # Throw out 0,0 df = pd.DataFrame({ 'lat':lat, 'lon':lon }) df = df.replace(0,np.nan) df = df.loc[(df!=0).any(axis=1)] df.fillna(method='bfill',axis=0,inplace=True) df.fillna(method='ffill',axis=0,inplace=True) lat = df['lat'] lon = df['lon'] if lat.empty or lon.empty: return [0,"invalid coordinate data"] latmean = lat.mean() lonmean = lon.mean() latbegin = lat[lat.index[0]] longbegin = lon[lon.index[0]] latend = lat[lat.index[-1]] longend = lon[lon.index[-1]] coordinates = zip(lat,lon) scoordinates = "[" for x,y in coordinates: scoordinates += """[{x},{y}], """.format( x=x, y=y ) scoordinates += "]" script = """ var streets = L.tileLayer( 'https://api.mapbox.com/styles/v1/{{id}}/tiles/{{z}}/{{x}}/{{y}}?access_token={{accessToken}}', {{ attribution: '© Mapbox © OpenStreetMap Improve this map', tileSize: 512, maxZoom: 18, zoomOffset: -1, id: 'mapbox/streets-v11', accessToken: 'pk.eyJ1Ijoic2FuZGVycm9vc2VuZGFhbCIsImEiOiJjajY3aTRkeWQwNmx6MzJvMTN3andlcnBlIn0.MFG8Xt0kDeSA9j7puZQ9hA' }} ), satellite = L.tileLayer( 'https://api.mapbox.com/styles/v1/{{id}}/tiles/{{z}}/{{x}}/{{y}}?access_token={{accessToken}}', {{ attribution: '© Mapbox © OpenStreetMap Improve this map', tileSize: 512, maxZoom: 18, zoomOffset: -1, id: 'mapbox/satellite-v9', accessToken: 'pk.eyJ1Ijoic2FuZGVycm9vc2VuZGFhbCIsImEiOiJjajY3aTRkeWQwNmx6MzJvMTN3andlcnBlIn0.MFG8Xt0kDeSA9j7puZQ9hA' }} ), outdoors = L.tileLayer( 'https://api.mapbox.com/styles/v1/{{id}}/tiles/{{z}}/{{x}}/{{y}}?access_token={{accessToken}}', {{ attribution: '© Mapbox © OpenStreetMap Improve this map', tileSize: 512, maxZoom: 18, zoomOffset: -1, id: 'mapbox/outdoors-v11', accessToken: 'pk.eyJ1Ijoic2FuZGVycm9vc2VuZGFhbCIsImEiOiJjajY3aTRkeWQwNmx6MzJvMTN3andlcnBlIn0.MFG8Xt0kDeSA9j7puZQ9hA' }} ); var mymap = L.map('map_canvas', {{ center: [{latmean}, {lonmean}], zoom: 13, layers: [streets, satellite] }}).setView([{latmean},{lonmean}], 13); var navionics = new JNC.Leaflet.NavionicsOverlay({{ navKey: 'Navionics_webapi_03205', chartType: JNC.NAVIONICS_CHARTS.NAUTICAL, isTransparent: true, zIndex: 1 }}); var osmUrl2='http://tiles.openseamap.org/seamark/{{z}}/{{x}}/{{y}}.png'; var osmUrl='http://{{s}}.tile.openstreetmap.org/{{z}}/{{x}}/{{y}}.png'; //create two TileLayer var nautical=new L.TileLayer(osmUrl,{{ maxZoom:18}}); L.control.layers({{ "Streets": streets, "Satellite": satellite, "Outdoors": outdoors, "Nautical": nautical, }},{{ "Navionics":navionics, }}, {{ position:'topleft' }}).addTo(mymap); var marker = L.marker([{latbegin}, {longbegin}]).addTo(mymap); marker.bindPopup("Start"); var latlongs = {scoordinates} var polyline = L.polyline(latlongs, {{color:'red'}}).addTo(mymap) mymap.fitBounds(polyline.getBounds()) """.format( latmean=latmean, lonmean=lonmean, latbegin = latbegin, latend=latend, longbegin=longbegin, longend=longend, scoordinates=scoordinates, ) 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 = c2stuff.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 = c2stuff.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 = c2stuff.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 = c2stuff.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 = c2stuff.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 = c2stuff.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 = c2stuff.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 = c2stuff.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' TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' plot = Figure(plot_width=900,x_axis_type=x_axis_type, tools=TOOLS) plot.sizing_mode = 'scale_width' 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,rowername=""): powerdf = powerdf[~(powerdf == 0).any(axis=1)] # plot tools if (promember==1): TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' else: TOOLS = 'pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' x_axis_type = 'log' y_axis_type = 'linear' deltas = powerdf['Delta'].apply(lambda x: timedeltaconv(x)) powerdf['ftime'] = niceformat(deltas) source = ColumnDataSource( data = powerdf ) # there is no Paul's law for OTW thesecs = powerdf['Delta'] theavpower = powerdf['CP'] p1,fitt,fitpower,ratio = datautils.cpfit(powerdf) message = "" #if len(fitpower[fitpower<0]) > 0: # message = "CP model fit didn't give correct results" deltas = fitt.apply(lambda x: timedeltaconv(x)) ftime = niceformat(deltas) sourcecomplex = ColumnDataSource( data = dict( CP = fitpower, CPmax = ratio*fitpower, duration = fitt, ftime = ftime ) ) # making the plot plot = Figure(tools=TOOLS,x_axis_type=x_axis_type, plot_width=900, toolbar_location="above", toolbar_sticky=False) # 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.sizing_mode = 'scale_width' plot.image_url([watermarkurl],1.8*max(thesecs),watermarky, watermarkw,watermarkh, global_alpha=watermarkalpha, w_units='screen', h_units='screen', anchor=watermarkanchor, dilate=True, y_range_name = "watermark", ) plot.circle('Delta','CP',source=source,fill_color='red',size=15, legend='Power Data') plot.xaxis.axis_label = "Duration (seconds)" plot.yaxis.axis_label = "Power (W)" plot.y_range = Range1d(0,1.5*max(theavpower)) plot.x_range = Range1d(1,2*max(thesecs)) plot.legend.orientation = "vertical" plot.title.text = "Critical Power for "+rowername hover = plot.select(dict(type=HoverTool)) hover.tooltips = OrderedDict([ ('Duration ','@ftime'), ('Power (W)','@CP{int}'), ('Power (W) upper','@CPmax{int}'), ]) hover.mode = 'mouse' plot.line('duration','CP',source=sourcecomplex,legend="CP Model", color='green') plot.line('duration','CPmax',source=sourcecomplex,legend="CP Model", color='red') script, div = components(plot) return [script,div,p1,ratio,message] def interactive_agegroup_plot(df,distance=2000,duration=None, sex='male',weightcategory='hwt'): if df.empty: return '','' age = df['age'] power = df['power'] name = df['name'] season = df['season'] if duration: duration2 = int(duration/60.) plottitle = sex+' '+weightcategory+' %s min' % duration2 else: plottitle = sex+' '+weightcategory+' %s m' % distance # poly_coefficients = np.polyfit(age,power,6) age2 = np.linspace(11,95) # poly_vals = np.polyval(poly_coefficients,age2) # poly_vals = 0.5*(np.abs(poly_vals)+poly_vals) fitfunc = lambda pars, x: np.abs(pars[0])*(1-x/max(120,pars[1]))-np.abs(pars[2])*np.exp(-x/np.abs(pars[3]))+np.abs(pars[4])*(np.sin(np.pi*x/max(50,pars[5]))) errfunc = lambda pars, x,y: fitfunc(pars,x)-y p0age = [700,120,700,10,100,100] p1, success = optimize.leastsq(errfunc,p0age[:], args = (age,power)) expo_vals = fitfunc(p1, age2) expo_vals = 0.5*(np.abs(expo_vals)+expo_vals) source = ColumnDataSource( data = dict( age = age, power = power, age2 = age2, expo_vals = expo_vals, season = season, name=name, ) ) TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' plot = Figure(tools=TOOLS,plot_width=900) plot.sizing_mode='scale_width' plot.circle('age','power',source=source,fill_color='red',size=15, legend='World Record') plot.line(age2,expo_vals) plot.xaxis.axis_label = "Age" plot.yaxis.axis_label = "Concept2 power" plot.title.text = plottitle hover = plot.select(dict(type=HoverTool)) hover.tooltips = OrderedDict([ ('Name ','@name'), ('Season ','@season'), ]) hover.mode = 'mouse' script,div = components(plot) return script,div def interactive_cpchart(rower,thedistances,thesecs,theavpower, theworkouts,promember=0, wcpower=[],wcdurations=[]): message = 0 # plot tools if (promember==1): TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' else: TOOLS = 'pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' x_axis_type = 'log' y_axis_type = 'linear' thesecs = pd.Series(thesecs) velo = thedistances/thesecs p = pd.Series(500./velo) p2 = p.fillna(method='ffill').apply(lambda x: timedeltaconv(x)) source = ColumnDataSource( data = dict( dist = thedistances, duration = thesecs, spm = 0*theavpower, tim = niceformat( thesecs.fillna(method='ffill').apply(lambda x: timedeltaconv(x)) ), power = theavpower, fpace = nicepaceformat(p2), ) ) # fitting the data to Paul if len(thedistances)>=2: paulslope, paulintercept,r,p,stderr = linregress(np.log10(thedistances),p) else: paulslope = 5.0/np.log10(2.0) paulintercept = p[0]-paulslope*np.log10(thedistances[0]) fitx = pd.Series(np.arange(100)*2*max(np.log10(thedistances))/100.) fitp = paulslope*fitx+paulintercept fitvelo = 500./fitp fitpower = 2.8*(fitvelo**3) fitt = 10**fitx/fitvelo fitp2 = fitp.fillna(method='ffill').apply(lambda x: timedeltaconv(x)) sourcepaul = ColumnDataSource( data = dict( dist = 10**fitx, duration = fitt, power = fitpower, spm = 0*fitpower, tim = niceformat( fitt.fillna(method='ffill').apply(lambda x: timedeltaconv(x)) ), fpace = nicepaceformat(fitp2), ) ) 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] wcpower = pd.Series(wcpower) wcdurations = pd.Series(wcdurations) # fitting WC data to three parameter CP model if len(wcdurations)>=4: p1wc, success = optimize.leastsq(errfunc, p0[:], args = (wcdurations,wcpower)) else: p1wc = None # fitting the data to three parameter CP model success = 0 p1 = p0 if len(thesecs)>=4: p1, success = optimize.leastsq(errfunc, p0[:], args = (thesecs,theavpower)) else: factor = fitfunc(p0,thesecs.mean())/theavpower.mean() p1 = [p0[0]/factor,p0[1]/factor,p0[2],p0[3]] success = 0 # Get stayer score if success == 1: power1min = fitfunc(p1,60.) power4min = fitfunc(p1,240.) power6min = fitfunc(p1,360.) power30min = fitfunc(p1,1800.) power1h = fitfunc(p1,3600.) power10sec = fitfunc(p1,10.) r10sec4min = 100.*power10sec/power4min r1h4min = 100.*power1h/power4min r1min6min = 100.*power1min/power6min r30min6min = 100.*power30min/power6min combined = r1h4min-0.2*(r10sec4min-100) combined2 = r30min6min-1.5*(r1min6min-100) dataset = pd.read_csv('static/stats/combined_set.csv') dataset2 = pd.read_csv('static/stats/combined_set6min.csv') stayerscore = int(percentileofscore(dataset['combined'],combined)) stayerscore2 = int(percentileofscore(dataset2['combined'],combined2)) else: stayerscore = None stayerscore2 = None fitt = pd.Series(10**(4*np.arange(100)/100.)) fitpower = fitfunc(p1,fitt) if p1wc is not None: fitpowerwc = 0.95*fitfunc(p1wc,fitt) fitpowerexcellent = 0.7*fitfunc(p1wc,fitt) fitpowergood = 0.6*fitfunc(p1wc,fitt) fitpowerfair = 0.5*fitfunc(p1wc,fitt) fitpoweraverage = 0.4*fitfunc(p1wc,fitt) else: fitpowerwc = 0*fitpower fitpowerexcellent = 0*fitpower fitpowergood = 0*fitpower fitpowerfair = 0*fitpower fitpoweraverage = 0*fitpower message = "" if len(fitpower[fitpower<0]) > 0: message = "CP model fit didn't give correct results" fitvelo = (fitpower/2.8)**(1./3.) fitdist = fitt*fitvelo fitp = 500./fitvelo fitp2 = fitp.fillna(method='ffill').apply(lambda x: timedeltaconv(x)) sourcecomplex = ColumnDataSource( data = dict( dist = fitdist, duration = fitt, tim = niceformat( fitt.fillna(method='ffill').apply(lambda x: timedeltaconv(x)) ), spm = 0*fitpower, power = fitpower, fitpowerwc = fitpowerwc, fitpowerexcellent = fitpowerexcellent, fitpowergood = fitpowergood, fitpowerfair = fitpowerfair, fitpoweraverage = fitpoweraverage, fpace = nicepaceformat(fitp2), ) ) # making the plot plot = Figure(tools=TOOLS,x_axis_type=x_axis_type, plot_width=900, toolbar_location="above", toolbar_sticky=False) # 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.sizing_mode = 'scale_width' plot.image_url([watermarkurl],1.8*max(thesecs),watermarky, watermarkw,watermarkh, global_alpha=watermarkalpha, w_units='screen', h_units='screen', anchor=watermarkanchor, dilate=True, y_range_name = "watermark", ) plot.circle('duration','power',source=source,fill_color='red',size=15, legend='Power') plot.xaxis.axis_label = "Duration (seconds)" plot.yaxis.axis_label = "Power (W)" if stayerscore is not None: plot.add_layout( Label(x=100,y=100,x_units='screen',y_units='screen', text='Stayer Score '+str(stayerscore)+'%', background_fill_alpha=0.7, background_fill_color='white', text_color='black') ) # plot.add_layout( # Label(x=100,y=120,x_units='screen',y_units='screen', # text='Stayer Score (6min) '+str(stayerscore2)+'%', # background_fill_alpha=0.7, # background_fill_color='white', # text_color='black') # ) cpdata = dataprep.fetchcperg(rower, theworkouts) if cpdata.empty: message = 'Calculations are running in the background. Please refresh this page to see updated results' return ['','',paulslope,paulintercept,p1,message,p1wc] velo = cpdata['distance']/cpdata['delta'] p = 500./velo p2 = p.fillna(method='ffill').apply(lambda x: timedeltaconv(x)) source2 = ColumnDataSource( data = dict( duration = cpdata['delta'], power = cpdata['cp'], tim = niceformat( cpdata['delta'].fillna(method='ffill').apply(lambda x: timedeltaconv(x)) ), dist = cpdata['distance'], pace = nicepaceformat(p2), ) ) plot.circle('duration','power',source=source2, fill_color='blue',size=3, legend = 'Power from segments') hover = plot.select(dict(type=HoverTool)) hover.tooltips = OrderedDict([ ('Duration ','@tim'), ('Power (W)','@power{int}'), ('Distance (m)','@dist{int}'), ('Pace (/500m)','@fpace'), ]) hover.mode = 'mouse' plot.y_range = Range1d(0,1.5*max(theavpower)) plot.x_range = Range1d(1,2*max(thesecs)) plot.legend.orientation = "vertical" plot.line('duration','power',source=sourcepaul,legend="Paul's Law") plot.line('duration','power',source=sourcecomplex,legend="CP Model", color='green') if p1wc is not None: plot.line('duration','fitpowerwc',source=sourcecomplex, legend="World Class", color='Maroon',line_dash='dotted') plot.line('duration','fitpowerexcellent',source=sourcecomplex, legend="90% percentile", color='Purple',line_dash='dotted') plot.line('duration','fitpowergood',source=sourcecomplex, legend="75% percentile", color='Olive',line_dash='dotted') plot.line('duration','fitpowerfair',source=sourcecomplex, legend="50% percentile", color='Gray',line_dash='dotted') plot.line('duration','fitpoweraverage',source=sourcecomplex, legend="25% percentile", color='SkyBlue',line_dash='dotted') script, div = components(plot) return [script,div,paulslope,paulintercept,p1,message,p1wc] def interactive_windchart(id=0,promember=0): # check if valid ID exists (workout exists) row = Workout.objects.get(id=id) # g = GraphImage.objects.filter(workout=row).order_by("-creationdatetime") f1 = row.csvfilename # create interactive plot plot = Figure(plot_width=400,plot_height=300) # get user # u = User.objects.get(id=row.user.id) r = row.user u = r.user rr = rrower(hrmax=r.max,hrut2=r.ut2, hrut1=r.ut1,hrat=r.at, hrtr=r.tr,hran=r.an,ftp=r.ftp) rowdata = rdata(f1,rower=rr) if rowdata == 0: return 0 try: dist = rowdata.df.loc[:,'cum_dist'] except KeyError: return ['','No Data Found'] try: vwind = rowdata.df.loc[:,'vwind'] winddirection = rowdata.df.loc[:,'winddirection'] bearing = rowdata.df.loc[:,'bearing'] except KeyError: rowdata.add_wind(0,0) rowdata.add_bearing() vwind = rowdata.df.loc[:,'vwind'] winddirection = rowdata.df.loc[:,'winddirection'] bearing = rowdata.df.loc[:,'winddirection'] rowdata.write_csv(f1,gzip=True) dataprep.update_strokedata(id,rowdata.df) winddirection = winddirection % 360 winddirection = (winddirection + 360) % 360 tw = tailwind(bearing,vwind,1.0*winddirection) source = ColumnDataSource( data = dict( dist=dist, vwind=vwind, tw=tw, winddirection=winddirection, ) ) # plot tools if (promember==1): TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,crosshair' else: TOOLS = 'pan,box_zoom,wheel_zoom,reset,tap,crosshair' # making the plot plot = Figure(tools=TOOLS,plot_width=400,height=500, # toolbar_location="below", toolbar_sticky=False, ) plot.line('dist','vwind',source=source,legend="Wind Speed (m/s)") plot.line('dist','tw',source=source,legend="Tail (+)/Head (-) Wind (m/s)",color='black') plot.title.text = row.name # plot.title.text_font_size=value("1.0em") plot.title.text_font="1.0em" plot.xaxis.axis_label = "Distance (m)" plot.yaxis.axis_label = "Wind Speed (m/s)" plot.y_range = Range1d(-7,7) plot.sizing_mode = 'scale_width' plot.extra_y_ranges = {"winddirection": Range1d(start=0,end=360)} plot.line('dist','winddirection',source=source, legend='Wind Direction',color="red", y_range_name="winddirection") plot.add_layout(LinearAxis(y_range_name="winddirection",axis_label="Wind Direction (degree)"),'right') script, div = components(plot) return [script,div] def interactive_streamchart(id=0,promember=0): # check if valid ID exists (workout exists) row = Workout.objects.get(id=id) # g = GraphImage.objects.filter(workout=row).order_by("-creationdatetime") f1 = row.csvfilename # create interactive plot plot = Figure(plot_width=400, ) # get user # u = User.objects.get(id=row.user.id) r = row.user u = r.user rr = rrower(hrmax=r.max,hrut2=r.ut2, hrut1=r.ut1,hrat=r.at, hrtr=r.tr,hran=r.an,ftp=r.ftp) rowdata = rdata(f1,rower=rr) if rowdata == 0: return "","No Valid Data Available" try: dist = rowdata.df.loc[:,'cum_dist'] except KeyError: return ['','No Data found'] try: vstream = rowdata.df.loc[:,'vstream'] except KeyError: rowdata.add_stream(0) vstream = rowdata.df.loc[:,'vstream'] rowdata.write_csv(f1,gzip=True) dataprep.update_strokedata(id,rowdata.df) # plot tools if (promember==1): TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,crosshair' else: TOOLS = 'pan,box_zoom,wheel_zoom,reset,tap,crosshair' # making the plot plot = Figure(tools=TOOLS,plot_width=400,height=500, # toolbar_location="below", toolbar_sticky=False, ) plot.line(dist,vstream,legend="River Stream Velocity (m/s)") plot.title.text = row.name plot.title.text_font_size=value("1.0em") plot.xaxis.axis_label = "Distance (m)" plot.yaxis.axis_label = "River Current (m/s)" plot.y_range = Range1d(-2,2) plot.sizing_mode = 'scale_width' script, div = components(plot) return [script,div] def interactive_chart(id=0,promember=0,intervaldata = {}): # Add hover to this comma-separated string and see what changes if (promember==1): TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' else: TOOLS = 'pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' columns = ['time','pace','hr','fpace','ftime','spm'] datadf = dataprep.getsmallrowdata_db(columns,ids=[id]) datadf.dropna(axis=0,how='any',inplace=True) row = Workout.objects.get(id=id) if datadf.empty: return "","No Valid Data Available" #else: # try: # datadf.sort_values(by='time',ascending=True,inplace=True) # except KeyError: # return "","No valid data available" try: spm = datadf['spm'] except KeyError: datadf['spm'] = 0 try: pace = datadf['pace'] except KeyError: datadf['pace'] = 0 source = ColumnDataSource( datadf ) plot = Figure(x_axis_type="datetime",y_axis_type="datetime", plot_width=400, plot_height=400, toolbar_sticky=False, tools=TOOLS) # 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_x_ranges = {"watermark": watermarkrange} plot.image_url([watermarkurl],0.01,0.99, 0.5*watermarkw,0.5*watermarkh, global_alpha=watermarkalpha, w_units='screen', h_units='screen', anchor='top_left', dilate=True, x_range_name = "watermark", y_range_name = "watermark", ) plot.line('time','pace',source=source,legend="Pace",name="pace") plot.title.text = row.name plot.title.text_font_size=value("1.0em") plot.sizing_mode = 'scale_width' plot.xaxis.axis_label = "Time" plot.yaxis.axis_label = "Pace (/500m)" plot.xaxis[0].formatter = DatetimeTickFormatter( hours = ["%H"], minutes = ["%M"], seconds = ["%S"], days = ["0"], months = [""], years = [""] ) plot.yaxis[0].formatter = DatetimeTickFormatter( seconds = ["%S"], minutes = ["%M"] ) ymax = 90. ymin = 150. if row.workouttype == 'water': ymax = 90. ymin = 210. plot.y_range = Range1d(1.e3*ymin,1.e3*ymax) plot.extra_y_ranges["spmax"] = Range1d(start=10,end=45) plot.line('time','spm',source=source,color="red", y_range_name="spmax", legend="Stroke Rate",name="spm") plot.add_layout(LinearAxis(y_range_name="spmax",axis_label="SPM"),'right') plot.legend.location = "bottom_right" # add shaded bar chart areas if intervaldata != {}: intervaldf = pd.DataFrame(intervaldata) intervaldf['itime'] = intervaldf['itime']*1.e3 intervaldf['time'] = intervaldf['itime'].cumsum() intervaldf['time'] = intervaldf['time'].shift(1) intervaldf.loc[:,'time'].iloc[0] = 0 intervaldf['time_r'] = intervaldf['time'] +intervaldf['itime'] intervaldf['value'] = 100 mask = intervaldf['itype'] == 3 intervaldf.loc[mask,'value'] = 0 intervaldf['bottom'] = 10 intervalsource = ColumnDataSource( intervaldf ) plot.quad(left='time',top='value',bottom='bottom', right='time_r',source=intervalsource,color='mediumvioletred', y_range_name='spmax',fill_alpha=0.2,line_alpha=0.2) hover = plot.select(dict(type=HoverTool)) hover.tooltips = OrderedDict([ ('Time','@ftime'), ('Pace','@fpace'), ('HR','@hr{int}'), ('SPM','@spm{1.1}'), ]) hover.mode = 'mouse' hover.names = ["spm","pace"] script, div = components(plot) return [script,div] def interactive_chart_video(videodata): spm = videodata['spm'] time = range(len(spm)) data = zip(time,spm) data2 = "[" for t,s in data: data2 += "{x: %s, y: %s}, " % (t,s) data2 = data2[:-2] + "]" markerpoint = { 'x': time[0], 'y': spm[0], 'r': 10, } div = """ """ script = """ var ctx = document.getElementById("myChart").getContext('2d'); var data = %s var myChart = new Chart(ctx, { type: 'scatter', label: 'SPM', animationSteps: 10, options: { legend: { display: false, }, animation: { duration: 100, }, scales: { yAxes: [{ scaleLabel: { display: true, labelString: 'Stroke Rate' } }], xAxes: [{ scaleLabel: { type: 'linear', display: true, labelString: 'Time (seconds)' } }], } }, data: { datasets: [ { type: 'bubble', label: 'now', data: [ %s ], backgroundColor: '#36a2eb', }, { label: 'spm', data: data, backgroundColor: "#ff0000", borderColor: "#ff0000", fill: false, borderDash: [0, 0], pointRadius: 1, pointHoverRadius: 1, showLine: true, tension: 0, }, ] }, }); var marker = { datapoint: %s , setLatLng: function (LatLng) { var lat = LatLng.lat; var lng = LatLng.lng; this.datapoint = { 'x': lat, 'y': lng, 'r': 10, } myChart.data.datasets[0].data[0] = this.datapoint; myChart.update(); } } marker.setLatLng({ 'lat': data[0]['x'], 'lng': data[0]['y'] }) """ % (data2, markerpoint, markerpoint) return [script,div] def interactive_multiflex(datadf,xparam,yparam,groupby,extratitle='', ploterrorbars=False, title=None,binsize=1,colorlegend=[], spmmin=0,spmmax=0,workmin=0,workmax=0): if datadf.empty: return ['','

No non-zero data in selection

'] if xparam == 'workoutid': xparamname = 'Workout' else: xparamname = axlabels[xparam] if yparam == 'workoutid': yparamname = 'Workout' else: yparamname = axlabels[yparam] if groupby == 'workoutid': groupname = 'Workout' elif groupby == 'date': groupname = 'Date' else: groupname = axlabels[groupby] if title==None: title = '{y} vs {x} grouped by {gr}'.format( x = xparamname, y = yparamname, gr = groupname, ) if xparam == 'cumdist': res = make_cumvalues(datadf[xparam]) datadf[xparam] = res[0] if xparam=='distance': xaxmax = datadf[xparam].max() xaxmin = datadf[xparam].min() elif xparam=='time': tseconds = datadf.loc[:,'time'] xaxmax = tseconds.max() xaxmin = 0 elif xparam == 'workoutid': xaxmax = datadf[xparam].max()-5 xaxmin = datadf[xparam].min()+5 else: xaxmax = yaxmaxima[xparam] xaxmin = yaxminima[xparam] if yparam=='distance': yaxmax = datadf[yparam].max() yaxmin = datadf[yparam].min() elif yparam=='time': tseconds = datadf.loc[:,'time'] yaxmax = tseconds.max() yaxmin = 0 elif yparam == 'workoutid': yaxmax = datadf[yparam].max()-5 yaxmin = datadf[yparam].min()+5 else: yaxmax = yaxmaxima[yparam] yaxmin = yaxminima[yparam] x_axis_type = 'linear' y_axis_type = 'linear' if xparam == 'time': x_axis_type = 'datetime' if yparam == 'pace': y_axis_type = 'datetime' datadf.index.names = ['index'] source = ColumnDataSource( datadf, ) TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap' if groupby != 'date': hover = HoverTool(names=['data'], tooltips = [ (groupby,'@groupval{1.1}'), (xparamname,'@x{1.1}'), (yparamname,'@y') ]) else: hover = HoverTool(names=['data'], tooltips = [ (groupby,'@groupval'), (xparamname,'@x{1.1}'), (yparamname,'@y') , ]) hover.mode = 'mouse' TOOLS = [SaveTool(),PanTool(),BoxZoomTool(),WheelZoomTool(), ResetTool(),TapTool(),hover] plot = Figure(x_axis_type=x_axis_type,y_axis_type=y_axis_type, tools=TOOLS, toolbar_location="above", toolbar_sticky=False,plot_width=920) # 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_x_ranges = {"watermark": watermarkrange} plot.title.text = title plot.title.text_font_size=value("1.0em") plot.sizing_mode = 'scale_width' plot.image_url([watermarkurl],watermarkx,watermarky, watermarkw,watermarkh, global_alpha=watermarkalpha, w_units='screen', h_units='screen', anchor=watermarkanchor, dilate=True, x_range_name = "watermark", y_range_name = "watermark", ) errorbar(plot,xparam,yparam,source=source, xerr=ploterrorbars, yerr=ploterrorbars, point_kwargs={ 'line_color':"#969696", 'size':"groupsize", 'fill_color':"color", 'fill_alpha':1.0, }, ) for nr, gvalue, color in colorlegend: box = BoxAnnotation(bottom=75+20*nr,left=50,top=95+20*nr, right=70, bottom_units='screen', top_units='screen', left_units='screen', right_units='screen', fill_color=color, fill_alpha=1.0, line_color=color) legendlabel = Label(x=71,y=78+20*nr,x_units='screen', y_units='screen', text = "{gvalue:3.0f}".format(gvalue=gvalue), background_fill_alpha=1.0, text_color='black', text_font_size=value("0.7em")) plot.add_layout(box) plot.add_layout(legendlabel) if colorlegend: legendlabel = Label(x=322,y=250,x_units='screen', y_units='screen', text = 'group legend', text_color='black', text_font_size=value("0.7em"), angle=90, angle_units='deg') if xparam == 'workoutid': plot.xaxis.axis_label = 'Workout' else: plot.xaxis.axis_label = axlabels[xparam] if yparam == 'workoutid': plot.xaxis.axis_label = 'Workout' else: plot.yaxis.axis_label = axlabels[yparam] binlabel = Label(x=50,y=50,x_units='screen', y_units='screen', text="Bin size {binsize:3.1f}".format(binsize=binsize), background_fill_alpha=0.7, background_fill_color='white', text_color='black',text_font_size='10pt', ) slidertext = 'SPM: {:.0f}-{:.0f}, WpS: {:.0f}-{:.0f}'.format( spmmin,spmmax,workmin,workmax ) sliderlabel = Label(x=50,y=20,x_units='screen',y_units='screen', text=slidertext, background_fill_alpha=0.7, background_fill_color='white', text_color='black',text_font_size='10pt', ) plot.add_layout(binlabel) plot.add_layout(sliderlabel) yrange1 = Range1d(start=yaxmin,end=yaxmax) plot.y_range = yrange1 xrange1 = Range1d(start=xaxmin,end=xaxmax) plot.x_range = xrange1 if yparam == 'pace': plot.yaxis[0].formatter = DatetimeTickFormatter( seconds = ["%S"], minutes = ["%M"] ) script,div = components(plot) return [script,div] def interactive_cum_flex_chart2(theworkouts,promember=0, xparam='spm', yparam1='power', yparam2='spm', workstrokesonly=False): # datadf = dataprep.smalldataprep(theworkouts,xparam,yparam1,yparam2) ids = [int(w.id) for w in theworkouts] columns = [xparam,yparam1,yparam2,'spm','driveenergy','distance'] datadf = dataprep.getsmallrowdata_db(columns,ids=ids,doclean=True, workstrokesonly=workstrokesonly) try: tests = datadf[yparam2] except KeyError: yparam2 = 'None' try: tests = datadf[yparam1] except KeyError: yparam1 = 'None' datadf.dropna(axis=1,how='all',inplace=True) datadf.dropna(axis=0,how='any',inplace=True) # test if we have drive energy nowork = 1 try: test = datadf['driveenergy'].mean() nowork = 0 except KeyError: datadf['driveenergy'] = 500. # test if we have power nopower = 1 try: test = datadf['power'].mean() nopower = 0 except KeyError: datadf['power'] = 50. yparamname1 = axlabels[yparam1] if yparam2 != 'None': yparamname2 = axlabels[yparam2] # check if dataframe not empty if datadf.empty: return ['','

No non-zero data in selection

','',''] try: datadf['x1'] = datadf.loc[:,xparam] except KeyError: try: datadf['x1'] = datadf['distance'] except KeyError: try: datadf['x1'] = datadf['time'] except KeyError: return ['','

No non-zero data in selection

','',''] try: datadf['y1'] = datadf.loc[:,yparam1] except KeyError: try: datadf['y1'] = datadf['pace'] except KeyError: return ['','

No non-zero data in selection

','',''] if yparam2 != 'None': try: datadf['y2'] = datadf.loc[:,yparam2] except KeyError: datadf['y2'] = datadf['y1'] else: datadf['y2'] = datadf['y1'] if xparam=='distance': xaxmax = datadf['x1'].max() xaxmin = datadf['x1'].min() else: xaxmax = yaxmaxima[xparam] xaxmin = yaxminima[xparam] # average values x1mean = datadf['x1'].mean() y1mean = datadf['y1'].mean() y2mean = datadf['y2'].mean() xvals = pd.Series(xaxmin+np.arange(100)*(xaxmax-xaxmin)/100.) x_axis_type = 'linear' y_axis_type = 'linear' if xparam == 'time': x_axis_type = 'datetime' if yparam1 == 'pace': y_axis_type = 'datetime' y1mean = datadf.loc[:,'pace'].mean() datadf['xname'] = axlabels[xparam] datadf['yname1'] = axlabels[yparam1] if yparam2 != 'None': datadf['yname2'] = axlabels[yparam2] else: datadf['yname2'] = axlabels[yparam1] source = ColumnDataSource( datadf ) source2 = ColumnDataSource( datadf.copy() ) # Add hover to this comma-separated string and see what changes if (promember==1): TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,crosshair' else: TOOLS = 'pan,box_zoom,wheel_zoom,reset,tap,crosshair' plot = Figure(x_axis_type=x_axis_type,y_axis_type=y_axis_type, tools=TOOLS, toolbar_location="above", toolbar_sticky=False) # 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_x_ranges = {"watermark": watermarkrange} plot.sizing_mode = 'scale_width' plot.image_url([watermarkurl],watermarkx,watermarky, watermarkw,watermarkh, global_alpha=watermarkalpha, w_units='screen', h_units='screen', anchor=watermarkanchor, dilate=True, x_range_name = "watermark", y_range_name = "watermark", ) x1means = Span(location=x1mean,dimension='height',line_color='green', line_dash=[6,6], line_width=2) y1means = Span(location=y1mean,dimension='width',line_color='blue', line_dash=[6,6],line_width=2) y2means = y1means xlabel = Label(x=50,y=80,x_units='screen',y_units='screen', text=axlabels[xparam]+": {x1mean:6.2f}".format(x1mean=x1mean), background_fill_alpha=.7, background_fill_color='white', text_color='green', ) sliderlabel = Label(x=10,y=470,x_units='screen',y_units='screen', text='', background_fill_alpha=0.7, background_fill_color='white', text_color='black',text_font_size='10pt', ) plot.add_layout(x1means) plot.add_layout(xlabel) plot.add_layout(y1means) plot.add_layout(sliderlabel) y1label = Label(x=50,y=50,x_units='screen',y_units='screen', text=axlabels[yparam1]+": {y1mean:6.2f}".format(y1mean=y1mean), background_fill_alpha=.7, background_fill_color='white', text_color='blue', ) if yparam1 != 'time' and yparam1 != 'pace': plot.add_layout(y1label) y2label = y1label plot.circle('x1','y1',source=source2,fill_alpha=0.3,line_color=None, legend=yparamname1, ) plot.xaxis.axis_label = axlabels[xparam] plot.yaxis.axis_label = axlabels[yparam1] yrange1 = Range1d(start=yaxminima[yparam1],end=yaxmaxima[yparam1]) plot.y_range = yrange1 xrange1 = Range1d(start=yaxminima[xparam],end=yaxmaxima[xparam]) plot.x_range = xrange1 if yparam1 == 'pace': plot.yaxis[0].formatter = DatetimeTickFormatter( seconds = ["%S"], minutes = ["%M"] ) if yparam2 != 'None': yrange2 = Range1d(start=yaxminima[yparam2],end=yaxmaxima[yparam2]) plot.extra_y_ranges["yax2"] = yrange2 plot.circle('x1','y2',color="red",y_range_name="yax2", legend=yparamname2, source=source2,fill_alpha=0.3,line_color=None) plot.add_layout(LinearAxis(y_range_name="yax2", axis_label=axlabels[yparam2]),'right') y2means = Span(location=y2mean,dimension='width',line_color='red', line_dash=[6,6],line_width=2,y_range_name="yax2") plot.add_layout(y2means) y2label = Label(x=50,y=20,x_units='screen',y_units='screen', text=axlabels[yparam2]+": {y2mean:6.2f}".format(y2mean=y2mean), background_fill_alpha=.7, background_fill_color='white', text_color='red', ) if yparam2 != 'pace' and yparam2 != 'time': plot.add_layout(y2label) callback = CustomJS(args = dict(source=source,source2=source2, x1means=x1means, y1means=y1means, y1label=y1label, y2label=y2label, xlabel=xlabel, sliderlabel=sliderlabel, y2means=y2means), code=""" var data = source.data var data2 = source2.data var x1 = data['x1'] var y1 = data['y1'] var y2 = data['y2'] var spm1 = data['spm'] var index1 = data['index'] var distance1 = data['distance'] var power1 = data['power'] var driveenergy1 = data['driveenergy'] var xname = data['xname'] var yname1 = data['yname1'] var yname2 = data['yname2'] var workoutid1 = data['workoutid'] var minspm = minspm.value var maxspm = maxspm.value var mindist = mindist.value var maxdist = maxdist.value var minwork = minwork.value var maxwork = maxwork.value sliderlabel.text = 'SPM: '+minspm.toFixed(0)+'-'+maxspm.toFixed(0) sliderlabel.text += ', Dist: '+mindist.toFixed(0)+'-'+maxdist.toFixed(0) sliderlabel.text += ', WpS: '+minwork.toFixed(0)+'-'+maxwork.toFixed(0) var xm = 0 var ym1 = 0 var ym2 = 0 data2['x1'] = [] data2['y1'] = [] data2['y2'] = [] data2['distance'] = [] data2['power'] = [] data2['x1mean'] = [] data2['y1mean'] = [] data2['y2mean'] = [] data2['driveenergy'] = [] data2['workoutid'] = [] data2['xname'] = [] data2['yname1'] = [] data2['yname2'] = [] data2['spm'] = [] for (i=0; i=minspm && spm1[i]<=maxspm) { if (distance1[i]>=mindist && distance1[i]<=maxdist) { if (driveenergy1[i]>=minwork && driveenergy1[i]<=maxwork) { data2['x1'].push(x1[i]) data2['y1'].push(y1[i]) data2['y2'].push(y2[i]) data2['spm'].push(spm1[i]) data2['driveenergy'].push(driveenergy1[i]) data2['distance'].push(distance1[i]) data2['power'].push(power1[i]) data2['workoutid'].push(0) data2['xname'].push(0) data2['yname1'].push(0) data2['yname2'].push(0) xm += x1[i] ym1 += y1[i] ym2 += y2[i] } } } } xm /= data2['x1'].length ym1 /= data2['x1'].length ym2 /= data2['x1'].length for (i=0; i=minspm && spm1[i]<=maxspm) { if (distance1[i]>=mindist && distance1[i]<=maxdist) { if (driveenergy1[i]>=minwork && driveenergy1[i]<=maxwork) { data2['x1'].push(x1[i]) data2['y1'].push(y1[i]) data2['y2'].push(y2[i]) data2['spm'].push(spm1[i]) data2['time'].push(time1[i]) data2['ftime'].push(ftime1[i]) data2['fpace'].push(fpace1[i]) data2['driveenergy'].push(driveenergy1[i]) data2['pace'].push(pace1[i]) data2['hr'].push(hr1[i]) data2['distance'].push(distance1[i]) data2['power'].push(power1[i]) data2['workoutid'].push(0) data2['workoutstate'].push(0) data2['xname'].push(0) data2['yname1'].push(0) data2['yname2'].push(0) xm += x1[i] ym1 += y1[i] ym2 += y2[i] } } } } xm /= data2['x1'].length ym1 /= data2['x1'].length ym2 /= data2['x1'].length for (i=0; i maxlength: try: bins = np.linspace(rowdata['time'].min(),rowdata['time'].max(),maxlength) groups = rowdata.groupby(np.digitize(rowdata['time'],bins)) rowdata = groups.mean() except KeyError: pass for f in favorites: workstrokesonly = not f.reststrokes script,div = thumbnail_flex_chart( rowdata, id=id, xparam=f.xparam, yparam1=f.yparam1, yparam2=f.yparam2, plottype=f.plottype, ) charts.append({ 'script':script, 'div':div, 'notes':f.notes}) return charts def thumbnail_flex_chart(rowdata,id=0,promember=0, xparam='time', yparam1='pace', yparam2='hr', plottype='line', workstrokesonly=False): try: tests = rowdata[yparam2] except KeyError: yparam2 = 'None' try: tests = rowdata[yparam1] except KeyError: yparam1 = 'None' try: tseconds = rowdata.loc[:,'time'] except KeyError: return '','No time data - cannot make flex plot' try: rowdata['x1'] = rowdata.loc[:,xparam] except KeyError: rowdata['x1'] = 0*rowdata.loc[:,'time'] try: rowdata['y1'] = rowdata.loc[:,yparam1] except KeyError: rowdata['y1'] = 0*rowdata.loc[:,'time'] if yparam2 != 'None': try: rowdata['y2'] = rowdata.loc[:,yparam2] except KeyError: rowdata['y2'] = 0*rowdata.loc[:,'time'] else: rowdata['y2'] = rowdata['y1'] if xparam=='time': xaxmax = tseconds.max() xaxmin = tseconds.min() elif xparam=='distance' or xparam=='cumdist': xaxmax = rowdata['x1'].max() xaxmin = rowdata['x1'].min() else: xaxmax = yaxmaxima[xparam] xaxmin = yaxminima[xparam] x_axis_type = 'linear' y_axis_type = 'linear' if xparam == 'time': x_axis_type = 'datetime' if yparam1 == 'pace': y_axis_type = 'datetime' y1mean = rowdata.loc[:,'pace'].mean() rowdata['xname'] = axlabels[xparam] try: rowdata['yname1'] = axlabels[yparam1] except KeyError: rowdata['yname1'] = axlabels[xparam] if yparam2 != 'None': rowdata['yname2'] = axlabels[yparam2] else: rowdata['yname2'] = axlabels[yparam1] # prepare data source = ColumnDataSource( rowdata ) sizing_mode = 'fixed' # 'scale_width' also looks nice with this example plot = Figure(x_axis_type=x_axis_type,y_axis_type=y_axis_type, plot_width=200,plot_height=150, ) # plot.sizing_mode = 'scale_width' plot.sizing_mode = 'fixed' plot.toolbar.logo = None plot.toolbar_location = None #plot.yaxis.visible = False plot.xaxis.axis_label_text_font_size = "7pt" plot.yaxis.axis_label_text_font_size = "7pt" plot.xaxis.major_label_text_font_size = "7pt" plot.yaxis.major_label_text_font_size = "7pt" if plottype=='line': plot.line('x1','y1',source=source) elif plottype=='scatter': plot.scatter('x1','y1',source=source,fill_alpha=0.4, line_color=None) try: plot.xaxis.axis_label = axlabels[xparam] except KeyError: plot.xaxis.axis_label = 'X' try: plot.yaxis.axis_label = axlabels[yparam1] except KeyError: plot.yaxis.axis_label = 'Y' try: yrange1 = Range1d(start=yaxminima[yparam1],end=yaxmaxima[yparam1]) except KeyError: yrange1 = Range1d(start=yparam1.min(), end=yparam1.max()) plot.y_range = yrange1 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 yparam1 == 'pace': plot.yaxis[0].formatter = DatetimeTickFormatter( seconds = ["%S"], minutes = ["%M"] ) if yparam2 != 'None': yrange2 = Range1d(start=yaxminima[yparam2],end=yaxmaxima[yparam2]) plot.extra_y_ranges["yax2"] = yrange2 #= {"yax2": yrange2} if plottype=='line': plot.line('x1','y2',color="red",y_range_name="yax2", source=source) elif plottype=='scatter': plot.scatter('x1','y2',source=source, fill_alpha=0.4, line_color=None,color="red",y_range_name="yax2") plot.add_layout(LinearAxis(y_range_name="yax2", axis_label=axlabels[yparam2], major_label_text_font_size="7pt", axis_label_text_font_size="7pt", ),'right', ) script, div = components(plot) return [script,div] def interactive_bar_chart(id=0,promember=0): # check if valid ID exists (workout exists) rowdata,row = dataprep.getrowdata_db(id=id) rowdata.dropna(axis=1,how='all',inplace=True) rowdata.dropna(axis=0,how='any',inplace=True) if rowdata.empty: return "","No Valid Data Available" # Add hover to this comma-separated string and see what changes if (promember==1): TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' else: TOOLS = 'pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' source = ColumnDataSource( rowdata ) plot = Figure(x_axis_type="datetime",y_axis_type="datetime", toolbar_sticky=False, plot_width=920, tools=TOOLS) # 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_x_ranges = {"watermark": watermarkrange} plot.sizing_mode = 'scale_width' plot.image_url([watermarkurl],0.01,0.99, watermarkw,watermarkh, global_alpha=watermarkalpha, w_units='screen', h_units='screen', anchor='top_left', dilate=True, x_range_name = "watermark", y_range_name = "watermark", ) plot.title.text = row.name plot.title.text_font_size=value("1.0em") plot.xaxis.axis_label = "Time" plot.yaxis.axis_label = "Pace (/500m)" plot.xaxis[0].formatter = DatetimeTickFormatter( hours ="", minutes = ["%M"], seconds = ["%S"], days = ["0"], months = [""], years = [""] ) plot.yaxis[0].formatter = DatetimeTickFormatter( hours = "", seconds = ["%S"], minutes = ["%M"], ) ymax = 1.0e3*90 ymin = 1.0e3*180 if row.workouttype == 'water': ymax = 1.0e3*90 ymin = 1.0e3*210 plot.y_range = Range1d(ymin,ymax) hover = plot.select(dict(type=HoverTool)) hover.tooltips = OrderedDict([ ('Time','@ftime'), ('Pace','@fpace'), ('HR','@hr{int}'), ('SPM','@spm{1.1}'), ]) hover.mode = 'mouse' plot.extra_y_ranges["hr"] = Range1d(start=100,end=200) plot.quad(left='time',top='hr_ut2',bottom='hr_bottom', right='x_right',source=source,color="gray", y_range_name="hr", legend="A chart data error occurred

','','A chart data error occurred'] yparamname = axlabels[yparam] #datadf = datadf[datadf[yparam] > 0] #datadf = datadf[datadf[xparam] > 0] # check if dataframe not empty if datadf.empty: return ['','

No non-zero data in selection

','','No non-zero data in selection'] if xparam != 'distance' and xparam != 'time' and xparam != 'cumdist': xaxmax = yaxmaxima[xparam] xaxmin = yaxminima[xparam] elif xparam == 'time' and not startenddict: xaxmax = tseconds.max() xaxmin = tseconds.min() elif xparam == 'time' and startenddict: deltas = [pair[1]-pair[0] for key,pair in startenddict.items()] xaxmin = 0 xaxmax = pd.Series(deltas).max()*1000. if xaxmax == 0: xaxmax = tseconds.max() else: xaxmax = datadf['distance'].max() xaxmin = datadf['distance'].min() if yparam == 'distance': yaxmin = datadf['distance'].min() yaxmax = datadf['distance'].max() elif yparam == 'cumdist': yaxmin = datadf['cumdist'].min() yaxmax = datadf['cumdist'].max() else: yaxmin = yaxminima[yparam] yaxmax = yaxmaxima[yparam] x_axis_type = 'linear' y_axis_type = 'linear' # Add hover to this comma-separated string and see what changes if (promember==1): TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,crosshair' else: TOOLS = 'pan,box_zoom,wheel_zoom,reset,tap,crosshair' if yparam == 'pace': y_axis_type = 'datetime' yaxmax = 90.*1e3 yaxmin = 150.*1e3 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, tools=TOOLS, toolbar_location="above", plot_width=920,plot_height=500, toolbar_sticky=False) # 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_x_ranges = {"watermark": watermarkrange} plot.sizing_mode = 'scale_width' plot.image_url([watermarkurl],0.05,0.9, watermarkw,watermarkh, global_alpha=watermarkalpha, w_units='screen', h_units='screen', anchor='top_left', dilate=True, x_range_name = "watermark", y_range_name = "watermark", ) colors = itertools.cycle(palette) cntr = 0 l1 = [] try: items = itertools.izip(ids,colors) except AttributeError: items = zip(ids,colors) for id,color in items: group = datadf[datadf['workoutid']==int(id)].copy() try: startsecond,endsecond = startenddict[id] except KeyError: startsecond = 0 endsecond = 0 group.sort_values(by='time',ascending=True,inplace=True) if endsecond > 0: group['time'] = group['time'] - 1.e3*startsecond mask = group['time'] < 0 group.mask(mask,inplace=True) mask = group['time'] > 1.e3*(endsecond-startsecond) group.mask(mask,inplace=True) if xparam == 'cumdist': group['cumdist'] = group['cumdist'] - group['cumdist'].min() res = make_cumvalues(group[xparam]) group[xparam] = res[0] elif xparam == 'distance': group['distance'] = group['distance'] - group['distance'].min() try: group['x'] = group[xparam] except KeyError: group['x'] = group['time'] errormessage = xparam+' has no values. Plot invalid' try: group['y'] = group[yparam] except KeyError: group['y'] = 0.0*group['x'] ymean = group['y'].mean() f = group['time'].diff().mean() if f != 0 and not np.isnan(f): windowsize = 2* (int(20000./(f))) + 1 else: windowsize = 1 if windowsize > 3 and windowsize < len(group['y']): try: group['y'] = savgol_filter(group['y'],windowsize,3) except ValueError: pass ylabel = Label(x=100,y=60+nrworkouts*20-20*cntr, x_units='screen',y_units='screen', text=axlabels[yparam]+": {ymean:6.2f}".format(ymean=ymean), background_fill_alpha=.7, background_fill_color='white', text_color=color, ) if yparam != 'time' and yparam != 'pace': plot.add_layout(ylabel) source = ColumnDataSource( group ) TIPS = OrderedDict([ ('time','@ftime'), ('pace','@fpace'), ('hr','@hr'), ('spm','@spm{1.1}'), ('distance','@distance{5}'), ]) hover = plot.select(type=HoverTool) hover.tooltips = TIPS if labeldict: try: legend=labeldict[id] except KeyError: legend = str(id) else: legend=str(id) if plottype=='line': l1.append(plot.line('x','y',source=source,color=color,legend=legend,line_width=2)) else: l1.append(plot.scatter('x','y',source=source,color=color,legend=legend, fill_alpha=0.4,line_color=None)) plot.add_tools(HoverTool(renderers=[l1[cntr]],tooltips=TIPS)) cntr += 1 plot.legend.location='top_right' 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 yrange1 = Range1d(start=yaxmin,end=yaxmax) plot.y_range = yrange1 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) return [script,div,message,errormessage] def interactive_comparison_chart(id1=0,id2=0,xparam='distance',yparam='spm', promember=0,plottype='line'): columns = [xparam,yparam, 'ftime','distance','fpace', 'power','hr','spm', 'time','pace','workoutstate'] # check if valid ID exists (workout exists) #rowdata1,row1 = dataprep.getrowdata_db(id=id1) #rowdata2,row2 = dataprep.getrowdata_db(id=id2) rowdata1 = dataprep.getsmallrowdata_db(columns,ids=[id1]) rowdata2 = dataprep.getsmallrowdata_db(columns,ids=[id2]) for n in ['distance','power','hr','spm','time','pace','workoutstate']: try: rowdata1[n].fillna(value=0,inplace=True) except KeyError: pass try: rowdata2[n].fillna(value=0,inplace=True) except KeyError: pass rowdata1.dropna(axis=1,how='all',inplace=True) rowdata1.dropna(axis=0,how='any',inplace=True) rowdata2.dropna(axis=1,how='all',inplace=True) rowdata2.dropna(axis=0,how='any',inplace=True) row1 = Workout.objects.get(id=id1) row2 = Workout.objects.get(id=id2) if rowdata1.empty: return "","No Valid Data Available" # else: # rowdata1.sort_values(by='time',ascending=True,inplace=True) if rowdata2.empty: return "","No Valid Data Available" # else: # rowdata2.sort_values(by='time',ascending=True,inplace=True) try: x1 = rowdata1.loc[:,xparam] x2 = rowdata2.loc[:,xparam] y1 = rowdata1.loc[:,yparam] y2 = rowdata2.loc[:,yparam] except KeyError: return "","No valid Data Available" x_axis_type = 'linear' y_axis_type = 'linear' if xparam == 'time': x_axis_type = 'datetime' if yparam == 'pace': y_axis_type = 'datetime' ymax = 1.0e3*90 ymin = 1.0e3*180 if row1.workouttype == 'water': ymax = 1.0e3*90 ymin = 1.0e3*210 ftime1 = rowdata1.loc[:,'ftime'] ftime2 = rowdata2.loc[:,'ftime'] hr1 = rowdata1.loc[:,'hr'] hr2 = rowdata2.loc[:,'hr'] fpace1 = rowdata1.loc[:,'fpace'] fpace2 = rowdata2.loc[:,'fpace'] distance1 = rowdata1.loc[:,'distance'] distance2 = rowdata2.loc[:,'distance'] spm1 = rowdata1.loc[:,'spm'] spm2 = rowdata2.loc[:,'spm'] if (promember==1): TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' else: TOOLS = 'pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' data1 = pd.DataFrame( dict( x1=x1, y1=y1, ftime1=ftime1, fpace1=fpace1, hr1 = hr1, spm1 = spm1, distance1=distance1, ) ).dropna() data2 = pd.DataFrame( dict( x2=x2, y2=y2, ftime2=ftime2, fpace2=fpace2, hr2 = hr2, spm2 = spm2, distance2=distance2, ) ).dropna() source1 = ColumnDataSource( data1 ) source2 = ColumnDataSource( data2 ) ymean1 = data1['y1'].mean() ymean2 = data2['y2'].mean() # create interactive plot plot = Figure(x_axis_type=x_axis_type,y_axis_type=y_axis_type, tools=TOOLS, plot_width=920, toolbar_sticky=False) # 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_x_ranges = {"watermark": watermarkrange} plot.sizing_mode = 'scale_width' plot.image_url([watermarkurl],0.05,watermarky, watermarkw,watermarkh, global_alpha=watermarkalpha, w_units='screen', h_units='screen', anchor='bottom_left', dilate=True, x_range_name = "watermark", y_range_name = "watermark", ) TIPS = OrderedDict([ ('time','@ftime1'), ('pace','@fpace1'), ('hr','@hr1'), ('spm','@spm1{1.1}'), ('distance','@distance1{5}'), ]) TIPS2 = OrderedDict([ ('time','@ftime2'), ('pace','@fpace2'), ('hr','@hr2'), ('spm','@spm2{1.1}'), ('distance','@distance2{5}'), ]) hover1 = plot.select(type=HoverTool) hover1.tooltips = TIPS hover2 = plot.select(type=HoverTool) hover2.tooltips = TIPS2 if plottype=='line': l1 = plot.line('x1','y1',source=source1, color="blue",legend=row1.name, ) l2 = plot.line('x2','y2',source=source2, color="red",legend=row2.name, ) elif plottype=='scatter': l1 = plot.scatter('x1','y1',source=source1,legend=row1.name, fill_alpha=0.4, line_color=None) l2 = plot.scatter('x2','y2',source=source2,legend=row2.name, fill_alpha=0.4, line_color=None,color="red") plot.add_tools(HoverTool(renderers=[l1],tooltips=TIPS)) plot.add_tools(HoverTool(renderers=[l2],tooltips=TIPS2)) plot.legend.location = "bottom_right" plot.title.text = row1.name+' vs '+row2.name plot.title.text_font_size=value("1.2em") plot.xaxis.axis_label = axlabels[xparam] plot.yaxis.axis_label = axlabels[yparam] ylabel1 = Label(x=100,y=90,x_units='screen',y_units='screen', text=axlabels[yparam]+": {ymean1:6.2f}".format( ymean1=ymean1 ), background_fill_alpha=.7, background_fill_color='white', text_color='blue' ) ylabel2 = Label(x=100,y=110,x_units='screen',y_units='screen', text=axlabels[yparam]+": {ymean2:6.2f}".format( ymean2=ymean2 ), background_fill_alpha=.7, background_fill_color='white', text_color='red' ) plot.add_layout(ylabel1) plot.add_layout(ylabel2) if xparam == 'time': 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"] ) plot.y_range = Range1d(ymin,ymax) script, div = components(plot) return [script,div] def interactive_otw_advanced_pace_chart(id=0,promember=0): # check if valid ID exists (workout exists) rowdata,row = dataprep.getrowdata_db(id=id) rowdata.dropna(axis=1,how='all',inplace=True) rowdata.dropna(axis=0,how='any',inplace=True) if rowdata.empty: return "","No Valid Data Available" # Add hover to this comma-separated string and see what changes if (promember==1): TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' else: TOOLS = 'pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' source = ColumnDataSource( rowdata ) plot = Figure(x_axis_type="datetime",y_axis_type="datetime", tools=TOOLS, plot_width=920, toolbar_sticky=False) # 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_x_ranges = {"watermark": watermarkrange} plot.sizing_mode = 'scale_width' plot.image_url([watermarkurl],watermarkx,watermarky, watermarkw,watermarkh, global_alpha=watermarkalpha, w_units='screen', h_units='screen', anchor=watermarkanchor, dilate=True, x_range_name = "watermark", y_range_name = "watermark", ) plot.title.text = row.name plot.title.text_font_size=value("1.2em") plot.xaxis.axis_label = "Time" plot.yaxis.axis_label = "Pace (/500m)" plot.xaxis[0].formatter = DatetimeTickFormatter( hours = ["%H"], minutes = ["%M"], seconds = ["%S"], days = ["0"], months = [""], years = [""] ) plot.yaxis[0].formatter = DatetimeTickFormatter( seconds = ["%S"], minutes = ["%M"] ) ymax = 1.0e3*90 ymin = 1.0e3*210 plot.y_range = Range1d(ymin,ymax) hover = plot.select(dict(type=HoverTool)) plot.line('time','pace',source=source,legend="Pace",color="black") plot.line('time','nowindpace',source=source,legend="Corrected Pace",color="red") hover.tooltips = OrderedDict([ ('Time','@ftime'), ('Pace','@fpace'), ('Corrected Pace','@fnowindpace'), ('HR','@hr{int}'), ('SPM','@spm{1.1}'), ]) hover.mode = 'mouse' try: script, div = components(plot) except: script = '' div = '' return [script,div]