Here are the examples of the python api bokeh.plotting.curdoc taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.
14 Examples
3
View Source File : uibokeh.py
License : Apache License 2.0
Project Creator : OpendTect
License : Apache License 2.0
Project Creator : OpendTect
def setReady( runbutbar ):
runbutbar['state'] = RunState.Ready
runbutbar['run'].label = go_lbl
runbutbar['run'].button_type = enums.ButtonType.success
runbutbar['pause'].visible = False
if 'cb' in runbutbar:
cb = runbutbar.pop( 'cb' )
curdoc().remove_periodic_callback( cb )
def setPaused( runbutbar ):
3
View Source File : dashboard.py
License : MIT License
Project Creator : pfnet-research
License : MIT License
Project Creator : pfnet-research
def _run():
# type: () -> None
# Please note that `_study` and `optuna.dashboard._study` are different here. Here, this module
# is loaded inside Bokeh, and thus it is not `optuna.dashboard`, but `bk_script_????`.
study = optuna.dashboard._study
mode = optuna.dashboard._mode
assert study is not None
app = _DashboardApp(study, launch_update_thread=(mode == 'serve'))
doc = bokeh.plotting.curdoc()
app(doc)
if __name__.startswith('bk_script_'):
0
View Source File : detfl_iJO1366.py
License : Apache License 2.0
Project Creator : EPFL-LCSB
License : Apache License 2.0
Project Creator : EPFL-LCSB
def plot_dynamics(model, time_data):
bp.curdoc().clear()
# time_data += model.solver.configuration.tolerances.feasibility
p1 = bp.figure(y_axis_type = 'log')
p2 = bp.figure(y_axis_type = 'log')
p3 = bp.figure(y_axis_type = 'log')
p4 = bp.figure(y_axis_type = 'log')
pex = bp.figure()
t = time_data.loc['t']
vars_to_obs = ['MR_b4025', 'MR_b1779', 'EZ_rib', 'EZ_rnap']
cmap = Category10[10]
for e, the_var in enumerate(['S_EX_glc__D_e','S_EX_glyc_e','X']):
plot_hist(p1, t, time_data, the_var, cmap[e])
rev_glc = model.reactions.EX_glc__D_e.reverse_variable.name
for e, the_var in enumerate(['ub_EX_glc__D_e', 'ub_EX_glyc_e',
'act_EX_glc__D_e', 'act_EX_glyc_e',
'mu']):
shape = 'square' if the_var.startswith('act_') else 'circle'
plot_hist(p2, t, time_data, the_var, cmap[e], marker=shape)
glycolysis_enzymes = get_enzymes_of_subsystem(model, 'Glycolysis')
ppp_enzymes = get_enzymes_of_subsystem(model, 'pentose phosphate')
tca_enzymes = get_enzymes_of_subsystem(model, 'Citric Acid Cycle')
for e, the_var in enumerate(vars_to_obs):
plot_hist(p3, t, time_data, the_var, cmap[e])
time_data.loc['glycolysis'] = get_prot_total(time_data, glycolysis_enzymes)
time_data.loc['ppp'] = get_prot_total(time_data, ppp_enzymes)
time_data.loc['tca'] = get_prot_total(time_data, tca_enzymes)
plot_hist(p4, t, time_data, 'glycolysis', cmap[e+1])
plot_hist(p4, t, time_data, 'ppp', cmap[e+2])
plot_hist(p4, t, time_data, 'tca', cmap[e+3])
effluxes = time_data.loc[ time_data.index.str.startswith('EX_')
& time_data.index.str.endswith('_e') ]
effluxes['score'] = effluxes.std(axis=1) / effluxes.mean(axis=1)
effluxes = effluxes.reindex(
effluxes['score'].sort_values(ascending = False).index,
axis=0)
for e,(the_var, values) in enumerate(effluxes[:5].T.iteritems()):
pex.line(t, values,
color = cmap[e],
line_width = 2,
legend=the_var)
for p in [p1,p2,p3,p4,pex]:
# p.legend.location = 'top_left'
p.output_backend = 'svg'
gp = gridplot([[p1,p3],[p2,p4],[pex]])
bp.output_file('plots/dETFL_cheby_glyc.html')
bp.show(gp)
export_svgs(gp, filename='plots/dETFL_cheby_glyc.svg')
def plot_hist(figure, t, time_data, the_var, color, marker='circle'):
0
View Source File : detfl_monod.py
License : Apache License 2.0
Project Creator : EPFL-LCSB
License : Apache License 2.0
Project Creator : EPFL-LCSB
def plot_dynamics(model, time_data):
bp.curdoc().clear()
# time_data += model.solver.configuration.tolerances.feasibility
p1 = bp.figure()#y_axis_type = 'log')
p2 = bp.figure()#y_axis_type = 'log')
p3 = bp.figure(y_axis_type = 'log')
p4 = bp.figure(y_axis_type = 'log')
ps = bp.figure()
px = bp.figure()
t = time_data.loc['t']
vars_to_obs = ['MR_b4025', 'MR_b1779', 'EZ_rib', 'EZ_rnap']
cmap = Category10[10]
for e, the_var in enumerate(concentrations):
plot_var(p1, t, time_data, the_var, cmap[e])
for e, (the_flux, the_ub) in enumerate(flux_ubs):
plot_ub (p2, t, time_data, the_ub , color=cmap[e])
plot_var(p2, t, time_data, the_flux, color=cmap[e])
p2.legend.location = 'bottom_right'
plot_var(p2,t,time_data, 'mu', color=cmap[e+1])
plot_growth(px,t,time_data)
glycolysis_enzymes = get_enzymes_of_subsystem(model, 'Glycolysis')
ppp_enzymes = get_enzymes_of_subsystem(model, 'pentose phosphate')
tca_enzymes = get_enzymes_of_subsystem(model, 'Citric Acid Cycle')
for e, the_var in enumerate(vars_to_obs):
plot_var(p3, t, time_data, the_var, cmap[e])
time_data.loc['glycolysis',:] = get_prot_total(time_data, glycolysis_enzymes)
time_data.loc['ppp',:] = get_prot_total(time_data, ppp_enzymes)
time_data.loc['tca',:] = get_prot_total(time_data, tca_enzymes)
plot_var(p4, t, time_data, 'glycolysis', cmap[e + 1])
plot_var(p4, t, time_data, 'ppp', cmap[e + 2])
plot_var(p4, t, time_data, 'tca', cmap[e + 3])
effluxes = time_data.loc[ time_data.index.str.startswith('EX_')
& time_data.index.str.endswith('_e') ]
effluxes['score'] = effluxes.std(axis=1) / effluxes.mean(axis=1)
effluxes = effluxes.reindex(
effluxes['score'].sort_values(ascending = False).index,
axis=0)
# for e,(the_var, values) in enumerate(effluxes[:5].T.iteritems()):
#
# pex.line(t, values,
# color = cmap[e],
# line_width = 2,
# legend=the_var)
plot_subsystems(ps,t,model,time_data)
for p in [p1,p2,p3,p4,ps,px]:
# p.legend.location = 'top_left'
p.output_backend = 'svg'
gp = gridplot([[p1,p3],[p2,p4],[ps,px]])
bp.output_file('plots/{}.html'.format(model_tag))
bp.show(gp)
export_svgs(gp, filename='plots/{}.svg'.format(model_tag))
def plot_var(p, t, time_data, the_var, color, **kwargs):
0
View Source File : plot_expression_va.py
License : Apache License 2.0
Project Creator : EPFL-LCSB
License : Apache License 2.0
Project Creator : EPFL-LCSB
def plot_va(filename, tag, kind, color = DEFAULT_COLOR, orient = 'horizontal'):
bp.curdoc().clear()
title = verbose_kinds[kind] + ' variability analysis for {} iJO1366 model'\
.format(tag)
data = pd.read_csv(os.path.join(outputs_folder, filename), index_col = 0)
if not data.columns[0] in ['minimum','maximum']:
data.columns = ['minimum','maximum']
data += 1e-9 # Resolution of the solver
f = lambda x: np.sqrt(x[0]*x[1])
# data['score'] = data.mean(axis=1)
data['score'] = data.apply(f, axis=1)
data.sort_values(by='score', ascending = False, inplace = True)
data['y'] = range(len(data))
data['name'] = data.index
source = ColumnDataSource(data)
xdr = DataRange1d()
ydr = DataRange1d()
_tools_to_show = 'box_zoom,pan,save,hover,reset,tap,wheel_zoom'
if orient == 'vertical':
p1 = bp.figure( title=title, x_range=xdr, y_range=ydr,
x_axis_type = 'log',
plot_width=600,
plot_height=1000,
tools=_tools_to_show,
# h_symmetry=False, v_symmetry=False,
min_border=0)
glyph = HBar(y="y", right="maximum", left="minimum", height=0.9,
fill_color=color, fill_alpha=0.5,
line_color = None)
p1.add_glyph(source, glyph)
p1.circle(x='score', y='y', fill_color=color, line_color=None,
source=source)
axis1 = p1.xaxis
axis2 = p1.yaxis
elif orient == 'horizontal':
p1 = bp.figure(title=title, x_range=ydr, y_range=xdr,
y_axis_type='log',
plot_width=1000,
plot_height=600,
tools=_tools_to_show,
# h_symmetry=False, v_symmetry=False,
min_border=0)
glyph = VBar(x="y", top="maximum", bottom="minimum", width=0.9,
fill_color=color, fill_alpha=0.5,
line_color=None)
p1.add_glyph(source, glyph)
p1.circle(y='score', x='y', fill_color=color, line_color=None,
source=source)
axis1 = p1.yaxis
axis2 = p1.xaxis
else:
raise ValueError("orient should be 'vertical' or 'horizontal'")
# Fix ticks
label_dict = {}
for i, s in enumerate(data.index):
label_dict[i] = s
axis2.formatter = FuncTickFormatter(code="""
var labels = %s;
return labels[tick];
""" % label_dict)
axis1.axis_label = '[{}]'.format(verbose_kinds[kind])
# p1.yaxis.ticker = [x for x in range(len(data))]
hover = p1.select(dict(type=HoverTool))
hover.tooltips = [(verbose_kinds[kind], "@name"),
("min", "@minimum"),
("max", "@maximum"),
]
hover.mode = 'mouse'
path = os.path.join(plots_folder, 'va_' + filename)
bp.output_file(path + '.html')
bp.show(p1)
p1.output_backend='svg'
export_svgs(p1, filename=path+'.svg')
bp.curdoc().clear()
return data
if __name__ == '__main__':
0
View Source File : viz_constraint_matix.py
License : Apache License 2.0
Project Creator : EPFL-LCSB
License : Apache License 2.0
Project Creator : EPFL-LCSB
def plot_spy_matrix(model, destination):
nzs = pd.DataFrame(get_matrix_coo_gurobi(model),
columns=['row_idx',
'col_idx',
'coeff',
'var_name',
'var_type',
'cons_name'])
nzs = add_color_group(nzs)
nzs['row_idx'] *= -1
bp.curdoc().clear()
hover = HoverTool(tooltips=[("constraint name", "@cons_name"),
("variable name", "@var_name"),
("coefficient", "@coeff"),
("(x,y)", "(@col_idx, @row_idx)"),
("type", "@var_type"), ])
p = bp.figure(width = 1000)
p.add_tools(hover)
legend_it = []
for e, (subgroup, this_data) in enumerate(nzs.groupby('groups')):
source = ColumnDataSource.from_df(this_data)
# if this_data['var_type'].iloc[0] in ['I', 'B']:
# plot_fun = p.square
# else:
# plot_fun = p.circle
plot_fun = p.square
c = plot_fun('col_idx', 'row_idx',
color = tableau20[e],
source = source,
size = 2,
alpha=1)
legend_it.append((subgroup,[c]))
legend = Legend(items=legend_it, location=(0, 0))
legend.click_policy = "mute"
p.add_layout(legend, 'right')
bp.output_file(destination)
bp.show(p)
return p
0
View Source File : plotting.py
License : Apache License 2.0
Project Creator : EPFL-LCSB
License : Apache License 2.0
Project Creator : EPFL-LCSB
def summarize_model(model,time_data,groups,
output_path='.', model_tag='', backend ='png'):
summary_plots = dict()
detailed_plots = dict()
cleaned_groups = dict()
# Cleanup missing vars
for key, varnames in groups.items():
cleaned_groups[key] = [x for x in varnames if x in time_data.index or x == 'total']
groups = cleaned_groups
total_groups = {k:v for k,v in groups.items() if 'total' in v and 'pathway_enz' in k}
for key,data_type in groups.items():
summary_plots[key] = make_summary_plots(model,time_data,key,data_type)
detailed_plots[key] = make_detailed_plots(model,time_data,data_type,backend)
summary_plots['growth'] = make_growth_plot(model,time_data)
summary_plots['mass_ratios'] = plot_mass(model,time_data)
if model is not None:
summary_plots['subsystems'] = plot_subsystems(model,time_data)
summary_plots['total'] = make_total_plot(model, time_data, total_groups)
output_folder = join(output_path)#,model_tag)#+'_'+get_timestr())
if not exists(output_folder):
makedirs(output_folder)
bp.curdoc().clear()
bp.output_file(join(output_folder,'summary.html'), title = model_tag)
for p in summary_plots.values():
p.output_backend = backend
bp.show(column(list(summary_plots.values())))
for key,this_dp in detailed_plots.items():
bp.curdoc().clear()
bp.output_file(join(output_folder,'{}.html'.format(key)))
for p in this_dp.children:
try:
p.output_backend = backend
except AttributeError:
# Fails for gridplots
pass
# from bokeh.layouts import GridBox
# if isinstance(p,GridBox):
# p.children[0][0].output_backend = backend
# else: # Toolbox bar etc..
# pass
bp.show(this_dp)
def make_summary_plots(model, time_data, key, data_type, total=False):
0
View Source File : bokeh_server.py
License : MIT License
Project Creator : karlicoss
License : MIT License
Project Creator : karlicoss
def bokeh_main():
from random import random
# create a plot and style its properties
p = figure(x_range=(0, 100), y_range=(0, 100), toolbar_location=None)
p.border_fill_color = 'black'
p.background_fill_color = 'black'
p.outline_line_color = None
p.grid.grid_line_color = None
# add a text renderer to our plot (no data yet)
r = p.text(x=[], y=[], text=[], text_color=[], text_font_size="26px",
text_baseline="middle", text_align="center")
i = 0
ds = r.data_source
# create a callback that will add a number in a random location
def callback():
nonlocal i
# BEST PRACTICE --- update .data in one step with a new dict
new_data = dict()
new_data['x'] = ds.data['x'] + [random()*70 + 15]
new_data['y'] = ds.data['y'] + [random()*70 + 15]
new_data['text_color'] = ds.data['text_color'] + [RdYlBu3[i%3]]
new_data['text'] = ds.data['text'] + [str(i)]
ds.data = new_data
i = i + 1
# add a button widget and configure with the call back
button = Button(label="Press Me")
button.on_click(callback)
# put the button and plot in a layout and add to the document
curdoc().add_root(column(button, p))
# todo autogenerate all plot tabs? maybe based on annotations?
def bokeh_main_2():
0
View Source File : bokeh_server.py
License : MIT License
Project Creator : karlicoss
License : MIT License
Project Creator : karlicoss
def bokeh_main_2():
import sys
src = Path(__file__).absolute().parent / 'src'
sys.path.insert(0, str(src))
from bokeh.layouts import layout # type: ignore
from bokeh.models.widgets import Tabs, Panel # type: ignore
from bokeh.plotting import figure # type: ignore
from dashboard.core.bokeh import test_scatter_matrix
import holoviews as hv
f1 = hv.render(test_scatter_matrix())
f2 = figure()
f2.circle([0,0,2],[4,-1,1])
# todo need something more lazy?
from dashboard.data import sleep_dataframe
from dashboard.sleep import plot_sleep
# TODO would be cool to display logs in the frontend and also currently evaluated function?
# although pehaps it's easier to just always keep logs open?
from bokeh.models.widgets import DateRangeSlider # type: ignore
from datetime import date
drs = DateRangeSlider(
title="Date Range: ",
start=date(2017, 1, 1),
end=date.today(),
value=(date(2017, 9, 7), date(2017, 10, 15)),
step=1,
)
def update(attr, old, new):
print(attr, old, new)
from bokeh.models import CustomJS # type: ignore
# todo see https://docs.bokeh.org/en/latest/docs/gallery/slider.html
update_js = CustomJS(
args=dict(drs=drs),
code='''
console.log("HIIII");
'''
)
drs.on_change('value', update)
drs.js_on_change('value', update_js)
l1 = layout([[f1, drs]], sizing_mode='fixed')
l2 = layout([[f2]], sizing_mode='fixed')
tabs = Tabs(tabs=[
Panel(child=l1 , title='This is Tab 1' ),
Panel(child=l2 , title='This is Tab 2' ),
# Panel(child=layout([[sp]]), title='Sleep dataframe'),
])
curdoc().add_root(tabs)
def main():
0
View Source File : main.py
License : MIT License
Project Creator : MathOnco
License : MIT License
Project Creator : MathOnco
def button_callback():
theme_t = theme_select.value
if(theme_t == 'black'):
curdoc().theme= theme_black
elif(theme_t == 'gray'):
curdoc().theme= theme_gray
elif(theme_t == 'dark blue'):
curdoc().theme= theme_blue
jk = create_figure(stack_montage_flag)
layout.children[1] = jk[0]
print('############')
print('In Button callback')
tsne3 = jk[1]
print(type(tsne3))
print(tsne3)
file_name_hover = jk[2]
print('############fnh in button callback')
print('file_name_hover')
print(file_name_hover)
markers_single = jk[3]
print('############')
print(type(markers_single))
print(markers_single)
cluster_ms_list = jk[4]
print('############')
print(type(cluster_ms_list ))
print(cluster_ms_list )
p1_out = draw_tSNE_scatter(tsne3, file_name_hover, cluster_ms_list)
p1 = p1_out[0]
p2 = p1_out[1]
p3 = p1_out[2]
p4 = p1_out[3]
source = p1_out[4]
tab1 = Panel(child=p1, title="Response")
tab2 = Panel(child=p2, title="Treatment")
tab3 = Panel(child=p3, title="Cluster Annotations")
tab4 = Panel(child=p4, title="Patient id")
tabs = Tabs(tabs=[ tab1, tab2, tab3, tab4 ])
layout.children[2] = tabs
return([p,p1,p2,p3,p4,source,tabs])
############################################################################
### create_figure() collects the user choices from the GUI and ####
### calls either the generate_stack_montage() for reading in ####
### a single image or the generate_image_tSNE() for multiplexed images ####
############################################################################
def create_figure(stack_montage_flag):
0
View Source File : simulate.py
License : MIT License
Project Creator : microsoft
License : MIT License
Project Creator : microsoft
def simulate(self,
agents: List[Agent],
baseline_accuracy: float = None,
init_train_data_portion: float = 0.1,
pm_test_sets: list = None,
accuracy_plot_wait_s=2E5,
train_size: int = None, test_size: int = None,
filename_indicator: str = None
):
"""
Run a simulation.
:param agents: The agents that will interact with the data.
:param baseline_accuracy: The baseline accuracy of the model.
Usually the accuracy on a hidden test set when the model is trained with all data.
:param init_train_data_portion: The portion of the data to initially use for training. Must be [0,1].
:param pm_test_sets: The test sets for the prediction market incentive mechanism.
:param accuracy_plot_wait_s: The amount of time to wait in seconds between plotting the accuracy.
:param train_size: The amount of training data to use.
:param test_size: The amount of test data to use.
:param filename_indicator: Path of the filename to create for the run.
"""
assert 0 < = init_train_data_portion < = 1
# Data to save.
save_data = dict(agents=[asdict(a) for a in agents],
baselineAccuracy=baseline_accuracy,
initTrainDataPortion=init_train_data_portion,
accuracies=[],
balances=[],
)
time_for_filenames = int(time.time())
save_path = f'saved_runs/{time_for_filenames}-{filename_indicator}-simulation_data.json'
model_save_path = f'saved_runs/{time_for_filenames}-{filename_indicator}-model.json'
plot_save_path = f'saved_runs/{time_for_filenames}-{filename_indicator}.png'
self._logger.info("Saving run info to \"%s\".", save_path)
os.makedirs(os.path.dirname(save_path), exist_ok=True)
# Set up plots.
doc: Document = curdoc()
doc.title = "DeCAI Simulation"
plot = figure(title="Balances & Accuracy on Hidden Test Set",
)
plot.width = 800
plot.height = 600
plot.xaxis.axis_label = "Time (days)"
plot.yaxis.axis_label = "Percent"
plot.title.text_font_size = '20pt'
plot.xaxis.major_label_text_font_size = '20pt'
plot.xaxis.axis_label_text_font_size = '20pt'
plot.yaxis.major_label_text_font_size = '20pt'
plot.yaxis.axis_label_text_font_size = '20pt'
plot.xaxis[0].ticker = AdaptiveTicker(base=5 * 24 * 60 * 60)
plot.xgrid[0].ticker = AdaptiveTicker(base=24 * 60 * 60)
balance_plot_sources_per_agent = dict()
good_colors = cycle([
colors.named.green,
colors.named.lawngreen,
colors.named.darkgreen,
colors.named.limegreen,
])
bad_colors = cycle([
colors.named.red,
colors.named.darkred,
])
for agent in agents:
source = ColumnDataSource(dict(t=[], b=[]))
assert agent.address not in balance_plot_sources_per_agent
balance_plot_sources_per_agent[agent.address] = source
if agent.calls_model:
color = 'blue'
line_dash = 'dashdot'
elif agent.good:
color = next(good_colors)
line_dash = 'dotted'
else:
color = next(bad_colors)
line_dash = 'dashed'
plot.line(x='t', y='b',
line_dash=line_dash,
line_width=2,
source=source,
color=color,
legend=f"{agent.address} Balance")
plot.legend.location = 'top_left'
plot.legend.label_text_font_size = '12pt'
# JavaScript code.
plot.xaxis[0].formatter = FuncTickFormatter(code="""
return (tick / 86400).toFixed(0);
""")
plot.yaxis[0].formatter = PrintfTickFormatter(format="%0.1f%%")
acc_source = ColumnDataSource(dict(t=[], a=[]))
if baseline_accuracy is not None:
plot.ray(x=[0], y=[baseline_accuracy * 100], length=0, angle=0, line_width=2,
legend=f"Accuracy when trained with all data: {baseline_accuracy * 100:0.1f}%")
plot.line(x='t', y='a',
line_dash='solid',
line_width=2,
source=acc_source,
color='black',
legend="Current Accuracy")
@gen.coroutine
def plot_cb(agent: Agent, t, b):
source = balance_plot_sources_per_agent[agent.address]
source.stream(dict(t=[t], b=[b * 100 / agent.start_balance]))
save_data['balances'].append(dict(t=t, a=agent.address, b=b))
@gen.coroutine
def plot_accuracy_cb(t, a):
acc_source.stream(dict(t=[t], a=[a * 100]))
save_data['accuracies'].append(dict(t=t, accuracy=a))
continuous_evaluation = not isinstance(self._decai.im, PredictionMarket)
def task():
(x_train, y_train), (x_test, y_test) = \
self._data_loader.load_data(train_size=train_size, test_size=test_size)
classifications = self._data_loader.classifications()
x_train, x_test, feature_index_mapping = self._feature_index_mapper.map(x_train, x_test)
x_train_len = x_train.shape[0]
init_idx = int(x_train_len * init_train_data_portion)
self._logger.info("Initializing model with %d out of %d samples.",
init_idx, x_train_len)
x_init_data, y_init_data = x_train[:init_idx], y_train[:init_idx]
x_remaining, y_remaining = x_train[init_idx:], y_train[init_idx:]
save_model = isinstance(self._decai.im, PredictionMarket) and self._decai.im.reset_model_during_reward_phase
self._decai.model.init_model(x_init_data, y_init_data, save_model)
if self._logger.isEnabledFor(logging.DEBUG):
s = self._decai.model.evaluate(x_init_data, y_init_data)
self._logger.debug("Initial training data evaluation: %s", s)
if len(x_remaining) > 0:
s = self._decai.model.evaluate(x_remaining, y_remaining)
self._logger.debug("Remaining training data evaluation: %s", s)
else:
self._logger.debug("There is no more remaining data to evaluate.")
self._logger.info("Evaluating initial model.")
accuracy = self._decai.model.log_evaluation_details(x_test, y_test)
self._logger.info("Initial test set accuracy: %0.2f%%", accuracy * 100)
t = self._time()
doc.add_next_tick_callback(
partial(plot_accuracy_cb, t=t, a=accuracy))
q = PriorityQueue()
random.shuffle(agents)
for agent in agents:
self._balances.initialize(agent.address, agent.start_balance)
q.put((self._time() + agent.get_next_wait_s(), agent))
doc.add_next_tick_callback(
partial(plot_cb, agent=agent, t=t, b=agent.start_balance))
unclaimed_data = []
next_data_index = 0
next_accuracy_plot_time = 1E4
desc = "Processing agent requests"
current_time = 0
with tqdm(desc=desc,
unit_scale=True, mininterval=2, unit=" requests",
total=len(x_remaining),
) as pbar:
while not q.empty():
# For now assume sending a transaction (editing) is free (no gas)
# since it should be relatively cheaper than the deposit required to add data.
# It may not be cheaper than calling `report`.
if next_data_index >= len(x_remaining):
if not continuous_evaluation or len(unclaimed_data) == 0:
break
current_time, agent = q.get()
update_balance_plot = False
if current_time > next_accuracy_plot_time:
self._logger.debug("Evaluating.")
next_accuracy_plot_time += accuracy_plot_wait_s
accuracy = self._decai.model.evaluate(x_test, y_test)
doc.add_next_tick_callback(
partial(plot_accuracy_cb, t=current_time, a=accuracy))
if continuous_evaluation:
self._logger.debug("Unclaimed data: %d", len(unclaimed_data))
pbar.set_description(f"{desc} ({len(unclaimed_data)} unclaimed)")
with open(save_path, 'w') as f:
json.dump(save_data, f, separators=(',', ':'))
self._decai.model.export(model_save_path, classifications,
feature_index_mapping=feature_index_mapping)
if os.path.exists(plot_save_path):
os.remove(plot_save_path)
self.save_plot_image(plot, plot_save_path)
self._time.set_time(current_time)
balance = self._balances[agent.address]
if balance > 0 and next_data_index < len(x_remaining):
# Pick data.
x, y = x_remaining[next_data_index], y_remaining[next_data_index]
if agent.calls_model:
# Only call the model if it's good.
if random.random() < accuracy:
update_balance_plot = True
self._decai.predict(Msg(agent.address, agent.pay_to_call), x)
else:
if not agent.good:
y = 1 - y
if agent.prob_mistake > 0 and random.random() < agent.prob_mistake:
y = 1 - y
# Bad agents always contribute.
# Good agents will only work if the model is doing well.
# Add a bit of chance they will contribute since 0.85 accuracy is okay.
if not agent.good or random.random() < accuracy + 0.15:
value = agent.get_next_deposit()
if value > balance:
value = balance
msg = Msg(agent.address, value)
try:
self._decai.add_data(msg, x, y)
# Don't need to plot every time. Plot less as we get more data.
update_balance_plot = next_data_index / len(x_remaining) + 0.1 < random.random()
balance = self._balances[agent.address]
if continuous_evaluation:
unclaimed_data.append((current_time, agent, x, y))
next_data_index += 1
pbar.update()
except RejectException:
# Probably failed because they didn't pay enough which is okay.
# Or if not enough time has passed since data was attempted to be added
# which is okay too because a real contract would reject this
# because the smallest unit of time we can use is 1s.
if self._logger.isEnabledFor(logging.DEBUG):
self._logger.exception("Error adding data.")
if balance > 0:
q.put((current_time + agent.get_next_wait_s(), agent))
claimed_indices = []
for i in range(len(unclaimed_data)):
added_time, adding_agent, x, classification = unclaimed_data[i]
if current_time - added_time < self._decai.im.refund_time_s:
break
if next_data_index >= len(x_remaining) \
and current_time - added_time < self._decai.im.any_address_claim_wait_time_s:
break
balance = self._balances[agent.address]
msg = Msg(agent.address, balance)
if current_time - added_time > self._decai.im.any_address_claim_wait_time_s:
# Attempt to take the entire deposit.
try:
self._decai.report(msg, x, classification, added_time, adding_agent.address)
update_balance_plot = True
except RejectException:
if self._logger.isEnabledFor(logging.DEBUG):
self._logger.exception("Error taking reward.")
elif adding_agent.address == agent.address:
try:
self._decai.refund(msg, x, classification, added_time)
update_balance_plot = True
except RejectException:
if self._logger.isEnabledFor(logging.DEBUG):
self._logger.exception("Error getting refund.")
else:
try:
self._decai.report(msg, x, classification, added_time, adding_agent.address)
update_balance_plot = True
except RejectException:
if self._logger.isEnabledFor(logging.DEBUG):
self._logger.exception("Error taking reward.")
stored_data = self._decai.data_handler.get_data(x, classification,
added_time, adding_agent.address)
if stored_data.claimable_amount < = 0:
claimed_indices.append(i)
for i in claimed_indices[::-1]:
unclaimed_data.pop(i)
if update_balance_plot:
balance = self._balances[agent.address]
doc.add_next_tick_callback(
partial(plot_cb, agent=agent, t=current_time, b=balance))
self._logger.info("Done going through data.")
if continuous_evaluation:
pbar.set_description(f"{desc} ({len(unclaimed_data)} unclaimed)")
if isinstance(self._decai.im, PredictionMarket):
self._time.add_time(agents[0].get_next_wait_s())
self._decai.im.end_market()
for i, test_set_portion in enumerate(pm_test_sets):
if i != self._decai.im.test_reveal_index:
self._decai.im.verify_next_test_set(test_set_portion)
with tqdm(desc="Processing contributions",
unit_scale=True, mininterval=2, unit=" contributions",
total=self._decai.im.get_num_contributions_in_market(),
) as pbar:
finished_first_round_of_rewards = False
while self._decai.im.remaining_bounty_rounds > 0:
self._time.add_time(agents[0].get_next_wait_s())
self._decai.im.process_contribution()
pbar.update()
if not finished_first_round_of_rewards:
accuracy = self._decai.im.prev_acc
# If we plot too often then we end up with a blob instead of a line.
if random.random() < 0.1:
doc.add_next_tick_callback(
partial(plot_accuracy_cb, t=self._time(), a=accuracy))
if self._decai.im.state == MarketPhase.REWARD_RESTART:
finished_first_round_of_rewards = True
if self._decai.im.reset_model_during_reward_phase:
# Update the accuracy after resetting all data.
accuracy = self._decai.im.prev_acc
else:
# Use the accuracy after training with all data.
pass
doc.add_next_tick_callback(
partial(plot_accuracy_cb, t=self._time(), a=accuracy))
pbar.total += self._decai.im.get_num_contributions_in_market()
self._time.add_time(self._time() * 0.001)
for agent in agents:
balance = self._balances[agent.address]
market_bal = self._decai.im._market_balances[agent.address]
self._logger.debug("\"%s\" market balance: %0.2f Balance: %0.2f",
agent.address, market_bal, balance)
doc.add_next_tick_callback(
partial(plot_cb, agent=agent, t=self._time(), b=max(balance + market_bal, 0)))
self._time.add_time(self._time() * 0.02)
for agent in agents:
msg = Msg(agent.address, 0)
# Find data submitted by them.
data = None
for key, stored_data in self._decai.data_handler:
if stored_data.sender == agent.address:
data = key[0]
break
if data is not None:
self._decai.refund(msg, np.array(data), stored_data.classification, stored_data.time)
balance = self._balances[agent.address]
doc.add_next_tick_callback(
partial(plot_cb, agent=agent, t=self._time(), b=balance))
self._logger.info("Balance for \"%s\": %.2f (%+.2f%%)",
agent.address, balance,
(balance - agent.start_balance) / agent.start_balance * 100)
else:
self._logger.warning("No data submitted by \"%s\" was found."
"\nWill not update it's balance.", agent.address)
self._logger.info("Done issuing rewards.")
accuracy = self._decai.model.log_evaluation_details(x_test, y_test)
doc.add_next_tick_callback(
partial(plot_accuracy_cb, t=current_time + 100, a=accuracy))
with open(save_path, 'w') as f:
json.dump(save_data, f, separators=(',', ':'))
self._decai.model.export(model_save_path, classifications, feature_index_mapping=feature_index_mapping)
if os.path.exists(plot_save_path):
os.remove(plot_save_path)
self.save_plot_image(plot, plot_save_path)
doc.add_root(plot)
thread = Thread(target=task)
thread.start()
0
View Source File : rca.py
License : MIT License
Project Creator : smartyal
License : MIT License
Project Creator : smartyal
def rca(functionNode):
logger = functionNode.get_logger()
logger.info("==>>>> in rca (root cause analysis " + functionNode.get_browse_path())
progressNode = functionNode.get_child("control").get_child("progress")
progressNode.set_value(0.1)
variables = functionNode.get_child("selectedVariables").get_leaves()
tag = functionNode.get_child("selectedTags").get_value() #only one tag
annotations = functionNode.get_child("annotations").get_leaves()
feature = functionNode.get_child("selectedFeatures").get_value()
algo = functionNode.get_child("selectedAlgorithms").get_value()
target = functionNode.get_child("selectedTarget").get_target()
p=Progress(progressNode)
p.set_divisor(len(annotations)/0.5)
p.set_offset(0.1)
#now create the data as x-y
results = {"x":[],"y":[]}
var = variables[0]
#now iterate over all annotations of the matching type and create feature
for idx,anno in enumerate(annotations):
p.set_progress(idx)
if (anno.get_child("type").get_value() == "time") and (tag in anno.get_child("tags").get_value()):
startTime =anno.get_child("startTime").get_value()
endTime = anno.get_child("endTime").get_value()
data = var.get_time_series(startTime,endTime)
#now create the feature
feat = calc_feature(data["values"],feature)
targetValue = get_target(target,(date2secs(startTime)+date2secs(endTime))/2)
if feat and targetValue and numpy.isfinite(feat) and numpy.isfinite(targetValue):
results["x"].append(feat)
results["y"].append(targetValue)
else:
logger.warning(f"no result for {var.get_name} @ {startTime}, anno:{tag}, feat:{feat}, target: {target}")
#now we have all the x-y
progressNode.set_value(0.7)
fig = figure(title = "x-y Correlation Plot "+var.get_name(),
tools=[PanTool(), WheelZoomTool(),ResetTool(),SaveTool()],
plot_height=300,
x_axis_label=feature+"("+var.get_name()+") @ "+tag,
y_axis_label=target.get_name())
fig.toolbar.logo = None
curdoc().theme = Theme(json=themes.darkTheme)
fig.xaxis.major_label_text_color = themes.darkTickColor
fig.yaxis.major_label_text_color = themes.darkTickColor
fig.scatter(x=results["x"], y=results["y"], size=5, fill_color="#d9b100", marker="o")
fileName = functionNode.get_child("outputFileName").get_value()
filePath = os.path.join(myDir,'./../web/customui/'+fileName)
progressNode.set_value(0.8)
output_file(filePath,mode="inline")#inline: put the bokeh .js into this html, otherwise the default cdn will be taken, might cause CORS problems)
save(fig)
#print(results)
return True
#
def data_cleaning(annotations,order=None,logger=None):
0
View Source File : rca.py
License : MIT License
Project Creator : smartyal
License : MIT License
Project Creator : smartyal
def rca2(functionNode):
logger = functionNode.get_logger()
logger.info("==>>>> in rca2 (root cause analysis " + functionNode.get_browse_path())
progressNode = functionNode.get_child("control").get_child("progress")
progressNode.set_value(0.1)
m=functionNode.get_model()
report = ' < i>REPORT < /i> < br> < div style="font-size:85%">'
annotations = functionNode.get_child("annotations").get_leaves()
#order = ["Step"+str(no) for no in range(1,19)]
#order = ["Phase"+str(no) for no in range(3,28)]
order = functionNode.get_child("annotationsOrder").get_value()
logger.debug("filtering by order")
annotations = data_cleaning( annotations ,order = order,logger=logger) #Step1,Step2,...Step18 lsit of lists
report+=(f"found {len(annotations)} valid processes < br>")
#for now, flatten them out
annotations = [subprocess for process in annotations for subprocess in process]
algo = functionNode.get_child("selectedAlgorithm").get_value()
target = functionNode.get_child("selectedTarget").get_target()
progressNode.set_value(0.3)
#now we are building up the table by iterating all the children in "selection"
entries = functionNode.get_child("selection").get_children()
table = {"target":[]}
firstVariable = True
for entry in entries:
logger.debug(f"entry {entry.get_name()}")
#each entry is a combination of variable, tags and feature
vars = entry.get_child("selectedVariables").get_targets()
tags = entry.get_child("selectedTags").get_value()
features = entry.get_child("selectedFeatures").get_value()
#for iterate over variables
for var in vars:
logger.debug(f"processing variable: {var.get_name()} with tags {tags} and features {features}")
#columnName = var.get_name()+str(tags)+m.getRandomId()
for tag in tags:
row = 0
#table[columnName]=[]# make a column
for idx,anno in enumerate(annotations):
if anno.get_child("type").get_value() != "time":
continue
if tag in anno.get_child("tags").get_value():
startTime =anno.get_child("startTime").get_value()
endTime = anno.get_child("endTime").get_value()
data = var.get_time_series(startTime,endTime)["values"]
#we take only the values "inside" the annotation
if len(data)>2:
data =data[1:-1]
#now create the features
for feature in features:
feat = calc_feature(data,feature)
columnName = var.get_name()+"_"+tag+"_"+feature
if not columnName in table:
table[columnName]=[]
table[columnName].append(feat)
targetValue = get_target(target,(date2secs(startTime)+date2secs(endTime))/2)
if targetValue:
if firstVariable:
#for the first variable we also write the target
table["target"].append(targetValue)
else:
#for all others we make sure we have the same target value for that case (sanity check)
if table["target"][row] != targetValue:
logger.warning(f'problem target {table["target"][row]} !=> {targetValue}')
row=row+1
else:
logger.warning(f"no corrrect target value for {startTime} - {endTime}")
firstVariable = False
#now we have the table, plot it
import json
#print(json.dumps(table,indent=2))
progressNode.set_value(0.5)
#try a model
algo = functionNode.get_child("selectedAlgorithm").get_value()
if algo=="lasso":
reg = linear_model.LassoCV()
report +=" using lasso Regression with auto-hyperparams < br>"
else:
#default
report +=" using linear Regression < br>"
reg = linear_model.LinearRegression() #try rigde, lasso
columnNames = []
dataTable = []
saveDict = {}
for k,v in table.items():
saveDict[k]=numpy.asarray(v,dtype=numpy.float64)
if k=="target":
continue
dataTable.append(v)
columnNames.append(k)
fileName = functionNode.get_child("outputFileName").get_value()
filePath = os.path.join(myDir,'./../web/customui/'+fileName.split(".")[0])
numpy.savez(filePath, **saveDict)
#for loading:
# get = numpy.load(name+".npz")
# for name in get.files:
# data = get[name]
dataTable = numpy.asarray(dataTable)
x=dataTable.T
scaler = StandardScaler()
scaler.fit(x)
x=scaler.transform(x)
y=table["target"]
x_train, x_test, y_train, y_test = train_test_split(x, y)
reg.fit(x_train,y_train)
#print(reg.coef_)
y_hat= reg.predict(x_test)
y_repeat = reg.predict(x_train)
#print(f"predict: {y_hat} vs real: {y_test}")
#check over/underfitting
r_train = r2_score(y_train, y_repeat)
r_test = r2_score(y_test,y_hat)
report+="R < sup>2 < /sup> train= %.4g, R < sup>2 < /sup> test = %.4g < br>"%(r_train,r_test)
pearsons = []
for col in x.T:
pearsons.append(pearsonr(col, y)[0])
#and finally the correlations between y and yhat
y_pearson_train = pearsonr(y_train, y_repeat)[0]
y_pearson_test = pearsonr(y_test,y_hat)[0]
report+="pearsonCorr y/y_hat train:%.4g , test:%.4g < br>"%(y_pearson_train,y_pearson_test)
report +="regression coefficients, pearsons correlations: < br>"
for col,coef,pear in zip(columnNames,reg.coef_,pearsons):
report+=" %s:%.4g, %.4g < br>"%(col,coef,pear)
#write report
progressNode.set_value(0.8)
report+=" < div>"#close the style div
functionNode.get_child("report").set_value(report)
#make a plot
hover1= HoverTool(tooltips=[ ( 'x,y','$x,$y')],mode='mouse')
hover1.point_policy='snap_to_data'
hover1.line_policy = "nearest"
tools = [PanTool(), WheelZoomTool(),BoxZoomTool(),ResetTool(),SaveTool(),hover1]
title = "prediction results on "+functionNode.get_child("selectedAlgorithm").get_value()
fig = figure(title = title,tools=tools,plot_height=300,plot_width=400)
fig.toolbar.logo = None
curdoc().theme = Theme(json=themes.darkTheme)
fig.xaxis.major_label_text_color = themes.darkTickColor
fig.yaxis.major_label_text_color = themes.darkTickColor
fig.xaxis.axis_label= target.get_name()
fig.xaxis.axis_label_text_color = "white"
fig.yaxis.axis_label="predicted Values for "+target.get_name()
fig.yaxis.axis_label_text_color="white"
fig.circle(y_train,y_repeat,size=4,line_color="white",fill_color="white",name="train",legend_label="train")
fig.circle(y_test,y_hat,line_color="#d9b100",fill_color="#d9b100",size=4,name="test",legend_label="test")
mini = min([min(y_train),min(y_repeat),min(y_test),min(y_hat)])
maxi = max([max(y_train),max(y_repeat),max(y_test),max(y_hat)])
fig.line([mini,maxi],[mini,maxi],line_color="grey",line_dash="dashed")
fileName = functionNode.get_child("outputFileName").get_value()
filePath = os.path.join(myDir,'./../web/customui/'+fileName)
fig.legend.location = "top_left"
output_file(filePath,mode="inline")
save(fig)
return True
def prepare_annos_filter(functionNode):
0
View Source File : varstatistics.py
License : MIT License
Project Creator : smartyal
License : MIT License
Project Creator : smartyal
def varstatistics(functionNode):
logger = functionNode.get_logger()
logger.info("==>>>> statistics " + functionNode.get_browse_path())
progressNode = functionNode.get_child("control").get_child("progress")
progressNode.set_value(0)
#functionNode.get_child("control.signal").set_value(None)
vars = functionNode.get_child("variable").get_targets()
widget = functionNode.get_child("widget").get_target()
bins = functionNode.get_child("bins").get_value()
tags = functionNode.get_child("annotations").get_value()
startTime = date2secs(widget.get_child("startTime").get_value())
endTime = date2secs(widget.get_child("endTime").get_value())
vars = {var.get_id():{"node":var} for var in vars}
#first 30% progress:
prog = Progress(progressNode)
progressNode.set_value(0.1)
prog.set_offset(0.1)
#prog.set_divisor()
if tags:
allAnnoNodes = widget.get_child("hasAnnotation.annotations").get_leaves()
allAnnos=[]
prog.set_divisor(len(allAnnoNodes)/0.2)
for index,node in enumerate(allAnnoNodes):
prog.set_progress(index)
if node.get_child("type").get_value()=="time":
thisTags = node.get_child("tags").get_value()
if any(tag in tags for tag in thisTags):
anno = {}
for child in node.get_children():
anno[child.get_name()]=child.get_value()
if date2secs(anno["startTime"])>=startTime and date2secs(anno["endTime"]) < =endTime and (anno["startTime"] < anno["endTime"]): #take this anno only if it is inside the current start/end time
allAnnos.append(anno)
if allAnnos == []:
give_up(functionNode,"no matching annotations in selected time")
return False
else:
allAnnos=[]
progressNode.set_value(0.3)
logger.debug(f"statistics annotations to look at: {len(allAnnos)}")
prog.set_offset(0.3)
totalAnnos = max(len(allAnnos),1)
totalCount = len(vars)*totalAnnos
prog.set_divisor(totalCount/0.3)
totalValids = 0
for varIndex,var in enumerate(vars):
info = vars[var]
if tags:
#iterate over all start and end times
values = numpy.asarray([],dtype=numpy.float64)
for annoIndex,anno in enumerate(allAnnos):
thisValues = info["node"].get_time_series(anno["startTime"],anno["endTime"])["values"]
values = numpy.append(values,thisValues)
myCount = varIndex*totalAnnos+annoIndex
prog.set_progress(myCount)
else:
values = info["node"].get_time_series(startTime,endTime)["values"]
valids = numpy.count_nonzero(numpy.isfinite(values))
totalValids+=valids
hist, edges = numpy.histogram(values, bins=bins)
hist=hist/len(values) #normalize
info["hist"]=hist
info["edges"]=edges
#make a plot
if totalValids == 0:
give_up(functionNode,"all Variables are have no data in the time and annotations selected")
return False
progressNode.set_value(0.6)
hover1= HoverTool(tooltips=[ ( 'x,y','$x,$y')],mode='mouse')
hover1.point_policy='snap_to_data'
hover1.line_policy = "nearest"
tools = [PanTool(), WheelZoomTool(),BoxZoomTool(),ResetTool(),SaveTool(),hover1]
title = "Statistics of "+str([info["node"].get_name() for var,info in vars.items()])
if tags:
title = title + " in annotation: "+ str(tags )
fig = figure(title = title,tools=tools,plot_height=300)
fig.toolbar.logo = None
curdoc().theme = Theme(json=themes.darkTheme)
fig.xaxis.major_label_text_color = themes.darkTickColor
fig.yaxis.major_label_text_color = themes.darkTickColor
for index,var in enumerate(vars):
info = vars[var]
col = themes.darkLineColors[index]
hist = info["hist"]
edges = info["edges"]
fig.quad(top=hist, bottom=0, left=edges[:-1], right=edges[1:],
fill_color=col, line_color=col, alpha=0.8,legend_label=info["node"].get_name())
fig.legend.location = "top_left"
fileName = functionNode.get_child("fileName").get_value()
filePath = os.path.join(myDir,'./../web/customui/'+fileName)
# now make the trend box plot, but only for tags
# for each variable we create statistics for the annotations and prepare the data
# {"node":Node(), "boxLower":[], "boxUpper", "mean", "limitUpper", "limitLower"}
#
startTime = date2secs(widget.get_child("startTime").get_value()) #we only take tags that are inside the current zoom of the widgets
endTime = date2secs(widget.get_child("endTime").get_value())
boxPlots = []
allTimes = []
if tags:
for index,var in enumerate(vars):
info={"node":vars[var]["node"],"boxLower":[],"boxUpper":[],"median":[],"time":[],"limitUpper":[],"limitLower":[],"mean":[]}
for anno in allAnnos:
data = info["node"].get_time_series(anno["startTime"],anno["endTime"])
if len(data["values"]):
data["values"] = data["values"][numpy.isfinite(data["values"])]
#remove the nan
if len(data["values"]):
#make the statistics
info["time"].append(numpy.median(data["__time"])*1000)
allTimes.append(numpy.median(data["__time"])*1000)
info["limitLower"].append(numpy.quantile(data["values"],0.01))
info["limitUpper"].append(numpy.quantile(data["values"],0.99))
info["boxLower"].append(numpy.quantile(data["values"],0.25))
info["boxUpper"].append(numpy.quantile(data["values"],0.75))
info["median"].append(numpy.median(data["values"]))
info["mean"].append(numpy.mean(data["values"]))
boxPlots.append(info)
format = "%Y-%m-%d-T%H:%M:%S"
custom = """var local = moment(value).tz('UTC'); return local.format();"""#%self.server.get_settings()["timeZone"]
hover = HoverTool(
tooltips=[ ( 'date','@x{%F}')],
formatters={ '@x' : CustomJSHover(code=custom)
},
mode='mouse'
)
hover.point_policy='snap_to_data'
hover.line_policy = "nearest"
tools = [PanTool(), BoxZoomTool(),WheelZoomTool(),ResetTool(),hover,SaveTool()]
fig2 = figure(title = "trends",tools=tools,plot_height=300,x_axis_type='datetime')
fig2.xaxis.major_label_text_color = themes.darkTickColor
fig2.yaxis.major_label_text_color = themes.darkTickColor
progressNode.set_value(0.7)
fig2.xaxis.formatter=DatetimeTickFormatter(years=format,days=format,months=format,hours=format,hourmin=format,minutes=format,minsec=format,seconds=format)
fig2.toolbar.logo = None
#fig2.line([1,2,3],[1,2,3])
#calc with of vbars
if len(allAnnos)>1:
xTimesStart = min(allTimes)
xTimesEnd = max(allTimes)
width = (xTimesEnd-xTimesStart)/2/len(allAnnos)
else:
width = 1000000
for index,info in enumerate(boxPlots):
#each info is for one variable
col = themes.darkLineColors[index]
fig2.segment(info["time"],info["limitUpper"],info["time"],info["boxUpper"],line_color=col)
fig2.segment(info["time"],info["limitLower"],info["time"],info["boxLower"],line_color=col)
width =20
#fig2.vbar(info["time"],width=width,bottom=info["median"],top=info["boxUpper"],fill_color=col,line_color="black",width_units='screen')
#fig2.vbar(info["time"],width=width,bottom=info["boxLower"],top=info["median"],fill_color=col,line_color="black",width_units='screen')
#upper box
sizUpper = numpy.asarray(info["boxUpper"])-numpy.asarray(info["median"])
medUpper = numpy.asarray(info["median"])+sizUpper/2
fig2.rect(x=info["time"],y=medUpper,width_units='screen',width=20,height=sizUpper,fill_color=col,line_color="black")
#lower box
sizLower = numpy.asarray(info["median"])-numpy.asarray(info["boxLower"])
medLower = numpy.asarray(info["median"])-sizLower/2
fig2.rect(x=info["time"],y=medLower,width_units='screen',width=20,height=sizLower,fill_color=col,line_color="black")
#sort data for line
x = numpy.asarray(info["time"])
y = numpy.asarray(info["mean"])
order = numpy.argsort(x)
x=x[order]
y=y[order]
fig2.line(x,y,line_color=col)
progressNode.set_value(0.8)
else:
#no fig2
pass
output_file(filePath,mode="inline")#inline: put the bokeh .js into this html, otherwise the default cdn will be taken, might cause CORS problems
if tags:
save(layout([[fig],[fig2]]))
else:
save(fig)
return True