Private
Public Access
1
0

Merge branch 'release/v3.43'

This commit is contained in:
Sander Roosendaal
2017-07-11 15:52:39 +02:00
4 changed files with 146 additions and 25 deletions
+9 -1
View File
@@ -327,6 +327,11 @@ formaxlabelsmultiflex.pop('distance')
formaxlabelsmultiflex['workoutid'] = 'Workout'
parchoicesmultiflex = list(sorted(formaxlabelsmultiflex.items(), key = lambda x:x[1]))
from utils import palettes
#palettechoices = { key:key for key, value in palettes.iteritems() }
palettechoices = tuple((p,p) for p in palettes.keys())
class MultiFlexChoiceForm(forms.Form):
xparam = forms.ChoiceField(choices=parchoicesmultiflex,
@@ -352,7 +357,10 @@ class MultiFlexChoiceForm(forms.Form):
includereststrokes = forms.BooleanField(initial=False,
required=False,
label='Include Rest Strokes')
palette = forms.ChoiceField(choices=palettechoices,
label = 'Color Scheme',
initial='monochrome_blue')
class ChartParamChoiceForm(forms.Form):
plotchoices = (
('line','Line Plot'),
+57 -14
View File
@@ -1,3 +1,4 @@
import colorsys
from rowers.models import Workout, User, Rower, WorkoutForm,RowerForm,GraphImage
from rowingdata import rower as rrower
from rowingdata import main as rmain
@@ -10,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
@@ -70,11 +71,9 @@ watermarkh = 35
watermarkanchor = 'bottom_right'
def errorbar(fig, x, y, source=ColumnDataSource(),
xerr=False, yerr=False, color='red',
xerr=False, yerr=False, color='black',
point_kwargs={}, error_kwargs={}):
fig.circle(x, y, source=source, name='data',color=color,
**point_kwargs)
xvalues = source.data[x]
yvalues = source.data[y]
@@ -96,7 +95,12 @@ def errorbar(fig, x, y, source=ColumnDataSource(),
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))
err_color.append(color)
(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',
@@ -113,13 +117,22 @@ def errorbar(fig, x, y, source=ColumnDataSource(),
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))
err_color.append(color)
(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
@@ -1176,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 ['','<p>No non-zero data in selection</p>']
@@ -1246,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'
@@ -1268,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}
@@ -1287,17 +1299,48 @@ 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,
point_kwargs={
'line_color':None,
'line_color':"#969696",
'size':"groupsize",
'fill_color':"color",
'fill_alpha':1.0,
},
)
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,
fill_alpha=1.0,
line_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:
+50
View File
@@ -1,9 +1,59 @@
import math
import numpy as np
import pandas as pd
import colorsys
lbstoN = 4.44822
def trcolors(r1,g1,b1,r2,g2,b2):
r1 = r1/255.
r2 = r2/255.
g1 = g1/255.
g2 = g2/255.
b2 = b2/255.
b1 = b1/255.
h1,s1,v1 = colorsys.rgb_to_hsv(r1,g1,b1)
h2,s2,v2 = colorsys.rgb_to_hsv(r2,g2,b2)
return 360*h1,360*(h2-h1),s1,(s2-s1),v1,(v2-v1)
palettes = {
'monochrome_blue':(207,-4,0.06,0.89,1.0,-0.38),
'gold_sunset':(47,-31,.26,-0.12,0.94,-0.5),
'blue_red':(207,-200,.85,0,.74,-.24),
'blue_green':(207,-120,.85,0,.75,.25),
'cyan_green':(192,-50,.08,.65,.98,-.34),
'cyan_purple':trcolors(237,248,251,136,65,157),
'green_blue':trcolors(240,249,232,8,104,172),
'orange_red':trcolors(254,240,217,179,0,0),
'cyan_blue':trcolors(241,238,246,4,90,141),
'cyan_green':trcolors(246,239,247,1,108,89),
'cyan_magenta':trcolors(241,238,246,152,0,67),
'beige_magenta':trcolors(254,235,226,122,1,119),
'yellow_green':trcolors(255,255,204,0,104,55),
'yellow_blue':trcolors(255,255,205,37,52,148),
'autumn':trcolors(255,255,212,153,52,4),
'yellow_red':trcolors(255,255,178,189,0,39)
}
def range_to_color_hex(groupcols,palette='monochrome_blue'):
try:
plt = palettes[palette]
except KeyErro:
plt = palettes['monochrome_blue']
rgb = [colorsys.hsv_to_rgb((plt[0]+plt[1]*x)/360.,
plt[2]+plt[3]*x,
plt[4]+plt[5]*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")
+30 -10
View File
@@ -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
@@ -3435,6 +3435,11 @@ def multiflex_view(request,userid=0,
ploterrorbars = options['ploterrorbars']
except KeyError:
ploterrorbars = False
try:
palette = options['palette']
except KeyError:
palette = 'blue_green'
workstrokesonly = not includereststrokes
@@ -3454,7 +3459,9 @@ def multiflex_view(request,userid=0,
request.session['ploterrorbars'] = ploterrorbars
request.session['includereststrokes'] = includereststrokes
workstrokesonly = not includereststrokes
palette = chartform.cleaned_data['palette']
request.session['palette'] = palette
groupby = chartform.cleaned_data['groupby']
binsize = chartform.cleaned_data['binsize']
if binsize <= 0:
@@ -3482,6 +3489,8 @@ def multiflex_view(request,userid=0,
request.session['ploterrorbars'] = ploterrorbars
request.session['includereststrokes'] = includereststrokes
workstrokesonly = not includereststrokes
palette = chartform.cleaned_data['palette']
request.session['palette'] = palette
groupby = chartform.cleaned_data['groupby']
binsize = chartform.cleaned_data['binsize']
@@ -3570,9 +3579,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,12 +3616,19 @@ def multiflex_view(request,userid=0,
if aantal == 1:
groupcols = np.array([1.])
groupcols *= 100.
rgb = [colorsys.hsv_to_rgb(float(x/100.), 1.0, 1.0) 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]
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)
clegendy = df['groupval'].min()+clegendx*(df['groupval'].max()-df['groupval'].min())
colorlegend = zip(range(6),clegendy,legcolors)
if userid == 0:
extratitle = ''
else:
@@ -3622,7 +3641,8 @@ def multiflex_view(request,userid=0,
groupby,
extratitle=extratitle,
ploterrorbars=ploterrorbars,
binsize=binsize)
binsize=binsize,
colorlegend=colorlegend)