diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py index fe428a73..0a4b2abc 100644 --- a/rowers/interactiveplots.py +++ b/rowers/interactiveplots.py @@ -11,7 +11,7 @@ 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.models import CustomJS,Slider, TextInput,BoxAnnotation from bokeh.charts import Histogram,HeatMap,Area,BoxPlot from bokeh.resources import CDN,INLINE from bokeh.embed import components @@ -1189,7 +1189,7 @@ def interactive_chart(id=0,promember=0): def interactive_multiflex(datadf,xparam,yparam,groupby,extratitle='', ploterrorbars=False, - title=None,binsize=1): + title=None,binsize=1,colorlegend=[]): if datadf.empty: return ['','

No non-zero data in selection

'] @@ -1259,18 +1259,17 @@ def interactive_multiflex(datadf,xparam,yparam,groupby,extratitle='', datadf, ) - TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,resize' if groupby != 'date': hover = HoverTool(names=['data'], tooltips = [ - (groupby,'@groupval{1.1}') + (groupby,'@groupval{1.1}'), ]) else: hover = HoverTool(names=['data'], tooltips = [ - (groupby,'@groupval') + (groupby,'@groupval'), ]) hover.mode = 'mouse' @@ -1281,7 +1280,7 @@ def interactive_multiflex(datadf,xparam,yparam,groupby,extratitle='', plot = Figure(x_axis_type=x_axis_type,y_axis_type=y_axis_type, tools=TOOLS, toolbar_location="above", - toolbar_sticky=False) + toolbar_sticky=False) #,plot_width=500,plot_height=500) # add watermark plot.extra_y_ranges = {"watermark": watermarkrange} @@ -1300,7 +1299,7 @@ def interactive_multiflex(datadf,xparam,yparam,groupby,extratitle='', x_range_name = "watermark", y_range_name = "watermark", ) - + errorbar(plot,xparam,yparam,source=source, xerr=ploterrorbars, yerr=ploterrorbars, @@ -1311,6 +1310,34 @@ def interactive_multiflex(datadf,xparam,yparam,groupby,extratitle='', }, ) + + + for nr, gvalue, color in colorlegend: + box = BoxAnnotation(bottom=500-20*nr,left=550,top=520-20*nr, + right=570, + bottom_units='screen', + top_units='screen', + left_units='screen', + right_units='screen', + fill_color=color) + legendlabel = Label(x=571,y=503-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=372,y=300,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: diff --git a/rowers/utils.py b/rowers/utils.py index 526dd327..51339a53 100644 --- a/rowers/utils.py +++ b/rowers/utils.py @@ -1,9 +1,20 @@ import math import numpy as np import pandas as pd +import colorsys lbstoN = 4.44822 +def range_to_color_hex(groupcols): + rgb = [colorsys.hsv_to_rgb((207-4*x)/360., + 0.06+0.89*x, + 1-0.38*x) for x in groupcols] + + RGB = [(int(255.*r),int(255.*g),int(255.*b)) for (r, g, b) in rgb] + colors = ["#%02x%02x%02x" % (r, g, b) for (r, g, b) in RGB] + + return colors + def str2bool(v): return v.lower() in ("yes", "true", "t", "1") diff --git a/rowers/views.py b/rowers/views.py index 6527134a..c4f274bd 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -272,7 +272,7 @@ def splitstdata(lijst): from utils import ( geo_distance,serialize_list,deserialize_list,uniqify, - str2bool + str2bool,range_to_color_hex ) import datautils @@ -3570,9 +3570,12 @@ def multiflex_view(request,userid=0, yerror = groups.std()[yparam] groupsize = groups.count()[xparam] - #groupsize = 15.*np.log10(1+99.*groupsize/float(max(groupsize))) - groupsize = 30.*np.sqrt(groupsize/float(max(groupsize))) - + 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, @@ -3604,16 +3607,19 @@ def multiflex_view(request,userid=0, if aantal == 1: groupcols = np.array([1.]) - # rgb = [colorsys.hsv_to_rgb(float(x/100.), 1.0, 1.0) for x in groupcols] - rgb = [colorsys.hsv_to_rgb((207-4*x)/360., - 0.06+0.89*x, - 1-0.38*x) for x in groupcols] - groupcols *= 100. - RGB = [(int(255.*r),int(255.*g),int(255.*b)) for (r, g, b) in rgb] - colors = ["#%02x%02x%02x" % (r, g, b) for (r, g, b) in RGB] + colors = range_to_color_hex(groupcols) + df['color'] = colors + clegendx = np.arange(0,1.2,.2) + legcolors = range_to_color_hex(clegendx) + clegendy = df['groupval'].min()+clegendx*(df['groupval'].max()-df['groupval'].min()) + + + colorlegend = zip(range(6),clegendy,legcolors) + + if userid == 0: extratitle = '' else: @@ -3626,7 +3632,8 @@ def multiflex_view(request,userid=0, groupby, extratitle=extratitle, ploterrorbars=ploterrorbars, - binsize=binsize) + binsize=binsize, + colorlegend=colorlegend)