From 305dc680e7672270683464acf133fc33f40bcad0 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sun, 28 Apr 2019 18:43:18 +0200 Subject: [PATCH] added trend flex chart --- rowers/views/analysisviews.py | 196 ++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) diff --git a/rowers/views/analysisviews.py b/rowers/views/analysisviews.py index 48a426c4..dcb5a610 100644 --- a/rowers/views/analysisviews.py +++ b/rowers/views/analysisviews.py @@ -214,8 +214,202 @@ def analysis_new(request,userid=0,function='boxplot'): 'optionsform':optionsform, 'teams':get_my_teams(request.user), }) + +def trendflexdata(workouts, options,userid=0): + + includereststrokes = options['includereststrokes'] + palette = options['palette'] + groupby = options['groupby'] + binsize = options['binsize'] + xparam = options['xparam'] + yparam = options['yparam'] + spmmin = options['spmmin'] + spmmax = options['spmmax'] + workmin = options['workmin'] + workmax = options['workmax'] + ploterrorbars = options['ploterrorbars'] + ids = options['ids'] + workstrokesonly = not includereststrokes + + labeldict = { + int(w.id): w.__str__() for w in workouts + } + + fieldlist,fielddict = dataprep.getstatsfields() + fieldlist = [xparam,yparam,groupby, + 'workoutid','spm','driveenergy', + 'workoutstate'] + + # prepare data frame + datadf,extracols = dataprep.read_cols_df_sql(ids,fieldlist) + + if xparam == groupby: + datadf['groupby'] = datadf[xparam] + groupy = 'groupby' + + datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly) + + + datadf = dataprep.filter_df(datadf,'spm',spmmin, + largerthan=True) + datadf = dataprep.filter_df(datadf,'spm',spmmax, + largerthan=False) + + datadf = dataprep.filter_df(datadf,'driveenergy',workmin, + largerthan=True) + datadf = dataprep.filter_df(datadf,'driveneergy',workmax, + largerthan=False) + + + datadf.dropna(axis=0,how='any',inplace=True) + + + datemapping = { + w.id:w.date for w in workouts + } + + datadf['date'] = datadf['workoutid'] + datadf['date'].replace(datemapping,inplace=True) + + today = datetime.date.today() + datadf['days ago'] = map(lambda x : x.days, datadf.date - today) + + if groupby != 'date': + try: + bins = np.arange(datadf[groupby].min()-binsize, + datadf[groupby].max()+binsize, + binsize) + groups = datadf.groupby(pd.cut(datadf[groupby],bins,labels=False)) + except ValueError: + messages.error( + request, + "Unable to compete. Probably not enough data selected" + ) + url = reverse(user_multiflex_select) + return HttpResponseRedirect(url) + else: + bins = np.arange(datadf['days ago'].min()-binsize, + datadf['days ago'].max()+binsize, + binsize, + ) + groups = datadf.groupby(pd.cut(datadf['days ago'], bins, + labels=False)) + + + xvalues = groups.mean()[xparam] + yvalues = groups.mean()[yparam] + xerror = groups.std()[xparam] + yerror = groups.std()[yparam] + groupsize = groups.count()[xparam] + + mask = groupsize <= min([0.01*groupsize.sum(),0.2*groupsize.mean()]) + xvalues.loc[mask] = np.nan + + yvalues.loc[mask] = np.nan + xerror.loc[mask] = np.nan + yerror.loc[mask] = np.nan + groupsize.loc[mask] = np.nan + + xvalues.dropna(inplace=True) + yvalues.dropna(inplace=True) + xerror.dropna(inplace=True) + yerror.dropna(inplace=True) + groupsize.dropna(inplace=True) + + if len(groupsize) == 0: + messages.error(request,'No data in selection') + url = reverse(user_multiflex_select) + return HttpResponseRedirect(url) + else: + groupsize = 30.*np.sqrt(groupsize/float(groupsize.max())) + + df = pd.DataFrame({ + xparam:xvalues, + yparam:yvalues, + 'x':xvalues, + 'y':yvalues, + 'xerror':xerror, + 'yerror':yerror, + 'groupsize':groupsize, + }) + + + if yparam == 'pace': + df['y'] = dataprep.paceformatsecs(df['y']/1.0e3) + + aantal = len(df) + + if groupby != 'date': + try: + df['groupval'] = groups.mean()[groupby] + df['groupval'].loc[mask] = np.nan + + groupcols = df['groupval'] + except ValueError: + df['groupval'] = groups.mean()[groupby].fillna(value=0) + df['groupval'].loc[mask] = np.nan + groupcols = df['groupval'] + except KeyError: + messages.error(request,'Data selection error') + url = reverse(user_multiflex_select) + return HttpResponseRedirect(url) + else: + try: + dates = groups.min()[groupby] + dates.loc[mask] = np.nan + dates.dropna(inplace=True) + df['groupval'] = [x.strftime("%Y-%m-%d") for x in dates] + df['groupval'].loc[mask] = np.nan + groupcols = 100.*np.arange(aantal)/float(aantal) + except AttributeError: + df['groupval'] = groups.mean()['days ago'].fillna(value=0) + groupcols = 100.*np.arange(aantal)/float(aantal) + + + groupcols = (groupcols-groupcols.min())/(groupcols.max()-groupcols.min()) + + if aantal == 1: + groupcols = np.array([1.]) + colors = range_to_color_hex(groupcols,palette=palette) + + df['color'] = colors + + clegendx = np.arange(0,1.2,.2) + legcolors = range_to_color_hex(clegendx,palette=palette) + if groupby != 'date': + clegendy = df['groupval'].min()+clegendx*(df['groupval'].max()-df['groupval'].min()) + else: + clegendy = df.index.min()+clegendx*(df.index.max()-df.index.min()) + + + + colorlegend = zip(range(6),clegendy,legcolors) + + + if userid == 0: + extratitle = '' + else: + u = User.objects.get(id=userid) + extratitle = ' '+u.first_name+' '+u.last_name + + + + script,div = interactive_multiflex(df,xparam,yparam, + groupby, + extratitle=extratitle, + ploterrorbars=ploterrorbars, + binsize=binsize, + colorlegend=colorlegend, + spmmin=spmmin,spmmax=spmmax, + workmin=workmin,workmax=workmax) + + scripta= script.split('\n')[2:-1] + script = ''.join(scripta) + + return(script,div) + def boxplotdata(workouts,options): @@ -320,6 +514,8 @@ def analysis_view_data(request,userid=0): if function == 'boxplot': script, div = boxplotdata(workouts,options) + elif function == 'trendflex': + script, div = trendflexdata(workouts, options,userid=userid) else: script = '' div = 'Unknown analysis functions'