from rowers.models import Workout, User, Rower, WorkoutForm,RowerForm,GraphImage 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 bokeh.palettes import Dark2_8 as palette import itertools from bokeh.plotting import figure, ColumnDataSource, Figure,curdoc from bokeh.models import CustomJS,Slider, TextInput from bokeh.charts import Histogram,HeatMap,Area,BoxPlot from bokeh.resources import CDN,INLINE from bokeh.embed import components from bokeh.layouts import layout,widgetbox 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.models.glyphs import ImageURL #from bokeh.models.widgets import Slider, Select, TextInput from bokeh.core.properties import value from collections import OrderedDict from django.conf import settings import datetime import math import numpy as np import pandas as pd from pytz import timezone as tz,utc from django.utils.timezone import get_current_timezone from django.utils.timezone import activate activate(settings.TIME_ZONE) thetimezone = get_current_timezone() from scipy.stats import linregress from scipy import optimize from scipy.signal import savgol_filter import stravastuff from rowers.dataprep import rdata import rowers.dataprep as dataprep from rowers.metrics import axes,axlabels,yaxminima,yaxmaxima from utils import lbstoN watermarkurl = "/static/img/logo7.png" watermarksource = ColumnDataSource(dict( url = [watermarkurl],)) watermarkrange = Range1d(start=0,end=1) watermarkalpha = 0.6 watermarkx = 0.99 watermarky = 0.01 watermarkw = 184 watermarkh = 35 watermarkanchor = 'bottom_right' def 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 def interactive_boxchart(datadf,fieldname,extratitle=''): if datadf.empty: return '','It looks like there are no data matching your filter' TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,resize,hover' plot = BoxPlot(datadf, values=fieldname, label='date', legend=False, title=axlabels[fieldname]+' '+extratitle, outliers=False, tools=TOOLS, toolbar_location="above", toolbar_sticky=False, x_mapper_type='datetime') yrange1 = Range1d(start=yaxminima[fieldname],end=yaxmaxima[fieldname]) plot.y_range = yrange1 plot.xaxis.axis_label = 'Date' plot.yaxis.axis_label = axlabels[fieldname] # add watermark 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.xaxis.formatter = DatetimeTickFormatter( days=["%d %B %Y"], months=["%d %B %Y"], years=["%d %B %Y"], ) if fieldname == 'pace': plot.yaxis[0].formatter = DatetimeTickFormatter( seconds = ["%S"], minutes = ["%M"] ) plot.xaxis.major_label_orientation = pi/4 hover = plot.select(dict(type=HoverTool)) hover.tooltips = OrderedDict([ ('Value','@y'), ('Date','@x'), ]) hover.mode = 'mouse' script, div = components(plot) return script,div def interactive_forcecurve(theworkouts,workstrokesonly=False): TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,resize,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) 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","","" try: catchav = rowdata['catch'].mean() except KeyError: catchav = 0 try: finishav = rowdata['finish'].mean() except KeyError: finishav = 0 try: washav = rowdata['wash'].mean() except KeyError: washav = 0 try: slipav = rowdata['slip'].mean() except KeyError: slipav = 0 try: peakforceav = rowdata['peakforce'].mean() except KeyError: peakforceav = 0 try: averageforceav = rowdata['averageforce'].mean() except KeyError: averageforceav = 0 try: peakforceangleav = rowdata['peakforceangle'].mean() except KeyError: peakforceangleav = 0 x = [catchav, catchav+slipav, peakforceangleav, finishav-washav, finishav] thresholdforce = 100 if 'x' in boattype else 200 #thresholdforce /= 4.45 # N to lbs y = [0,thresholdforce, peakforceav, thresholdforce,0] source = ColumnDataSource( data = dict( x = x, y = y, )) source2 = ColumnDataSource( rowdata ) plot = Figure(tools=TOOLS, toolbar_sticky=False) # add watermark 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", ) avf = Span(location=averageforceav,dimension='width',line_color='blue', line_dash=[6,6],line_width=2) plot.line('x','y',source=source,color="red") plot.add_layout(avf) peakflabel = Label(x=455,y=530,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=465,y=500,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=460,y=470,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=420,y=440,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=455,y=410,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=470,y=380,x_units='screen',y_units='screen', text="Slip: {slipav:6.2f}".format(slipav=slipav), background_fill_alpha=0.7, background_fill_color='white', text_color='red', ) washlabel = Label(x=460,y=350,x_units='screen',y_units='screen', text="Wash: {washav:6.2f}".format(washav=washav), background_fill_alpha=0.7, background_fill_color='white', text_color='red', ) 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.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, avf=avf, avflabel=avflabel, catchlabel=catchlabel, finishlabel=finishlabel, sliplabel=sliplabel, washlabel=washlabel, peakflabel=peakflabel, peakforceanglelabel=peakforceanglelabel, ), code=""" var data = source.data var data2 = source2.data var x = data['x'] var y = data['y'] 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 minspm = minspm.value var maxspm = maxspm.value var mindist = mindist.value var maxdist = maxdist.value var minwork = minwork.value var maxwork = maxwork.value var catchav = 0 var finishav = 0 var slipav = 0 var washav = 0 var peakforceangleav = 0 var averageforceav = 0 var peakforceav = 0 var count = 0 for (i=0; i=minspm && spm1[i]<=maxspm) { if (distance1[i]>=mindist && distance1[i]<=maxdist) { if (driveenergy1[i]>=minwork && driveenergy1[i]<=maxwork) { 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] 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) source.trigger('change'); """) 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=1, title="Min Distance",callback=callback) callback.args["mindist"] = slider_dist_min slider_dist_max = Slider(start=0,end=distmax,value=distmax, step=1, title="Max Distance",callback=callback) callback.args["maxdist"] = slider_dist_max layout = layoutrow([layoutcolumn([slider_spm_min, slider_spm_max, slider_dist_min, slider_dist_max, slider_work_min, slider_work_max, ], ), plot]) script, div = components(layout) js_resources = INLINE.render_js() css_resources = INLINE.render_css() return [script,div,js_resources,css_resources] def interactive_histoall(theworkouts): TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,resize,crosshair' ids = [int(w.id) for w in theworkouts] rowdata = dataprep.getsmallrowdata_db(['power'],ids=ids,doclean=True) rowdata.dropna(axis=0,how='any',inplace=True) if rowdata.empty: return "","No Valid Data Available","","" histopwr = rowdata['power'].values if len(histopwr) == 0: return "","No valid data available","","" # throw out nans histopwr = histopwr[~np.isinf(histopwr)] histopwr = histopwr[histopwr > 25] histopwr = histopwr[histopwr < 1000] plot = Figure(tools=TOOLS,plot_width=900, toolbar_sticky=False, toolbar_location="above" ) # add watermark 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 = "Power (W)" 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([ ('Power(W)','@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') script, div = components(plot) return [script,div] def googlemap_chart(lat,lon,name=""): if lat.empty or lon.empty: return [0,"invalid coordinate data"] # plot tools TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,resize' map_options = GMapOptions(lat = lat.mean(),lng=lon.mean(), map_type="roadmap",zoom=13) plot = GMapPlot( x_range=DataRange1d(), y_range=DataRange1d(), map_options=map_options, api_key = "AIzaSyAgu1w9QSthaGPMLp8y9JedPoMc9sfEgJ8", plot_width=400,plot_height=400, toolbar_sticky=False, ) source = ColumnDataSource( data = dict( lat=lat, lon=lon, ) ) circle = Circle(x="lon",y="lat",size=5,fill_color="blue", fill_alpha=0.2,line_color=None) plot.add_glyph(source,circle) plot.add_tools(PanTool(), WheelZoomTool(), SaveTool(), ResizeTool(), ResetTool(), TapTool(),CrosshairTool(), ) plot.title.text = name plot.title.text_font="1.0em" script, div = components(plot) return [script,div] def interactive_cpchart(thedistances,thesecs,theavpower, theworkouts,promember=0): message = 0 # plot tools if (promember==1): TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,resize,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), ) ) # fitting the data to three parameter CP model 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] 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]] fitt = pd.Series(10**(4*np.arange(100)/100.)) fitpower = fitfunc(p1,fitt) 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, 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 plot.extra_y_ranges = {"watermark": watermarkrange} 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)" therows = [] for workout in theworkouts: f1 = workout.csvfilename rowdata = rdata(f1) if rowdata != 0: therows.append(rowdata) cpdata = cumcpdata(therows) 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') script, div = components(plot) return [script,div,paulslope,paulintercept,p1,message] 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 dist = rowdata.df.ix[:,'cum_dist'] try: vwind = rowdata.df.ix[:,'vwind'] winddirection = rowdata.df.ix[:,'winddirection'] bearing = rowdata.df.ix[:,'bearing'] except KeyError: rowdata.add_wind(0,0) rowdata.add_bearing() vwind = rowdata.df.ix[:,'vwind'] winddirection = rowdata.df.ix[:,'winddirection'] bearing = rowdata.df.ix[:,'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,resize,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.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" dist = rowdata.df.ix[:,'cum_dist'] try: vstream = rowdata.df.ix[:,'vstream'] except KeyError: rowdata.add_stream(0) vstream = rowdata.df.ix[:,'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,resize,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) script, div = components(plot) return [script,div] def interactive_chart(id=0,promember=0): # Add hover to this comma-separated string and see what changes if (promember==1): TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,resize,crosshair' else: TOOLS = 'pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' columns = ['time','pace','hr','fpace','ftime'] 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: datadf.sort_values(by='time',ascending=True,inplace=True) #datadf,row = dataprep.getrowdata_db(id=id) #if datadf.empty: #return "","No Valid Data Available" 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 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") 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 = ["%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) 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["hrax"] = Range1d(start=100,end=200) plot.line('time','hr',source=source,color="red", y_range_name="hrax", legend="Heart Rate") plot.add_layout(LinearAxis(y_range_name="hrax",axis_label="HR"),'right') plot.legend.location = "bottom_right" 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.ix[:,xparam] except KeyError: datadf['x1'] = datadf['distance'] try: datadf['y1'] = datadf.ix[:,yparam1] except KeyError: try: datadf['y1'] = datadf['pace'] except KeyError: return ['','

No non-zero data in selection

','',''] if yparam2 != 'None': try: datadf['y2'] = datadf.ix[:,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.ix[:,'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,resize,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 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", ) 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=100,y=130,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', ) plot.add_layout(x1means) plot.add_layout(xlabel) plot.add_layout(y1means) y1label = Label(x=100,y=100,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=100,y=70,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, 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 distance1 = data['distance'] var driveenergy1 = data['driveenergy'] var xname = data['xname'][0] var yname1 = data['yname1'][0] var yname2 = data['yname2'][0] var minspm = minspm.value var maxspm = maxspm.value var mindist = mindist.value var maxdist = maxdist.value var minwork = minwork.value var maxwork = maxwork.value var xm = 0 var ym1 = 0 var ym2 = 0 data2['x1'] = [] data2['y1'] = [] data2['y2'] = [] data2['spm'] = [] data2['distance'] = [] data2['x1mean'] = [] data2['y1mean'] = [] data2['y2mean'] = [] data2['xvals'] = [] data2['y1vals'] = [] data2['y2vals'] = [] 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['distance'].push(distance1[i]) xm += x1[i] ym1 += y1[i] ym2 += y2[i] } } } } xm /= data2['x1'].length ym1 /= data2['x1'].length ym2 /= data2['x1'].length data2['x1mean'] = [xm,xm] data2['y1mean'] = [ym1,ym1] data2['y2mean'] = [ym2,ym2] x1means.location = xm y1means.location = ym1 y2means.location = ym2 y1label.text = yname1+': '+(ym1).toFixed(2) y2label.text = yname2+': '+(ym2).toFixed(2) xlabel.text = xname+': '+(xm).toFixed(2) source2.trigger('change'); """) 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.0, end=1500,value=0.0, step=10, title="Min Work per Stroke",callback=callback) callback.args["minwork"] = slider_work_min slider_work_max = Slider(start=0.0, end=1500,value=1500.0, step=10, title="Max Work per Stroke",callback=callback) callback.args["maxwork"] = slider_work_max distmax = 100+100*int(datadf['distance'].max()/100.) slider_dist_min = Slider(start=0,end=distmax,value=0,step=1, title="Min Distance",callback=callback) callback.args["mindist"] = slider_dist_min slider_dist_max = Slider(start=0,end=distmax,value=distmax, step=1, title="Max Distance",callback=callback) callback.args["maxdist"] = slider_dist_max layout = layoutrow([layoutcolumn([slider_spm_min, slider_spm_max, slider_dist_min, slider_dist_max, slider_work_min, slider_work_max, ], ), plot]) script, div = components(layout) js_resources = INLINE.render_js() css_resources = INLINE.render_css() return [script,div,js_resources,css_resources] def interactive_flex_chart2(id=0,promember=0, xparam='time', yparam1='pace', yparam2='hr', plottype='line', workstrokesonly=False): #rowdata,row = dataprep.getrowdata_db(id=id) columns = [xparam,yparam1,yparam2, 'ftime','distance','fpace', 'power','hr','spm','driveenergy', 'time','pace','workoutstate','time'] rowdata = dataprep.getsmallrowdata_db(columns,ids=[id],doclean=True, workstrokesonly=workstrokesonly) try: tests = rowdata[yparam2] except KeyError: yparam2 = 'None' try: tests = rowdata[yparam1] except KeyError: yparam1 = 'None' rowdata.dropna(axis=1,how='all',inplace=True) rowdata.dropna(axis=0,how='any',inplace=True) # test if we have drive energy nowork = 1 try: test = rowdata['driveenergy'].mean() nowork = 0 except KeyError: rowdata['driveenergy'] = 500. # test if we have power nopower = 1 try: test = rowdata['power'].mean() nopower = 0 except KeyError: rowdata['power'] = 50. row = Workout.objects.get(id=id) if rowdata.empty: return "","No valid data" else: try: rowdata.sort_values(by='time',ascending=True,inplace=True) except KeyError: pass 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 try: tseconds = rowdata.ix[:,'time'] except KeyError: return '','No time data - cannot make flex plot','','' try: rowdata['x1'] = rowdata.ix[:,xparam] except KeyError: rowdata['x1'] = 0*rowdata.ix[:,'time'] try: rowdata['y1'] = rowdata.ix[:,yparam1] except KeyError: rowdata['y1'] = 0*rowdata.ix[:,'time'] if yparam2 != 'None': try: rowdata['y2'] = rowdata.ix[:,yparam2] except KeyError: rowdata['y2'] = 0*rowdata.ix[:,'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] # average values if xparam != 'time': try: x1mean = rowdata['x1'].mean() except TypeError: x1mean = 0 else: x1mean = 0 y1mean = rowdata['y1'].mean() y2mean = rowdata['y2'].mean() if xparam != 'time': xvals = xaxmin+np.arange(100)*(xaxmax-xaxmin)/100. else: xvals = np.arange(100) # constant power plot if yparam1 == 'driveenergy': if xparam == 'spm': yconstantpower = rowdata['y1'].mean()*rowdata['x1'].mean()/xvals x_axis_type = 'linear' y_axis_type = 'linear' if xparam == 'time': x_axis_type = 'datetime' if yparam1 == 'pace': y_axis_type = 'datetime' y1mean = rowdata.ix[:,'pace'].mean() rowdata['xname'] = axlabels[xparam] rowdata['yname1'] = axlabels[yparam1] if yparam2 != 'None': rowdata['yname2'] = axlabels[yparam2] else: rowdata['yname2'] = axlabels[yparam1] # prepare data source = ColumnDataSource( rowdata ) # second source for filtering source2 = ColumnDataSource( rowdata.copy() ) # Add hover to this comma-separated string and see what changes if (promember==1): TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,resize,crosshair' else: TOOLS = 'pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair' 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, tools=TOOLS, toolbar_sticky=False ) # add watermark 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", ) 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=100,y=130,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', ) annolabel = Label(x=100,y=500,x_units='screen',y_units='screen', text='', background_fill_alpha=0.7, background_fill_color='white', text_color='black', ) if (xparam != 'time') and (xparam != 'distance') and (xparam != 'cumdist'): plot.add_layout(x1means) plot.add_layout(xlabel) plot.add_layout(y1means) plot.add_layout(annolabel) y1label = Label(x=100,y=100,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 # average values if yparam1 == 'driveenergy': if xparam == 'spm': plot.line(xvals,yconstantpower,color="green",legend="Constant Power") if plottype=='line': plot.line('x1','y1',source=source2,legend=axlabels[yparam1]) elif plottype=='scatter': plot.scatter('x1','y1',source=source2,legend=axlabels[yparam1],fill_alpha=0.4, line_color=None) plot.title.text = row.name plot.title.text_font_size=value("1.0em") plot.xaxis.axis_label = axlabels[xparam] plot.yaxis.axis_label = axlabels[yparam1] yrange1 = Range1d(start=yaxminima[yparam1],end=yaxmaxima[yparam1]) 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", legend=axlabels[yparam2], source=source2) elif plottype=='scatter': plot.scatter('x1','y2',source=source2,legend=axlabels[yparam2] ,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]),'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=100,y=70,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) hover = plot.select(dict(type=HoverTool)) hover.tooltips = OrderedDict([ ('Time','@ftime'), ('Distance','@distance{int}'), ('Pace','@fpace'), ('HR','@hr{int}'), ('SPM','@spm{1.1}'), ('Power','@power{int}'), ]) hover.mode = 'mouse' callback = CustomJS(args = dict(source=source,source2=source2, x1means=x1means, y1means=y1means, y1label=y1label, y2label=y2label, xlabel=xlabel, annolabel=annolabel, 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 time1 = data['time'] var pace1 = data['pace'] var hr1 = data['hr'] var fpace1 = data['fpace'] var distance1 = data['distance'] var power1 = data['power'] var driveenergy1 = data['driveenergy'] var xname = data['xname'][0] var yname1 = data['yname1'][0] var yname2 = data['yname2'][0] 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 var xm = 0 var ym1 = 0 var ym2 = 0 data2['x1'] = [] data2['y1'] = [] data2['y2'] = [] data2['spm'] = [] data2['time'] = [] data2['pace'] = [] data2['hr'] = [] data2['fpace'] = [] data2['distance'] = [] data2['power'] = [] data2['x1mean'] = [] data2['y1mean'] = [] data2['y2mean'] = [] data2['xvals'] = [] data2['y1vals'] = [] data2['y2vals'] = [] 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['fpace'].push(fpace1[i]) data2['pace'].push(pace1[i]) data2['hr'].push(hr1[i]) data2['distance'].push(distance1[i]) data2['power'].push(power1[i]) xm += x1[i] ym1 += y1[i] ym2 += y2[i] } } } } xm /= data2['x1'].length ym1 /= data2['x1'].length ym2 /= data2['x1'].length data2['x1mean'] = [xm,xm] data2['y1mean'] = [ym1,ym1] data2['y2mean'] = [ym2,ym2] x1means.location = xm y1means.location = ym1 y2means.location = ym2 y1label.text = yname1+': '+ym1.toFixed(2) y2label.text = yname2+': '+ym2.toFixed(2) xlabel.text = xname+': '+xm.toFixed(2) annolabel.text = annotation source2.trigger('change'); """) 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.0, end=1500,value=0.0, step=10, title="Min Work per Stroke",callback=callback) callback.args["minwork"] = slider_work_min slider_work_max = Slider(start=0.0, end=1500,value=1500.0, 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=1, title="Min Distance",callback=callback) callback.args["mindist"] = slider_dist_min slider_dist_max = Slider(start=0,end=distmax,value=distmax, step=1, title="Max Distance",callback=callback) callback.args["maxdist"] = slider_dist_max layout = layoutrow([layoutcolumn([slider_spm_min, slider_spm_max, slider_dist_min, slider_dist_max, slider_work_min, slider_work_max, annotation, ], ), plot]) script, div = components(layout) js_resources = INLINE.render_js() css_resources = INLINE.render_css() return [script,div,js_resources,css_resources] 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,resize,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 plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_x_ranges = {"watermark": watermarkrange} 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=" 0] #datadf = datadf[datadf[xparam] > 0] # check if dataframe not empty if datadf.empty: return ['','

No non-zero data in selection

','',''] if xparam != 'distance' and xparam != 'time' and xparam != 'cumdist': xaxmax = yaxmaxima[xparam] xaxmin = yaxminima[xparam] elif xparam == 'time': xaxmax = tseconds.max() xaxmin = tseconds.min() 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,resize,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, toolbar_sticky=False) # add watermark plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_x_ranges = {"watermark": watermarkrange} 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 for id,color in itertools.izip(ids,colors): group = datadf[datadf['workoutid']==int(id)].copy() group.sort_values(by='time',ascending=True,inplace=True) group['x'] = group[xparam] try: group['y'] = group[yparam] except KeyError: group['y'] = 0.0*group['x'] ymean = group['y'].mean() ylabel = Label(x=100,y=70+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: legend=labeldict[id] else: legend=str(id) if plottype=='line': l1 = plot.line('x','y',source=source,color=color,legend=legend) else: l1 = plot.scatter('x','y',source=source,color=color,legend=legend, fill_alpha=0.4,line_color=None) plot.add_tools(HoverTool(renderers=[l1],tooltips=TIPS)) cntr += 1 plot.legend.location='bottom_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] 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']: rowdata1[n].fillna(value=0,inplace=True) rowdata2[n].fillna(value=0,inplace=True) 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.ix[:,xparam] x2 = rowdata2.ix[:,xparam] y1 = rowdata1.ix[:,yparam] y2 = rowdata2.ix[:,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.ix[:,'ftime'] ftime2 = rowdata2.ix[:,'ftime'] hr1 = rowdata1.ix[:,'hr'] hr2 = rowdata2.ix[:,'hr'] fpace1 = rowdata1.ix[:,'fpace'] fpace2 = rowdata2.ix[:,'fpace'] distance1 = rowdata1.ix[:,'distance'] distance2 = rowdata2.ix[:,'distance'] spm1 = rowdata1.ix[:,'spm'] spm2 = rowdata2.ix[:,'spm'] if (promember==1): TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,resize,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 ) # 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 plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_x_ranges = {"watermark": watermarkrange} 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] 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,resize,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 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.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' script, div = components(plot) return [script,div]