def test_displays_button_type(self, typ, bokeh_model_page): button = Button(button_type=typ, css_classes=["foo"]) page = bokeh_model_page(button) button = page.driver.find_element_by_css_selector('.foo .bk-btn') assert typ in button.get_attribute('class')
def test_buttonclick_event_callbacks(): button = Button() test_callback = EventCallback() button.on_event(events.ButtonClick, test_callback) assert test_callback.event_name == None button._trigger_event(events.ButtonClick(button)) assert test_callback.event_name == events.ButtonClick.event_name
def root(): scrape_button = Button(label='Scrape Data') prices = scrape_button.on_click(scrape_prices(url)) #prices = scrape_prices(url) p = make_hist(prices) script, div = embed.components(p,scrape_button) return render_template('histograms.html',script = script,div = div)
class ButtonWrapper(object): def __init__(self, label, callback): self.ref = "button-" + make_id() self.obj = Button(label=label, css_classes=[self.ref]) self.obj.js_on_event('button_click', callback) def click(self, driver): button = driver.find_element_by_css_selector(".%s .bk-btn" % self.ref) button.click()
def modify_doc(doc): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1])) plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_glyph(source, Circle(x='x', y='y', size=20)) plot.add_tools(CustomAction(callback=CustomJS(args=dict(s=source), code=RECORD("data", "s.data")))) button = Button(css_classes=['foo']) def cb(event): source.data=dict(x=[10, 20], y=[10, 10]) button.on_event('button_click', cb) doc.add_root(column(button, plot))
def test_js_on_click_executes(self, bokeh_model_page): button = Button(css_classes=['foo']) button.js_on_click(CustomJS(code=RECORD("clicked", "true"))) page = bokeh_model_page(button) button = page.driver.find_element_by_css_selector('.foo .bk-btn') button.click() results = page.results assert results == {'clicked': True} assert page.has_no_console_errors()
def run(doc): fig = figure(title='random data', width=400, height=200, tools='pan,box_zoom,reset,save') source = ColumnDataSource(data={'x': [], 'y': []}) fig.line('x', 'y', source=source) def click(n=100): source.data = {'x': range(n), 'y': random(n)} button = Button(label='update', button_type='success') button.on_click(click) layout = column(widgetbox(button), fig) doc.add_root(layout) click()
def create_previous_event_widget(self): self.w_previous_event = Button( label="<", button_type="default", width=50 ) self.w_previous_event.on_click(self.on_previous_event_widget_click)
def create_goto_event_index_widget(self): self.w_goto_event_index = Button( label="GOTO Index", button_type="default", width=100 ) self.w_goto_event_index.on_click(self.on_goto_event_index_widget_click)
def modify_doc(doc): plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_tools(CustomAction(callback=CustomJS(args=dict(s=source), code=RECORD("data", "s.data")))) table = DataTable(columns=[ TableColumn(field="x", title="x", sortable=True), TableColumn(field="y", title="y", sortable=True) ], source=source, editable=False) button = Button(css_classes=["foo"]) def cb(): source.stream({'x': [100], 'y': [100]}) button.on_click(cb) doc.add_root(column(plot, table, button))
def create_goto_event_id_widget(self): self.w_goto_event_id = Button( label="GOTO ID", button_type="default", width=70 ) self.w_goto_event_id.on_click(self.on_goto_event_id_widget_click)
def test_event_handles_new_callbacks_in_event_callback(self): from bokeh.models import Button d = document.Document() button1 = Button(label="1") button2 = Button(label="2") def clicked_1(): button2.on_click(clicked_2) d.add_root(button2) def clicked_2(): pass button1.on_click(clicked_1) d.add_root(button1) event_json = json.dumps({"event_name":"button_click","event_values":{"model_id":button1.id}}) try: d.apply_json_event(event_json) except RuntimeError: pytest.fail("apply_json_event probably did not copy models before modifying")
def plot(): import numpy as np from bokeh.models import Button from bokeh.palettes import RdYlBu3 from bokeh.plotting import figure, vplot # create a plots 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 out plots (no data yet) r = p.text(x=[], y=[], text=[], text_color=[], text_font_size="20pt", 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 ds.data['x'].append(np.random.random()*70 + 15) ds.data['y'].append(np.random.random()*70 + 15) ds.data['text_color'].append(RdYlBu3[i%3]) ds.data['text'].append(str(i)) ds.trigger('data', ds.data, ds.data) i = i + 1 # add a button widget and configure with the call back button = Button(label="Press Me") button.on_click(callback) plot_this = vplot(button, p) return plot_this
def line_scratch(): line_width = 4 line1 = [(0, 1, 2, 3, 4, 5), (0, 1, 2, 3, 4, 5)] line2 = [(0, 1, 2, 3, 4, 5), (0, 5, 1, 4, 2, 3)] line3 = [(5, 4, 3, 2, 1), (5, 4, 3, 2, 1)] plot = figure() red = plot.line(x=line1[0], y=line1[1], line_width=line_width, color="crimson") blue = plot.line(x=line2[0], y=line2[1], line_width=line_width) # purple = plot.line(x=line3[0], y=line3[1], line_width=line_width, color="purple") button = Button(label="Add Line") button.on_click(add_line) curdoc().add_root(vplot(plot, button)) session = push_session(curdoc()) script = autoload_server(model=None, session_id=session.id) # script, div = components(vplot(plot, button)) return script
def test_data_table_selected_highlighting(output_file_url, selenium, screenshot): # Create a DataTable and Button that sets a selection data = dict(x = list(range(10))) source = ColumnDataSource(data=data) columns = [TableColumn(field="x", title="X")] data_table = DataTable(source=source, columns=columns) button = Button(label="Click") button.callback = CustomJS(args=dict(source=source), code=""" source['selected']['1d'].indices = [1, 2] source.change.emit(); """) # Save the table and start the test save(column(data_table, button)) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Click the button to select the rows button = selenium.find_element_by_class_name('bk-bs-btn') button.click() screenshot.assert_is_valid()
def init_controls(self): btnStop = Button(label="Stop", type="danger") btnStart = Button(label="Start", type="success") btnStop.on_click(self.handle_btnStop_press) btnStart.on_click(self.handle_btnStart_press) curdoc().add_root(btnStop) curdoc().add_root(btnStart) sliderHPThreshold = Slider(start=0, end=500, value=100, step=1, title="High pass threshold") sliderHPThreshold.on_change('value', self.onChangeHPThreshold) curdoc().add_root(vplot(sliderHPThreshold))
def do_step(document): document.clear() sl, c = next(examples) p = plot_slice(sl) b_A = Button(label="Accept") b_R = Button(label="Reject") b_A.on_click(functools.partial(callback, sl, c, 'accept')) b_R.on_click(functools.partial(callback, sl, c, 'reject')) plot = vplot(p, (hplot(b_A, b_R))) document.add_root(plot)
def __init__(self, server, doc=None, **kwargs): if doc is not None: self.doc = weakref.ref(doc) self.server = server self.log = self.server.io_loop.profile self.start = None self.stop = None self.ts = {"count": [], "time": []} self.state = profile.get_profile(self.log) data = profile.plot_data(self.state, profile_interval) self.states = data.pop("states") self.profile_plot, self.source = profile.plot_figure(data, **kwargs) changing = [False] # avoid repeated changes from within callback @without_property_validation def cb(attr, old, new): if changing[0] or len(new) == 0: return with log_errors(): data = profile.plot_data(self.states[new[0]], profile_interval) del self.states[:] self.states.extend(data.pop("states")) changing[0] = True # don't recursively trigger callback update(self.source, data) self.source.selected.indices = old changing[0] = False self.source.selected.on_change("indices", cb) self.ts_source = ColumnDataSource({"time": [], "count": []}) self.ts_plot = figure( title="Activity over time", height=150, x_axis_type="datetime", active_drag="xbox_select", tools="xpan,xwheel_zoom,xbox_select,reset", sizing_mode="stretch_width", toolbar_location="above", ) self.ts_plot.line("time", "count", source=self.ts_source) self.ts_plot.circle( "time", "count", source=self.ts_source, color=None, selection_color="orange" ) self.ts_plot.yaxis.visible = False self.ts_plot.grid.visible = False def ts_change(attr, old, new): with log_errors(): selected = self.ts_source.selected.indices if selected: start = self.ts_source.data["time"][min(selected)] / 1000 stop = self.ts_source.data["time"][max(selected)] / 1000 self.start, self.stop = min(start, stop), max(start, stop) else: self.start = self.stop = None self.trigger_update() self.ts_source.selected.on_change("indices", ts_change) self.reset_button = Button(label="Reset", button_type="success") self.reset_button.on_click(lambda: self.update(self.state)) self.update_button = Button(label="Update", button_type="success") self.update_button.on_click(self.trigger_update) self.root = column( row(self.reset_button, self.update_button, sizing_mode="scale_width"), self.profile_plot, self.ts_plot, **kwargs, )
dataSelect = Select(title='Select Data', options=fileNames) dataSelect.on_change('value', updatePatientCallback) def increaseCallback(): selects = iP.getSelects(entirePage.children[1].children[0].children) print(selects) createInnerPlot.toAddText(selects) entirePage.children[1] = createInnerPlot(folder, fileName) return addButton = Button(label='Add Sentence Outer') addButton.on_click(increaseCallback) #------------------------------------------------------- # Generate information about the first patient #------------------------------------------------------- innerPlot = createInnerPlot(folder, fileName) entirePage = column([dataSelect, innerPlot, addButton]) curdoc().add_root(entirePage) curdoc().title = "labelData"
def __init__(self, server, doc=None, **kwargs): if doc is not None: self.doc = weakref.ref(doc) try: self.key = doc.session_context.request.arguments.get("key", None) except AttributeError: self.key = None if isinstance(self.key, list): self.key = self.key[0] if isinstance(self.key, bytes): self.key = self.key.decode() self.task_names = ["All", self.key] if self.key else ["All"] else: self.key = None self.task_names = ["All"] self.server = server self.start = None self.stop = None self.ts = {"count": [], "time": []} self.state = profile.create() data = profile.plot_data(self.state, profile_interval) self.states = data.pop("states") self.profile_plot, self.source = profile.plot_figure(data, **kwargs) changing = [False] # avoid repeated changes from within callback @without_property_validation def cb(attr, old, new): if changing[0] or len(new) == 0: return with log_errors(): data = profile.plot_data(self.states[new[0]], profile_interval) del self.states[:] self.states.extend(data.pop("states")) changing[0] = True # don't recursively trigger callback update(self.source, data) self.source.selected.indices = old changing[0] = False self.source.selected.on_change("indices", cb) self.ts_source = ColumnDataSource({"time": [], "count": []}) self.ts_plot = figure( title="Activity over time", height=150, x_axis_type="datetime", active_drag="xbox_select", tools="xpan,xwheel_zoom,xbox_select,reset", sizing_mode="stretch_width", toolbar_location="above", ) self.ts_plot.line("time", "count", source=self.ts_source) self.ts_plot.circle( "time", "count", source=self.ts_source, color=None, selection_color="orange" ) self.ts_plot.yaxis.visible = False self.ts_plot.grid.visible = False def ts_change(attr, old, new): with log_errors(): selected = self.ts_source.selected.indices if selected: start = self.ts_source.data["time"][min(selected)] / 1000 stop = self.ts_source.data["time"][max(selected)] / 1000 self.start, self.stop = min(start, stop), max(start, stop) else: self.start = self.stop = None self.trigger_update(update_metadata=False) self.ts_source.selected.on_change("indices", ts_change) self.reset_button = Button(label="Reset", button_type="success") self.reset_button.on_click(lambda: self.update(self.state)) self.update_button = Button(label="Update", button_type="success") self.update_button.on_click(self.trigger_update) self.select = Select(value=self.task_names[-1], options=self.task_names) def select_cb(attr, old, new): if new == "All": new = None self.key = new self.trigger_update(update_metadata=False) self.select.on_change("value", select_cb) self.root = column( row( self.select, self.reset_button, self.update_button, sizing_mode="scale_width", height=250, ), self.profile_plot, self.ts_plot, **kwargs, )
def candlestick_plot(): def obv_indicator(data): res = talib.OBV(data.close.values, data.volume.values) return res def rsi_indicator(data): res = talib.RSI(data.close.values, timeperiod=14) return res def cci_indicator(data): res = talib.CCI(data.high.values, data.low.values, data.close.values, timeperiod=14) return res def technical_indicator(data, indicator): if indicator == 'CCI': data['tech'] = cci_indicator(data) elif indicator == 'RSI': data['tech'] = rsi_indicator(data) else: data['tech'] = obv_indicator(data) return data def load_data(obid, start, end, freq='1d'): print('running....') data = get_price(obid, start, end, freqency=freq).reset_index() data['pct_change'] = data['close'].pct_change() # data.dropna(inplace=True) data['pct_change'] = data['pct_change'].apply(lambda x: str(round(x * 100, 2)) + '%') data['index'] = list(np.arange(len(data))) data['date'] = data['date'].apply(lambda x: x.strftime("%Y%m%d")) return data def moving_average(data, selection): selection_mapping = {k: int(k.split('_')[-1]) for k in selection} for k, v in selection_mapping.items(): data[k] = data['close'].rolling(window=v).mean() return data def update_lines(attr, old, new): line_0.visible = 0 in average_selection.active line_1.visible = 1 in average_selection.active line_2.visible = 2 in average_selection.active line_3.visible = 3 in average_selection.active line_4.visible = 4 in average_selection.active line_5.visible = 5 in average_selection.active def update_plot(attr, old, new): indicator = indicator_selection.value new_data = technical_indicator(data, indicator) new_source = ColumnDataSource(new_data) source.data.update(new_source.data) def update_data(): # global obid, start, end obid = order_book_id.value start = start_date.value end = end_date.value # 提取数据,均线根据选取与否进行添加 new_data = load_data(obid, start, end) new_data_1 = moving_average(new_data, average_labels) new_data_2 = technical_indicator(new_data, indicator_selection.value) new_source = ColumnDataSource(new_data_2) new_source_1 = ColumnDataSource(new_data_1) source.data.update(new_source.data) source_1.data.update(new_source_1.data) inc = new_data.close >= new_data.open dec = new_data.close < new_data.open inc_source.data = inc_source.from_df(new_data_2.loc[inc]) dec_source.data = dec_source.from_df(new_data_2.loc[dec]) p.title.text = instruments(obid).symbol p.x_range.end = len(new_data) + 1 p2.xaxis.major_label_overrides = {i: date for i, date in enumerate(new_data['date'])} today = datetime.now().date() average_labels = ["MA_5", "MA_10", "MA_20", 'MA_30', 'MA_60', 'MA_120'] average_selection = CheckboxGroup(labels=average_labels, active=[0, 1, 2, 3, 4, 5, 6]) indicator_selection = Select(title='TechnicalIndicator', value='RSI', options=['OBV', 'RSI', 'CCI']) order_book_id = TextInput(title='StockCode', value='002916.XSHE') symbol = instruments(order_book_id.value).symbol start_date = DatePicker(title="StartDate", value='2018-01-01', min_date='2015-01-01', max_date=today) end_date = DatePicker(title="EndDate", value=today, min_date=start_date.value, max_date=today) # labels = [average_selection.labels[i] for i in average_selection.active] data = load_data(order_book_id.value, start_date.value, end_date.value) # 均线计算 data_1 = moving_average(data, average_labels) # 计算各种长度的均线 # 技术指标计算 data_2 = technical_indicator(data, indicator_selection.value) source = ColumnDataSource(data_2) source_1 = ColumnDataSource(data_1) inc = data.close >= data.open dec = data.open > data.close inc_source = ColumnDataSource(data_2.loc[inc]) dec_source = ColumnDataSource(data_2.loc[dec]) TOOLS = 'save, pan, box_zoom, reset, wheel_zoom' hover = HoverTool(tooltips=[('date', '@date'), ('open', '@open'), ('high', '@high'), ('low', '@low'), ('close', '@close'), ('pct_change', "@pct_change") ] ) length = len(data) p = figure(plot_width=1000, plot_height=500, title='{}'.format(symbol), tools=TOOLS, x_range=(0, length + 1)) p.xaxis.visible = False # 隐藏x-axis p.min_border_bottom = 0 # 均线图 line_0 = p.line(x='index', y='MA_5', source=source_1, color=Spectral6[5]) line_1 = p.line(x='index', y='MA_10', source=source_1, color=Spectral6[4]) line_2 = p.line(x='index', y='MA_20', source=source_1, color=Spectral6[3]) line_3 = p.line(x='index', y='MA_30', source=source_1, color=Spectral6[2]) line_4 = p.line(x='index', y='MA_60', source=source_1, color=Spectral6[1]) line_5 = p.line(x='index', y='MA_120', source=source_1, color=Spectral6[0]) p.segment(x0='index', y0='high', x1='index', y1='low', color='red', source=inc_source) p.segment(x0='index', y0='high', x1='index', y1='low', color='green', source=dec_source) p.vbar('index', 0.5, 'open', 'close', fill_color='red', line_color='red', source=inc_source, hover_fill_alpha=0.5) p.vbar('index', 0.5, 'open', 'close', fill_color='green', line_color='green', source=dec_source, hover_fill_alpha=0.5) p.add_tools(hover) p1 = figure(plot_width=p.plot_width, plot_height=200, x_range=p.x_range, toolbar_location=None) p1.vbar('index', 0.5, 0, 'volume', color='red', source=inc_source) p1.vbar('index', 0.5, 0, 'volume', color='green', source=dec_source) p1.xaxis.visible = False p2 = figure(plot_width=p.plot_width, plot_height=p1.plot_height, x_range=p.x_range, toolbar_location=None) p2.line(x='index', y='tech', source=source) p2.xaxis.major_label_overrides = {i: date for i, date in enumerate(data['date'])} p2.xaxis.major_label_orientation = pi / 4 p2.min_border_bottom = 0 button = Button(label="ClickToChange", button_type="success") button.on_click(update_data) average_selection.inline = True average_selection.width = 500 average_selection.on_change('active', update_lines) indicator_selection.on_change('value', update_plot) widgets = column(row(order_book_id, start_date, end_date, button), row(indicator_selection, average_selection)) layouts = column(widgets, p, p1, p2) # doc.add_root(pp) # make a layout tab = Panel(child=layouts, title='StockPrice') return tab
'yellow' ], factors=syn_factors), source=depth_sample, hover_line_color='white') # Sets up visualization and hover tool. genome_plot.add_tools(HoverTool(tooltips=TOOLTIPS)) genome_plot.xgrid.grid_line_alpha = 0 configurePlot(genome_plot) protein_names = protein_annotation(FIRST) FIRST = False genome_plot.xaxis.axis_label = "Protein" # Creates button that allows reset of plot to original state. reset_button = Button(label="Reset Plot") reset_button.js_on_click( CustomJS(args=dict(g=genome_plot), code=""" g.reset.emit() """)) # Creates text input button for user manual input of depth. ose = TextInput(title='Manually input depth:') # Creates checkboxes to show different types of mutations. syngroup = CheckboxGroup(labels=[ "Show synonymous mutations", "Show nonsynonymous mutations", "Show stopgains and stoplosses", "Show complex mutations", "Show mutations without longitudinal data" ],
def create_previous_event_widget(self): self.w_previous_event = Button(label="<", button_type="default", width=50) self.w_previous_event.on_click(self.on_previous_event_widget_click)
slider = Slider(start=years[0], end=years[-1], value=years[0], step=1, title="Year") slider.on_change('value', slider_update) callback_id = None def animate(): global callback_id if button.label == '► Play': button.label = '❚❚ Pause' callback_id = curdoc().add_periodic_callback(animate_update, 200) else: button.label = '► Play' curdoc().remove_periodic_callback(callback_id) button = Button(label='► Play', width=60) button.on_click(animate) layout = layout([ [plot], [slider, button], ], sizing_mode='scale_width') curdoc().add_root(layout) curdoc().title = "Gapminder"
# hide glyphs by clicking on an entry in a Legend. p.title.text = 'Click on legend entries to hide the corresponding lines' p.legend.click_policy = "hide" # "mute" "hide" # Vertical line vline = Span(location=0, dimension='height', line_color='black', line_width=0.5) # Horizontal line hline = Span(location=0, dimension='width', line_color='black', line_width=0.5) p.renderers.extend([vline, hline]) button = Button(label='reset', width=100, align="center") callback2 = CustomJS(args=dict(p=p, x_slide=x_slider, y_slide=y_slider), code=""" p.reset.emit(); x_slide.value = [500,1800]; y_slide.value = [-5000,5000]; """) button.js_on_click(callback2) # button3 = Button(label='Download 6s',width=100, align="center") # def export(): # # print('I was clicked') # df = pandas.read_csv('Cs.csv') # df = pandas.DataFrame(df, columns= ['wavelength','polarizability']) # df.to_csv(r'C:\Users\13022\Desktop\website\Bokeh\versionFinal\export_cs.csv', index = False, header=True) # return send_file('export_cs',
ry_far = x_far[1, :].tolist() source.data = dict(rx=rx, ry=ry) source_short.data = dict(rx_short=rx_short, ry_short=ry_short) source_far.data = dict(rx_far=rx_far, ry_far=ry_far) # initialize data source source = ColumnDataSource(data=dict(rx=[], ry=[])) source_short = ColumnDataSource(data=dict(rx_short=[], ry_short=[])) source_far = ColumnDataSource(data=dict(rx_far=[], ry_far=[])) source_datatable = ColumnDataSource(data=dict(shot_alpha=[], shot_error=[])) app_data = ColumnDataSource(data=dict(alpha=[bv_settings.alpha_init], alpha_left=[bv_settings.alpha_left], alpha_right=[bv_settings.alpha_right])) buttonShort = Button(label="shoot shorter") buttonShort.on_click(shoot_shorter) buttonFar = Button(label="shoot further") buttonFar.on_click(shoot_further) # initialize plot toolset = "crosshair,pan,reset,resize,wheel_zoom,box_zoom" # Generate a figure container plot = Figure(plot_height=bv_settings.fig_height, plot_width=bv_settings.fig_width, tools=toolset, title=bv_settings.title, # obj.text.value, x_range=[bv_settings.min_x, bv_settings.max_x], y_range=[bv_settings.min_y, bv_settings.max_y] ) # Plot the line by the x,y values in the source property
def create_interact_ui(doc): fig_tpf, stretch_slider = self._make_echelle_elements( dnu, maximum_frequency=maximum_frequency, minimum_frequency=minimum_frequency, **kwargs) maxdnu = self.periodogram.frequency.max().value / 5 # Interactive slider widgets dnu_slider = Slider(start=0.01, end=maxdnu, value=dnu.value, step=0.01, title="Delta Nu", width=290) r_button = Button(label=">", button_type="default", width=30) l_button = Button(label="<", button_type="default", width=30) rr_button = Button(label=">>", button_type="default", width=30) ll_button = Button(label="<<", button_type="default", width=30) def update(attr, old, new): """Callback to take action when dnu slider changes""" dnu = SeismologyQuantity(quantity=dnu_slider.value * u.microhertz, name='deltanu', method='echelle') ep, _, _ = self._clean_echelle( deltanu=dnu, minimum_frequency=minimum_frequency, maximum_frequency=maximum_frequency, **kwargs) fig_tpf.select('img')[0].data_source.data['image'] = [ep.value] fig_tpf.xaxis.axis_label = r'Frequency / {:.3f} Mod. 1'.format( dnu) def go_right_by_one_small(): """Step forward in time by a single cadence""" existing_value = dnu_slider.value if existing_value < maxdnu: dnu_slider.value = existing_value + 0.002 def go_left_by_one_small(): """Step back in time by a single cadence""" existing_value = dnu_slider.value if existing_value > 0: dnu_slider.value = existing_value - 0.002 def go_right_by_one(): """Step forward in time by a single cadence""" existing_value = dnu_slider.value if existing_value < maxdnu: dnu_slider.value = existing_value + 0.01 def go_left_by_one(): """Step back in time by a single cadence""" existing_value = dnu_slider.value if existing_value > 0: dnu_slider.value = existing_value - 0.01 dnu_slider.on_change('value', update) r_button.on_click(go_right_by_one_small) l_button.on_click(go_left_by_one_small) rr_button.on_click(go_right_by_one) ll_button.on_click(go_left_by_one) widgets_and_figures = layout( [fig_tpf, [Spacer(height=20), stretch_slider]], [ ll_button, Spacer(width=30), l_button, Spacer(width=25), dnu_slider, Spacer(width=30), r_button, Spacer(width=23), rr_button ]) doc.add_root(widgets_and_figures)
def on_selection_change2(obj, attr, _, inds): if inds: [index] = inds size = [10] * N size[index] = 40 else: size = [20] * N source1.data["size"] = size session.store_objects(source1) source2.on_change('selected', on_selection_change2) reset = Button(label="Reset") def on_reset_click(): source1.selected = [] source2.selected = [] session.store_objects(source1, source2) reset.on_click(on_reset_click) vbox = VBox(children=[reset], width=150) hbox = HBox(children=[vbox, plot1, plot2]) document.add(hbox) session.store_document(document)
def create_goto_event_id_widget(self): self.w_goto_event_id = Button(label="GOTO ID", button_type="default", width=70) self.w_goto_event_id.on_click(self.on_goto_event_id_widget_click)
def __init__(self): self.zoom = 12 self.center = self.start_location # Set up map lon_text = TextInput(value='', title='lon:') lat_text = TextInput(value='', title='lat:') self.lonlat_text_inputs = [lon_text, lat_text] self.topo_map = TopoMap(WORKING_POLYGON) self.folium_fig = self.bokeh_new_class_folium( lonlat_text_inputs=self.lonlat_text_inputs) # Set up widgets self.meters_step = Slider(title="meters_step", value=400, start=10, end=500, step=10) self.number_of_points_to_show = Slider( title="number of points to show", value=2, start=1, end=100) self.threshold = Slider(title="threshold for class", value=0, start=0, end=1, step=0.01) self.test_minimal_resolution = Slider(title="minimal resolution", value=8, start=2, end=50) get_points_button = Button(label='Get desired points!') get_points_button.on_click(self.get_points_and_update) set_working_polygon_button = Button(label='Set working polygon!') set_working_polygon_button.on_click(self.set_working_polygon) clean_all_buttun = Button(label='clean all') clean_all_buttun.on_click(self.clean_all) clean_text_buttun = Button(label='clean text') clean_text_buttun.on_click(self.clean_text) select_class_options = self.topo_map.get_all_available_classes() self.select_class = Select(title="Option:", value=select_class_options[0], options=select_class_options) get_class_button = Button(label='get_class') get_class_button.on_click(self.get_points_and_update_for_class) select_final_model_options = client_lib.get_available_final_model_file_names( ) self.select_final_model = Select(title="Option:", value=select_final_model_options[0], options=select_final_model_options) final_model_button = Button(label='select final model') final_model_button.on_click(self.update_final_model) get_segmentation_map_button = Button(label='get segmentation map') get_segmentation_map_button.on_click(self.add_segmentation_map) self.row_mid_column = column(Div(text='get top points of class'), self.select_class, get_class_button, get_segmentation_map_button, self.select_final_model, final_model_button, Div(text='')) # Set up layouts and add to document inputs = row( column(Div(text='get similar points'), lon_text, lat_text, get_points_button, set_working_polygon_button, clean_all_buttun, clean_text_buttun), self.row_mid_column, column(Div(text='search parameters'), self.meters_step, self.number_of_points_to_show, self.threshold, self.test_minimal_resolution)) self.main_panel = row(inputs, self.folium_fig, width=800)
class BokehFileViewer(Tool): name = "BokehFileViewer" description = ("Interactively explore an event file using the bokeh " "visualisation package") port = Int(5006, help="Port to open bokeh server onto").tag(config=True) disable_server = Bool(False, help="Do not start the bokeh server " "(useful for testing)").tag(config=True) default_url = get_dataset_path("gamma_test_large.simtel.gz") EventSource.input_url.default_value = default_url extractor_product = traits.create_class_enum_trait( ImageExtractor, default_value="NeighborPeakWindowSum") aliases = Dict( dict( port="BokehFileViewer.port", disable_server="BokehFileViewer.disable_server", f="EventSource.input_url", max_events="EventSource.max_events", extractor="BokehFileViewer.extractor_product", )) classes = List([ EventSource, ] + traits.classes_with_traits(ImageExtractor)) def __init__(self, **kwargs): super().__init__(**kwargs) self._event = None self._event_index = None self._event_id = None self._telid = None self._channel = None self.w_next_event = None self.w_previous_event = None self.w_event_index = None self.w_event_id = None self.w_goto_event_index = None self.w_goto_event_id = None self.w_telid = None self.w_channel = None self.w_dl1_dict = None self.wb_extractor = None self.layout = None self.reader = None self.seeker = None self.extractor = None self.calibrator = None self.viewer = None self._updating_dl1 = False # make sure, gzip files are seekable self.config.SimTelEventSource.back_seekable = True def setup(self): self.log_format = "%(levelname)s: %(message)s [%(name)s.%(funcName)s]" self.reader = EventSource.from_config(parent=self) self.seeker = EventSeeker(self.reader, parent=self) self.extractor = ImageExtractor.from_name( self.extractor_product, parent=self, subarray=self.reader.subarray, ) self.calibrator = CameraCalibrator( subarray=self.reader.subarray, parent=self, image_extractor=self.extractor, ) self.viewer = BokehEventViewer(parent=self, subarray=self.reader.subarray) # Setup widgets self.viewer.create() self.viewer.enable_automatic_index_increment() self.create_previous_event_widget() self.create_next_event_widget() self.create_event_index_widget() self.create_goto_event_index_widget() self.create_event_id_widget() self.create_goto_event_id_widget() self.create_telid_widget() self.create_channel_widget() self.create_dl1_widgets() self.update_dl1_widget_values() # Setup layout self.layout = layout([ [self.viewer.layout], [ self.w_previous_event, self.w_next_event, self.w_goto_event_index, self.w_goto_event_id, ], [self.w_event_index, self.w_event_id], [self.w_telid, self.w_channel], [self.wb_extractor], ]) def start(self): self.event_index = 0 def finish(self): if not self.disable_server: def modify_doc(doc): doc.add_root(self.layout) doc.title = self.name directory = os.path.abspath(os.path.dirname(__file__)) theme_path = os.path.join(directory, "theme.yaml") template_path = os.path.join(directory, "templates") doc.theme = Theme(filename=theme_path) env = jinja2.Environment( loader=jinja2.FileSystemLoader(template_path)) doc.template = env.get_template("index.html") self.log.info("Opening Bokeh application on " "http://localhost:{}/".format(self.port)) server = Server({"/": modify_doc}, num_procs=1, port=self.port) server.start() server.io_loop.add_callback(server.show, "/") server.io_loop.start() @property def event_index(self): return self._event_index @event_index.setter def event_index(self, val): try: self.event = self.seeker[val] except IndexError: self.log.warning(f"Event Index {val} does not exist") @property def event_id(self): return self._event_id @event_id.setter def event_id(self, val): try: self.event = self.seeker[str(val)] except IndexError: self.log.warning(f"Event ID {val} does not exist") @property def telid(self): return self._telid @telid.setter def telid(self, val): self.channel = 0 tels = list(self.event.r0.tels_with_data) if val not in tels: val = tels[0] self._telid = val self.viewer.telid = val self.update_telid_widget() @property def channel(self): return self._channel @channel.setter def channel(self, val): self._channel = val self.viewer.channel = val self.update_channel_widget() @property def event(self): return self._event @event.setter def event(self, val): self.calibrator(val) self._event = val self.viewer.event = val self._event_index = val.count self._event_id = val.index.event_id self.update_event_index_widget() self.update_event_id_widget() self._telid = self.viewer.telid self.update_telid_widget() self._channel = self.viewer.channel self.update_channel_widget() def update_dl1_calibrator(self, extractor=None): """ Recreate the dl1 calibrator with the specified extractor and cleaner Parameters ---------- extractor : ctapipe.image.extractor.ImageExtractor """ if extractor is None: extractor = self.calibrator.image_extractor self.extractor = extractor self.calibrator = CameraCalibrator( subarray=self.reader.subarray, parent=self, image_extractor=self.extractor, ) self.viewer.refresh() def create_next_event_widget(self): self.w_next_event = Button(label=">", button_type="default", width=50) self.w_next_event.on_click(self.on_next_event_widget_click) def on_next_event_widget_click(self): self.event_index += 1 def create_previous_event_widget(self): self.w_previous_event = Button(label="<", button_type="default", width=50) self.w_previous_event.on_click(self.on_previous_event_widget_click) def on_previous_event_widget_click(self): self.event_index -= 1 def create_event_index_widget(self): self.w_event_index = TextInput(title="Event Index:", value="") def update_event_index_widget(self): if self.w_event_index: self.w_event_index.value = str(self.event_index) def create_event_id_widget(self): self.w_event_id = TextInput(title="Event ID:", value="") def update_event_id_widget(self): if self.w_event_id: self.w_event_id.value = str(self.event_id) def create_goto_event_index_widget(self): self.w_goto_event_index = Button(label="GOTO Index", button_type="default", width=100) self.w_goto_event_index.on_click(self.on_goto_event_index_widget_click) def on_goto_event_index_widget_click(self): self.event_index = int(self.w_event_index.value) def create_goto_event_id_widget(self): self.w_goto_event_id = Button(label="GOTO ID", button_type="default", width=70) self.w_goto_event_id.on_click(self.on_goto_event_id_widget_click) def on_goto_event_id_widget_click(self): self.event_id = int(self.w_event_id.value) def create_telid_widget(self): self.w_telid = Select(title="Telescope:", value="", options=[]) self.w_telid.on_change("value", self.on_telid_widget_change) def update_telid_widget(self): if self.w_telid: tels = [str(t) for t in self.event.r0.tels_with_data] self.w_telid.options = tels self.w_telid.value = str(self.telid) def on_telid_widget_change(self, _, __, ___): if self.telid != int(self.w_telid.value): self.telid = int(self.w_telid.value) def create_channel_widget(self): self.w_channel = Select(title="Channel:", value="", options=[]) self.w_channel.on_change("value", self.on_channel_widget_change) def update_channel_widget(self): if self.w_channel: try: n_chan = self.event.r0.tel[self.telid].waveform.shape[0] except AttributeError: n_chan = 1 channels = [str(c) for c in range(n_chan)] self.w_channel.options = channels self.w_channel.value = str(self.channel) def on_channel_widget_change(self, _, __, ___): if self.channel != int(self.w_channel.value): self.channel = int(self.w_channel.value) def create_dl1_widgets(self): self.w_dl1_dict = dict( extractor=Select( title="Extractor:", value="", width=5, options=BokehFileViewer.extractor_product.values, ), extractor_window_start=TextInput(title="Window Start:", value=""), extractor_window_width=TextInput(title="Window Width:", value=""), extractor_window_shift=TextInput(title="Window Shift:", value=""), extractor_lwt=TextInput(title="Local Pixel Weight:", value=""), ) for val in self.w_dl1_dict.values(): val.on_change("value", self.on_dl1_widget_change) self.wb_extractor = widgetbox( PreText(text="Charge Extractor Configuration"), self.w_dl1_dict["extractor"], self.w_dl1_dict["extractor_window_start"], self.w_dl1_dict["extractor_window_width"], self.w_dl1_dict["extractor_window_shift"], self.w_dl1_dict["extractor_lwt"], ) def update_dl1_widget_values(self): if self.w_dl1_dict: for key, val in self.w_dl1_dict.items(): if "extractor" in key: if key == "extractor": val.value = self.extractor.__class__.__name__ else: key = key.replace("extractor_", "") try: val.value = str(getattr(self.extractor, key)) except AttributeError: val.value = "" def on_dl1_widget_change(self, _, __, ___): if self.event: if not self._updating_dl1: self._updating_dl1 = True cmdline = [] for key, val in self.w_dl1_dict.items(): k = key.replace("extractor_", "ImageExtractor.") if val.value: cmdline.append(f"--{k}={val.value}") self.parse_command_line(cmdline) extractor = ImageExtractor.from_name(self.extractor_product, parent=self) self.update_dl1_calibrator(extractor) self.update_dl1_widget_values() self._updating_dl1 = False
text_font_size="20pt", 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(): global 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))
def create_next_event_widget(self): self.w_next_event = Button(label=">", button_type="default", width=50) self.w_next_event.on_click(self.on_next_event_widget_click)
def eda_projects_tab(panel_title): lags_corr_src = ColumnDataSource(data=dict(variable_1=[], variable_2=[], relationship=[], lag=[], r=[], p_value=[])) class Thistab(Mytab): def __init__(self, table, cols, dedup_cols=[]): Mytab.__init__(self, table, cols, dedup_cols) self.table = table self.cols = cols self.DATEFORMAT = "%Y-%m-%d %H:%M:%S" self.df = None self.df1 = None self.df_predict = None self.day_diff = 1 # for normalizing for classification periods of different lengths self.df_grouped = '' self.cl = PythonClickhouse('aion') self.trigger = 0 self.groupby_dict = { 'project_duration': 'sum', 'project_start_delay': 'mean', 'project_end_delay': 'mean', 'project_owner_age': 'mean', 'project_owner_gender': 'mean', 'milestone_duration': 'sum', 'milestone_start_delay': 'mean', 'milestone_end_delay': 'mean', 'milestone_owner_age': 'mean', 'milestone_owner_gender': 'mean', 'task_duration': 'sum', 'task_start_delay': 'sum', 'task_end_delay': 'mean', 'task_owner_age': 'mean', 'task_owner_gender': 'mean' } self.feature_list = list(self.groupby_dict.keys()) self.lag_variable = 'task_duration' self.lag_days = "1,2,3" self.lag = 0 self.lag_menu = [str(x) for x in range(0, 100)] self.strong_thresh = .65 self.mod_thresh = 0.4 self.weak_thresh = 0.25 self.corr_df = None self.div_style = """ style='width:350px; margin-left:25px; border:1px solid #ddd;border-radius:3px;background:#efefef50;' """ self.header_style = """ style='color:blue;text-align:center;' """ self.variables = sorted(list(self.groupby_dict.keys())) self.variable = self.variables[0] self.relationships_to_check = ['weak', 'moderate', 'strong'] self.status = 'all' self.pm_gender = 'all' self.m_gender = 'all' self.t_gender = 'all' self.type = 'all' self.pym = PythonMongo('aion') self.menus = { 'status': ['all', 'open', 'closed'], 'type': [ 'all', 'research', 'reconciliation', 'audit', 'innovation', 'construction', 'manufacturing', 'conference' ], 'gender': ['all', 'male', 'female'], 'variables': list(self.groupby_dict.keys()), 'history_periods': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'], } self.multiline_vars = {'x': 'manager_gender', 'y': 'remuneration'} self.timestamp_col = 'project_startdate_actual' # ------- DIVS setup begin self.page_width = 1250 txt = """<hr/> <div style="text-align:center;width:{}px;height:{}px; position:relative;background:black;margin-bottom:200px"> <h1 style="color:#fff;margin-bottom:300px">{}</h1> </div>""".format(self.page_width, 50, 'Welcome') self.notification_div = { 'top': Div(text=txt, width=self.page_width, height=20), 'bottom': Div(text=txt, width=self.page_width, height=10), } lag_section_head_txt = 'Lag relationships between {} and...'.format( self.variable) self.section_divider = '-----------------------------------' self.section_headers = { 'lag': self.section_header_div(text=lag_section_head_txt, width=600, html_header='h2', margin_top=5, margin_bottom=-155), 'distribution': self.section_header_div(text='Pre-transform distribution:', width=600, html_header='h2', margin_top=5, margin_bottom=-155), 'relationships': self.section_header_div( text='Relationships between variables:{}'.format( self.section_divider), width=600, html_header='h2', margin_top=5, margin_bottom=-155), 'correlations': self.section_header_div(text='Correlations:', width=600, html_header='h3', margin_top=5, margin_bottom=-155), } # ----- UPDATED DIVS END # ---------------------- DIVS ---------------------------- def section_header_div(self, text, html_header='h2', width=600, margin_top=150, margin_bottom=-150): text = """<div style="margin-top:{}px;margin-bottom:-{}px;"><{} style="color:#4221cc;">{}</{}></div>""" \ .format(margin_top, margin_bottom, html_header, text, html_header) return Div(text=text, width=width, height=15) def notification_updater(self, text): txt = """<div style="text-align:center;background:black;width:100%;"> <h4 style="color:#fff;"> {}</h4></div>""".format(text) for key in self.notification_div.keys(): self.notification_div[key].text = txt def reset_adoption_dict(self, variable): self.significant_effect_dict[variable] = [] # ////////////// DIVS ///////////////////////////////// def title_div(self, text, width=700): text = '<h2 style="color:#4221cc;">{}</h2>'.format(text) return Div(text=text, width=width, height=15) def corr_information_div(self, width=400, height=300): div_style = """ style='width:350px; margin-left:-600px; border:1px solid #ddd;border-radius:3px;background:#efefef50;' """ txt = """ <div {}> <h4 {}>How to interpret relationships </h4> <ul style='margin-top:-10px;'> <li> Positive: as variable 1 increases, so does variable 2. </li> <li> Negative: as variable 1 increases, variable 2 decreases. </li> <li> Strength: decisions can be made on the basis of strong and moderate relationships. </li> <li> No relationship/not significant: no statistical support for decision making. </li> <li> The scatter graphs (below) are useful for visual confirmation. </li> <li> The histogram (right) shows the distribution of the variable. </li> </ul> </div> """.format(div_style, self.header_style) div = Div(text=txt, width=width, height=height) return div # ///////////////////////////////////////////////////////////// def filter_df(self, df1): if self.status != 'all': df1 = df1[df1.status == self.status] if self.pm_gender != 'all': df1 = df1[df1.project_owner_gender == self.pm_gender] if self.m_gender != 'all': df1 = df1[df1.milestone_owner_gender == self.m_gender] if self.t_gender != 'all': df1 = df1[df1.task_owner_gender == self.t_gender] if self.type != 'all': df1 = df1[df1.type == self.type] return df1 def prep_data(self, df1): try: ''' df1[self.timestamp_col] = df1[self.timestamp_col].apply(lambda x: datetime(x.year, x.month, x.day, x.hour,0,0)) ''' df1 = df1.set_index(self.timestamp_col) logger.warning('LINE 195 df:%s', df1.head()) # handle lag for all variables df = df1.copy() df = self.filter_df(df) logger.warning('LINE 199: length before:%s', len(df)) slice = df[['project']] df = df[list(self.groupby_dict.keys())] logger.warning('LINE 218: columns:%s', df.head()) df = df.astype(float) df = pd.concat([df, slice], axis=1) df = df.groupby('project').resample(self.resample_period).agg( self.groupby_dict) logger.warning('LINE 201: length after:%s', len(df)) df = df.reset_index() vars = self.feature_list.copy() if int(self.lag) > 0: for var in vars: if self.variable != var: df[var] = df[var].shift(int(self.lag)) df = df.dropna() self.df1 = df logger.warning('line 184- prep data: df:%s', self.df.head(10)) except Exception: logger.error('prep data', exc_info=True) def lags_plot(self, launch): try: df = self.df.copy() df = df[[self.lag_variable, self.variable]] cols = [self.lag_variable] lags = self.lag_days.split(',') for day in lags: try: label = self.lag_variable + '_' + day df[label] = df[self.lag_variable].shift(int(day)) cols.append(label) except: logger.warning('%s is not an integer', day) df = df.dropna() self.lags_corr(df) # plot the comparison logger.warning('in lags plot: df:%s', df.head(10)) return df.hvplot(x=self.variable, y=cols, kind='scatter', alpha=0.4) except Exception: logger.error('lags plot', exc_info=True) # calculate the correlation produced by the lags vector def lags_corr(self, df): try: corr_dict_data = { 'variable_1': [], 'variable_2': [], 'relationship': [], 'lag': [], 'r': [], 'p_value': [] } a = df[self.variable].tolist() for col in df.columns: if col not in [self.timestamp_col, self.variable]: # find lag var = col.split('_') try: tmp = int(var[-1]) lag = tmp except Exception: lag = 'None' b = df[col].tolist() slope, intercept, rvalue, pvalue, txt = self.corr_label( a, b) corr_dict_data['variable_1'].append(self.variable) corr_dict_data['variable_2'].append(col) corr_dict_data['relationship'].append(txt) corr_dict_data['lag'].append(lag) corr_dict_data['r'].append(round(rvalue, 4)) corr_dict_data['p_value'].append(round(pvalue, 4)) lags_corr_src.stream(corr_dict_data, rollover=(len(corr_dict_data['lag']))) columns = [ TableColumn(field="variable_1", title="variable 1"), TableColumn(field="variable_2", title="variable 2"), TableColumn(field="relationship", title="relationship"), TableColumn(field="lag", title="lag(days)"), TableColumn(field="r", title="r"), TableColumn(field="p_value", title="p_value"), ] data_table = DataTable(source=lags_corr_src, columns=columns, width=500, height=280) return data_table except Exception: logger.error('lags corr', exc_info=True) def correlation_table(self, launch): try: corr_dict = { 'Variable 1': [], 'Variable 2': [], 'Relationship': [], 'r': [], 'p-value': [] } # prep df df = self.df1 # get difference for money columns df = df.drop(self.timestamp_col, axis=1) # df = df.compute() a = df[self.variable].tolist() for col in self.feature_list: logger.warning('col :%s', col) if col != self.variable: logger.warning('%s:%s', col, self.variable) b = df[col].tolist() slope, intercept, rvalue, pvalue, txt = self.corr_label( a, b) # add to dict corr_dict['Variable 1'].append(self.variable) corr_dict['Variable 2'].append(col) corr_dict['Relationship'].append(txt) corr_dict['r'].append(round(rvalue, 4)) corr_dict['p-value'].append(round(pvalue, 4)) df = pd.DataFrame({ 'Variable 1': corr_dict['Variable 1'], 'Variable 2': corr_dict['Variable 2'], 'Relationship': corr_dict['Relationship'], 'r': corr_dict['r'], 'p-value': corr_dict['p-value'] }) # logger.warning('df:%s',df.head(23)) return df.hvplot.table(columns=[ 'Variable 1', 'Variable 2', 'Relationship', 'r', 'p-value' ], width=550, height=200, title='Correlation between variables') except Exception: logger.error('correlation table', exc_info=True) def non_parametric_relationship_table(self, launch): try: corr_dict = { 'Variable 1': [], 'Variable 2': [], 'Relationship': [], 'stat': [], 'p-value': [] } # prep df df = self.df1 # get difference for money columns df = df.drop(self.timestamp_col, axis=1) # df = df.compute() # logger.warning('line df:%s',df.head(10)) a = df[self.variable].tolist() for col in self.feature_list: logger.warning('col :%s', col) if col != self.variable: logger.warning('%s:%s', col, self.variable) b = df[col].tolist() stat, pvalue, txt = self.mann_whitneyu_label(a, b) corr_dict['Variable 1'].append(self.variable) corr_dict['Variable 2'].append(col) corr_dict['Relationship'].append(txt) corr_dict['stat'].append(round(stat, 4)) corr_dict['p-value'].append(round(pvalue, 4)) df = pd.DataFrame({ 'Variable 1': corr_dict['Variable 1'], 'Variable 2': corr_dict['Variable 2'], 'Relationship': corr_dict['Relationship'], 'stat': corr_dict['stat'], 'p-value': corr_dict['p-value'] }) # logger.warning('df:%s',df.head(23)) return df.hvplot.table( columns=[ 'Variable 1', 'Variable 2', 'Relationship', 'stat', 'p-value' ], width=550, height=200, title='Non parametric relationship between variables') except Exception: logger.error('non parametric table', exc_info=True) def hist(self, launch): try: return self.df.hvplot.hist(y=self.feature_list, subplots=True, shared_axes=False, bins=25, alpha=0.3, width=300).cols(4) except Exception: logger.warning('histogram', exc_info=True) def matrix_plot(self, launch=-1): try: logger.warning('line 306 self.feature list:%s', self.feature_list) df = self.df1 if df is not None: # thistab.prep_data(thistab.df) if self.timestamp_col in df.columns: df = df.drop(self.timestamp_col, axis=1) df = df.fillna(0) # logger.warning('line 302. df: %s',df.head(10)) cols_temp = self.feature_list.copy() if self.variable in cols_temp: cols_temp.remove(self.variable) # variable_select.options = cols_lst p = df.hvplot.scatter(x=self.variable, y=cols_temp, width=330, subplots=True, shared_axes=False, xaxis=False).cols(4) else: p = df.hvplot.scatter(x=[0, 0, 0], y=[0, 0, 0], width=330) return p except Exception: logger.error('matrix plot', exc_info=True) def multiline(self, launch=1): try: yvar = self.multiline_vars['y'] xvar = self.multiline_vars['x'] df = self.df.copy() df = df[[xvar, yvar, self.timestamp_col]] df = df.set_index(self.timestamp_col) df = df.groupby(xvar).resample(self.resample_period).agg( {yvar: 'mean'}) df = df.reset_index() lines = df[xvar].unique() # split data frames dfs = {} for idx, line in enumerate(lines): dfs[line] = df[df[xvar] == line] dfs[line] = dfs[line].fillna(0) logger.warning('LINE 428:%s - %s:', line, dfs[line].head()) if idx == 0: p = dfs[line].hvplot.line(x=self.timestamp_col, y=yvar, width=1200, height=500).relabel(line) else: p *= dfs[line].hvplot.line(x=self.timestamp_col, y=yvar, width=2, height=500).relabel(line) return p except Exception: logger.error('multiline plot', exc_info=True) def update_variable(attr, old, new): thistab.notification_updater("Calculations in progress! Please wait.") thistab.prep_data(thistab.df) if 'milestone owner gender' == new: thistab.variable = 'm_gender_code' if 'project owner gender' == new: thistab.variable = 'pm_gender_code' if 'task owner gender' == new: thistab.variable = 't_gender_code' if thistab.variable in thistab.adoption_variables['developer']: thistab.reset_adoption_dict(thistab.variable) thistab.section_head_updater('lag', thistab.variable) thistab.trigger += 1 stream_launch_matrix.event(launch=thistab.trigger) stream_launch_corr.event(launch=thistab.trigger) thistab.notification_updater("Ready!") def update_lag_plot_variable(attr, old, new): thistab.notification_updater("Calculations in progress! Please wait.") thistab.lag_variable = new thistab.prep_data(thistab.df) thistab.trigger += 1 stream_launch_lags_var.event(launch=thistab.trigger) thistab.notification_updater("Ready!") def update_IVs(attrname, old, new): thistab.notification_updater("Calculations in progress! Please wait.") thistab.pm_gender = pm_gender_select.value thistab.m_gender = m_gender_select.value thistab.t_gender = t_gender_select.value thistab.status = status_select.value thistab.type = type_select.value thistab.prep_data(thistab.df) thistab.trigger += 1 stream_launch_matrix.event(launch=thistab.trigger) stream_launch_corr.event(launch=thistab.trigger) thistab.notification_updater("Ready!") def update_lag(attr, old, new): # update lag & cryptocurrency thistab.notification_updater("Calculations in progress! Please wait.") thistab.lag = int(lag_select.value) thistab.prep_data(thistab.df) thistab.trigger += 1 stream_launch_matrix.event(launch=thistab.trigger) stream_launch_corr.event(launch=thistab.trigger) thistab.notification_updater("Ready!") def update(attrname, old, new): thistab.notification_updater( "Calculations underway. Please be patient") thistab.df = thistab.pym.load_df(start_date=datepicker_start.value, end_date=datepicker_end.value, cols=[], table=thistab.table, timestamp_col=thistab.timestamp_col) thistab.df['project_owner_gender'] = thistab.df[ 'project_owner_gender'].apply(lambda x: 1 if x == 'male' else 2) thistab.df['milestone_owner_gender'] = thistab.df[ 'milestone_owner_gender'].apply(lambda x: 1 if x == 'male' else 2) thistab.df['task_owner_gender'] = thistab.df[ 'task_owner_gender'].apply(lambda x: 1 if x == 'male' else 2) thistab.prep_data(thistab.df) thistab.trigger += 1 stream_launch_matrix.event(launch=thistab.trigger) stream_launch_corr.event(launch=thistab.trigger) thistab.notification_updater("Ready!") def update_resample(attrname, old, new): thistab.notification_updater( "Calculations underway. Please be patient") thistab.resample_period = new thistab.prep_data(thistab.df) thistab.trigger += 1 stream_launch_matrix.event(launch=thistab.trigger) stream_launch_corr.event(launch=thistab.trigger) stream_launch.event(launch=thistab.trigger) thistab.notification_updater("Ready!") def update_lags_selected(): thistab.notification_updater("Calculations in progress! Please wait.") thistab.lag_days = lags_input.value logger.warning('line 381, new checkboxes: %s', thistab.lag_days) thistab.trigger += 1 stream_launch_lags_var.event(launch=thistab.trigger) stream_launch.event(launch=thistab.trigger) thistab.notification_updater("Ready!") def update_multiline(attrname, old, new): thistab.notification_updater("Calculations in progress! Please wait.") thistab.multiline_vars['x'] = multiline_x_select.value thistab.multiline_vars['y'] = multiline_y_select.value thistab.trigger += 1 stream_launch.event(launch=thistab.trigger) thistab.notification_updater("Ready!") try: # SETUP table = 'project_composite1' thistab = Thistab(table, [], []) # setup dates first_date_range = datetime.strptime("2013-04-25 00:00:00", "%Y-%m-%d %H:%M:%S") last_date_range = datetime.now().date() last_date = dashboard_config['dates']['last_date'] - timedelta(days=2) first_date = last_date - timedelta(days=30) # initial function call thistab.df = thistab.pym.load_df(start_date=first_date, end_date=last_date, cols=[], table=thistab.table, timestamp_col=thistab.timestamp_col) if len(thistab.df) > 0: thistab.df['manager_gender'] = thistab.df['project_owner_gender'] thistab.df['project_owner_gender'] = thistab.df[ 'project_owner_gender'].apply(lambda x: 1 if x == 'male' else 2) thistab.df['milestone_owner_gender'] = thistab.df[ 'milestone_owner_gender'].apply(lambda x: 1 if x == 'male' else 2) thistab.df['task_owner_gender'] = thistab.df[ 'task_owner_gender'].apply(lambda x: 1 if x == 'male' else 2) logger.warning('LINE 527:columns %s', list(thistab.df.columns)) thistab.prep_data(thistab.df) # MANAGE STREAM stream_launch_hist = streams.Stream.define('Launch', launch=-1)() stream_launch_matrix = streams.Stream.define('Launch_matrix', launch=-1)() stream_launch_corr = streams.Stream.define('Launch_corr', launch=-1)() stream_launch_lags_var = streams.Stream.define('Launch_lag_var', launch=-1)() stream_launch = streams.Stream.define('Launch', launch=-1)() # CREATE WIDGETS datepicker_start = DatePicker(title="Start", min_date=first_date_range, max_date=last_date_range, value=first_date) datepicker_end = DatePicker(title="End", min_date=first_date_range, max_date=last_date_range, value=last_date) variable_select = Select(title='Select variable', value=thistab.variable, options=thistab.variables) lag_variable_select = Select(title='Select lag variable', value=thistab.lag_variable, options=thistab.feature_list) lag_select = Select(title='Select lag', value=str(thistab.lag), options=thistab.lag_menu) type_select = Select(title='Select project type', value=thistab.type, options=thistab.menus['type']) status_select = Select(title='Select project status', value=thistab.status, options=thistab.menus['status']) pm_gender_select = Select(title="Select project owner's gender", value=thistab.pm_gender, options=thistab.menus['gender']) m_gender_select = Select(title="Select milestone owner's gender", value=thistab.m_gender, options=thistab.menus['gender']) t_gender_select = Select(title="Select task owner's gender", value=thistab.t_gender, options=thistab.menus['gender']) resample_select = Select(title='Select resample period', value='D', options=['D', 'W', 'M', 'Q']) multiline_y_select = Select(title='Select comparative DV(y)', value=thistab.multiline_vars['y'], options=[ 'remuneration', 'delay_start', 'delay_end', 'project_duration' ]) multiline_x_select = Select( title='Select comparative IV(x)', value=thistab.multiline_vars['x'], options=['manager_gender', 'type', 'status']) lags_input = TextInput( value=thistab.lag_days, title="Enter lags (integer(s), separated by comma)", height=55, width=300) lags_input_button = Button(label="Select lags, then click me!", width=10, button_type="success") # --------------------- PLOTS---------------------------------- columns = [ TableColumn(field="variable_1", title="variable 1"), TableColumn(field="variable_2", title="variable 2"), TableColumn(field="relationship", title="relationship"), TableColumn(field="lag", title="lag(days)"), TableColumn(field="r", title="r"), TableColumn(field="p_value", title="p_value"), ] lags_corr_table = DataTable(source=lags_corr_src, columns=columns, width=500, height=200) hv_matrix_plot = hv.DynamicMap(thistab.matrix_plot, streams=[stream_launch_matrix]) hv_corr_table = hv.DynamicMap(thistab.correlation_table, streams=[stream_launch_corr]) hv_nonpara_table = hv.DynamicMap( thistab.non_parametric_relationship_table, streams=[stream_launch_corr]) # hv_hist_plot = hv.DynamicMap(thistab.hist, streams=[stream_launch_hist]) hv_lags_plot = hv.DynamicMap(thistab.lags_plot, streams=[stream_launch_lags_var]) hv_multiline = hv.DynamicMap(thistab.multiline, streams=[stream_launch]) matrix_plot = renderer.get_plot(hv_matrix_plot) corr_table = renderer.get_plot(hv_corr_table) nonpara_table = renderer.get_plot(hv_nonpara_table) lags_plot = renderer.get_plot(hv_lags_plot) multiline = renderer.get_plot(hv_multiline) # setup divs # handle callbacks variable_select.on_change('value', update_variable) lag_variable_select.on_change('value', update_lag_plot_variable) lag_select.on_change('value', update_lag) # individual lag resample_select.on_change('value', update_resample) pm_gender_select.on_change('value', update_IVs) m_gender_select.on_change('value', update_IVs) t_gender_select.on_change('value', update_IVs) datepicker_start.on_change('value', update) datepicker_end.on_change('value', update) lags_input_button.on_click(update_lags_selected) # lags array status_select.on_change('value', update_IVs) type_select.on_change('value', update_IVs) multiline_x_select.on_change('value', update_multiline) multiline_y_select.on_change('value', update_multiline) # COMPOSE LAYOUT # put the controls in a single element controls_lag = WidgetBox(lags_input, lags_input_button, lag_variable_select) controls_multiline = WidgetBox(multiline_x_select, multiline_y_select) controls_page = WidgetBox(datepicker_start, datepicker_end, variable_select, type_select, status_select, resample_select, pm_gender_select, m_gender_select, t_gender_select) controls_gender = WidgetBox(pm_gender_select, m_gender_select, t_gender_select) # create the dashboards grid = gridplot( [[thistab.notification_div['top']], [Spacer(width=20, height=70)], [thistab.section_headers['relationships']], [Spacer(width=20, height=30)], [matrix_plot.state, controls_page], [thistab.section_headers['correlations']], [Spacer(width=20, height=30)], [corr_table.state, thistab.corr_information_div()], [thistab.title_div('Compare levels in a variable', 400)], [Spacer(width=20, height=30)], [multiline.state, controls_multiline], [thistab.section_headers['lag']], [Spacer(width=20, height=30)], [lags_plot.state, controls_lag], [lags_corr_table], [thistab.notification_div['bottom']]]) # Make a tab with the layout tab = Panel(child=grid, title=panel_title) return tab except Exception: logger.error('EDA projects:', exc_info=True) return tab_error_flag(panel_title)
# drop down hour selector hour_interval_selector = Select(title='Hour interval', options=list(time_interval_dict.keys()), value='00:00') hour_interval_selector.on_change('value', lambda attr, old, new: update()) # minimum traffic flux slider flux_slider = Slider(start=0, end=30, value=0, step=1, width=1, align='start', title='Lower limit of total traffic flux') # allows scaling before update flux_slider.value = flux_slider.value flux_slider.on_change('value', lambda attr, old, new: update()) # hourly drop down and minimum flux selector hour_inputs = widgetbox(hour_interval_selector, sizing_mode='scale_width') slider_input = widgetbox(flux_slider, sizing_mode='scale_width') # video time lapse button button = Button(label='► Play', width=60, sizing_mode='scale_width', name='Traffic time lapse', align='end') button.on_click(animate)
def on_selection_change2(obj, attr, _, inds): inds = inds["1d"]["indices"] if inds: [index] = inds size = [10] * N size[index] = 40 else: size = [20] * N source1.data["size"] = size session.store_objects(source1) source2.on_change("selected", on_selection_change2) reset = Button(label="Reset") def on_reset_click(): source1.selected = {"0d": {"flag": False, "indices": []}, "1d": {"indices": []}, "2d": {"indices": []}} source2.selected = {"0d": {"flag": False, "indices": []}, "1d": {"indices": []}, "2d": {"indices": []}} session.store_objects(source1, source2) reset.on_click(on_reset_click) vbox = VBox(children=[reset], width=150) hbox = HBox(children=[vbox, plot1, plot2]) document.add(hbox) session.store_document(document)
class BokehFileViewer(Tool): name = "BokehFileViewer" description = ("Interactively explore an event file using the bokeh " "visualisation package") port = Int(5006, help="Port to open bokeh server onto").tag(config=True) disable_server = Bool(False, help="Do not start the bokeh server " "(useful for testing)").tag(config=True) aliases = Dict( dict( port='BokehFileViewer.port', disable_server='BokehFileViewer.disable_server', r='EventSourceFactory.product', f='EventSourceFactory.input_url', max_events='EventSourceFactory.max_events', ped='CameraR1CalibratorFactory.pedestal_path', tf='CameraR1CalibratorFactory.tf_path', pe='CameraR1CalibratorFactory.pe_path', ff='CameraR1CalibratorFactory.ff_path', extractor='ChargeExtractorFactory.product', extractor_t0='ChargeExtractorFactory.t0', extractor_window_width='ChargeExtractorFactory.window_width', extractor_window_shift='ChargeExtractorFactory.window_shift', extractor_sig_amp_cut_HG='ChargeExtractorFactory.sig_amp_cut_HG', extractor_sig_amp_cut_LG='ChargeExtractorFactory.sig_amp_cut_LG', extractor_lwt='ChargeExtractorFactory.lwt', cleaner='WaveformCleanerFactory.product', )) classes = List([ EventSourceFactory, ChargeExtractorFactory, CameraR1CalibratorFactory, CameraDL1Calibrator, WaveformCleanerFactory ]) def __init__(self, **kwargs): super().__init__(**kwargs) self._event = None self._event_index = None self._event_id = None self._telid = None self._channel = None self.w_next_event = None self.w_previous_event = None self.w_event_index = None self.w_event_id = None self.w_goto_event_index = None self.w_goto_event_id = None self.w_telid = None self.w_channel = None self.w_dl1_dict = None self.wb_extractor = None self.layout = None self.reader = None self.seeker = None self.extractor = None self.cleaner = None self.r1 = None self.dl0 = None self.dl1 = None self.viewer = None self._updating_dl1 = False def setup(self): self.log_format = "%(levelname)s: %(message)s [%(name)s.%(funcName)s]" kwargs = dict(config=self.config, tool=self) default_url = get_dataset_path("gamma_test.simtel.gz") EventSourceFactory.input_url.default_value = default_url self.reader = EventSourceFactory.produce(**kwargs) self.seeker = EventSeeker(self.reader, **kwargs) self.extractor = ChargeExtractorFactory.produce(**kwargs) self.cleaner = WaveformCleanerFactory.produce(**kwargs) self.r1 = CameraR1CalibratorFactory.produce(eventsource=self.reader, **kwargs) self.dl0 = CameraDL0Reducer(**kwargs) self.dl1 = CameraDL1Calibrator(extractor=self.extractor, cleaner=self.cleaner, **kwargs) self.viewer = BokehEventViewer(**kwargs) # Setup widgets self.viewer.create() self.viewer.enable_automatic_index_increment() self.create_previous_event_widget() self.create_next_event_widget() self.create_event_index_widget() self.create_goto_event_index_widget() self.create_event_id_widget() self.create_goto_event_id_widget() self.create_telid_widget() self.create_channel_widget() self.create_dl1_widgets() self.update_dl1_widget_values() # Setup layout self.layout = layout([[self.viewer.layout], [ self.w_previous_event, self.w_next_event, self.w_goto_event_index, self.w_goto_event_id ], [self.w_event_index, self.w_event_id], [self.w_telid, self.w_channel], [self.wb_extractor]]) def start(self): self.event_index = 0 def finish(self): if not self.disable_server: def modify_doc(doc): doc.add_root(self.layout) doc.title = self.name directory = os.path.abspath(os.path.dirname(__file__)) theme_path = os.path.join(directory, "theme.yaml") template_path = os.path.join(directory, "templates") doc.theme = Theme(filename=theme_path) env = jinja2.Environment( loader=jinja2.FileSystemLoader(template_path)) doc.template = env.get_template('index.html') self.log.info('Opening Bokeh application on ' 'http://localhost:{}/'.format(self.port)) server = Server({'/': modify_doc}, num_procs=1, port=self.port) server.start() server.io_loop.add_callback(server.show, "/") server.io_loop.start() @property def event_index(self): return self._event_index @event_index.setter def event_index(self, val): try: self.event = self.seeker[val] except IndexError: self.log.warning("Event Index {} does not exist".format(val)) @property def event_id(self): return self._event_id @event_id.setter def event_id(self, val): try: self.event = self.seeker[str(val)] except IndexError: self.log.warning("Event ID {} does not exist".format(val)) @property def telid(self): return self._telid @telid.setter def telid(self, val): self.channel = 0 tels = list(self.event.r0.tels_with_data) if val not in tels: val = tels[0] self._telid = val self.viewer.telid = val self.update_telid_widget() @property def channel(self): return self._channel @channel.setter def channel(self, val): self._channel = val self.viewer.channel = val self.update_channel_widget() @property def event(self): return self._event @event.setter def event(self, val): # Calibrate self.r1.calibrate(val) self.dl0.reduce(val) self.dl1.calibrate(val) self._event = val self.viewer.event = val self._event_index = val.count self._event_id = val.r0.event_id self.update_event_index_widget() self.update_event_id_widget() self._telid = self.viewer.telid self.update_telid_widget() self._channel = self.viewer.channel self.update_channel_widget() def update_dl1_calibrator(self, extractor=None, cleaner=None): """ Recreate the dl1 calibrator with the specified extractor and cleaner Parameters ---------- extractor : ctapipe.image.charge_extractors.ChargeExtractor cleaner : ctapipe.image.waveform_cleaning.WaveformCleaner """ if extractor is None: extractor = self.dl1.extractor if cleaner is None: cleaner = self.dl1.cleaner self.extractor = extractor self.cleaner = cleaner kwargs = dict(config=self.config, tool=self) self.dl1 = CameraDL1Calibrator(extractor=self.extractor, cleaner=self.cleaner, **kwargs) self.dl1.calibrate(self.event) self.viewer.refresh() def create_next_event_widget(self): self.w_next_event = Button(label=">", button_type="default", width=50) self.w_next_event.on_click(self.on_next_event_widget_click) def on_next_event_widget_click(self): self.event_index += 1 def create_previous_event_widget(self): self.w_previous_event = Button(label="<", button_type="default", width=50) self.w_previous_event.on_click(self.on_previous_event_widget_click) def on_previous_event_widget_click(self): self.event_index -= 1 def create_event_index_widget(self): self.w_event_index = TextInput(title="Event Index:", value='') def update_event_index_widget(self): if self.w_event_index: self.w_event_index.value = str(self.event_index) def create_event_id_widget(self): self.w_event_id = TextInput(title="Event ID:", value='') def update_event_id_widget(self): if self.w_event_id: self.w_event_id.value = str(self.event_id) def create_goto_event_index_widget(self): self.w_goto_event_index = Button(label="GOTO Index", button_type="default", width=100) self.w_goto_event_index.on_click(self.on_goto_event_index_widget_click) def on_goto_event_index_widget_click(self): self.event_index = int(self.w_event_index.value) def create_goto_event_id_widget(self): self.w_goto_event_id = Button(label="GOTO ID", button_type="default", width=70) self.w_goto_event_id.on_click(self.on_goto_event_id_widget_click) def on_goto_event_id_widget_click(self): self.event_id = int(self.w_event_id.value) def create_telid_widget(self): self.w_telid = Select(title="Telescope:", value="", options=[]) self.w_telid.on_change('value', self.on_telid_widget_change) def update_telid_widget(self): if self.w_telid: tels = [str(t) for t in self.event.r0.tels_with_data] self.w_telid.options = tels self.w_telid.value = str(self.telid) def on_telid_widget_change(self, _, __, ___): if self.telid != int(self.w_telid.value): self.telid = int(self.w_telid.value) def create_channel_widget(self): self.w_channel = Select(title="Channel:", value="", options=[]) self.w_channel.on_change('value', self.on_channel_widget_change) def update_channel_widget(self): if self.w_channel: try: n_chan = self.event.r0.tel[self.telid].waveform.shape[0] except AttributeError: n_chan = 1 channels = [str(c) for c in range(n_chan)] self.w_channel.options = channels self.w_channel.value = str(self.channel) def on_channel_widget_change(self, _, __, ___): if self.channel != int(self.w_channel.value): self.channel = int(self.w_channel.value) def create_dl1_widgets(self): self.w_dl1_dict = dict( cleaner=Select(title="Cleaner:", value='', width=5, options=WaveformCleanerFactory.subclass_names), extractor=Select(title="Extractor:", value='', width=5, options=ChargeExtractorFactory.subclass_names), extractor_t0=TextInput(title="T0:", value=''), extractor_window_width=TextInput(title="Window Width:", value=''), extractor_window_shift=TextInput(title="Window Shift:", value=''), extractor_sig_amp_cut_HG=TextInput(title="Significant Amplitude " "Cut (HG):", value=''), extractor_sig_amp_cut_LG=TextInput(title="Significant Amplitude " "Cut (LG):", value=''), extractor_lwt=TextInput(title="Local Pixel Weight:", value='')) for val in self.w_dl1_dict.values(): val.on_change('value', self.on_dl1_widget_change) self.wb_extractor = widgetbox( PreText(text="Charge Extractor Configuration"), self.w_dl1_dict['cleaner'], self.w_dl1_dict['extractor'], self.w_dl1_dict['extractor_t0'], self.w_dl1_dict['extractor_window_width'], self.w_dl1_dict['extractor_window_shift'], self.w_dl1_dict['extractor_sig_amp_cut_HG'], self.w_dl1_dict['extractor_sig_amp_cut_LG'], self.w_dl1_dict['extractor_lwt']) def update_dl1_widget_values(self): if self.w_dl1_dict: for key, val in self.w_dl1_dict.items(): if 'extractor' in key: if key == 'extractor': val.value = self.extractor.__class__.__name__ else: key = key.replace("extractor_", "") try: val.value = str(getattr(self.extractor, key)) except AttributeError: val.value = '' elif 'cleaner' in key: if key == 'cleaner': val.value = self.cleaner.__class__.__name__ else: key = key.replace("cleaner_", "") try: val.value = str(getattr(self.cleaner, key)) except AttributeError: val.value = '' def on_dl1_widget_change(self, _, __, ___): if self.event: if not self._updating_dl1: self._updating_dl1 = True cmdline = [] for key, val in self.w_dl1_dict.items(): if val.value: cmdline.append('--{}'.format(key)) cmdline.append(val.value) self.parse_command_line(cmdline) kwargs = dict(config=self.config, tool=self) extractor = ChargeExtractorFactory.produce(**kwargs) cleaner = WaveformCleanerFactory.produce(**kwargs) self.update_dl1_calibrator(extractor, cleaner) self.update_dl1_widget_values() self._updating_dl1 = False
class BokehFileViewer(Tool): name = "BokehFileViewer" description = ("Interactively explore an event file using the bokeh " "visualisation package") port = Int(5006, help="Port to open bokeh server onto").tag(config=True) disable_server = Bool(False, help="Do not start the bokeh server " "(useful for testing)").tag(config=True) aliases = Dict(dict( port='BokehFileViewer.port', disable_server='BokehFileViewer.disable_server', r='EventSourceFactory.product', f='EventSourceFactory.input_url', max_events='EventSourceFactory.max_events', ped='CameraR1CalibratorFactory.pedestal_path', tf='CameraR1CalibratorFactory.tf_path', pe='CameraR1CalibratorFactory.pe_path', ff='CameraR1CalibratorFactory.ff_path', extractor='ChargeExtractorFactory.product', extractor_t0='ChargeExtractorFactory.t0', extractor_window_width='ChargeExtractorFactory.window_width', extractor_window_shift='ChargeExtractorFactory.window_shift', extractor_sig_amp_cut_HG='ChargeExtractorFactory.sig_amp_cut_HG', extractor_sig_amp_cut_LG='ChargeExtractorFactory.sig_amp_cut_LG', extractor_lwt='ChargeExtractorFactory.lwt', cleaner='WaveformCleanerFactory.product', )) classes = List([ EventSourceFactory, ChargeExtractorFactory, CameraR1CalibratorFactory, CameraDL1Calibrator, WaveformCleanerFactory ]) def __init__(self, **kwargs): super().__init__(**kwargs) self._event = None self._event_index = None self._event_id = None self._telid = None self._channel = None self.w_next_event = None self.w_previous_event = None self.w_event_index = None self.w_event_id = None self.w_goto_event_index = None self.w_goto_event_id = None self.w_telid = None self.w_channel = None self.w_dl1_dict = None self.wb_extractor = None self.layout = None self.reader = None self.seeker = None self.extractor = None self.cleaner = None self.r1 = None self.dl0 = None self.dl1 = None self.viewer = None self._updating_dl1 = False def setup(self): self.log_format = "%(levelname)s: %(message)s [%(name)s.%(funcName)s]" kwargs = dict(config=self.config, tool=self) default_url = get_dataset_path("gamma_test.simtel.gz") EventSourceFactory.input_url.default_value = default_url self.reader = EventSourceFactory.produce(**kwargs) self.seeker = EventSeeker(self.reader, **kwargs) self.extractor = ChargeExtractorFactory.produce(**kwargs) self.cleaner = WaveformCleanerFactory.produce(**kwargs) self.r1 = CameraR1CalibratorFactory.produce( eventsource=self.reader, **kwargs ) self.dl0 = CameraDL0Reducer(**kwargs) self.dl1 = CameraDL1Calibrator( extractor=self.extractor, cleaner=self.cleaner, **kwargs ) self.viewer = BokehEventViewer(**kwargs) # Setup widgets self.viewer.create() self.viewer.enable_automatic_index_increment() self.create_previous_event_widget() self.create_next_event_widget() self.create_event_index_widget() self.create_goto_event_index_widget() self.create_event_id_widget() self.create_goto_event_id_widget() self.create_telid_widget() self.create_channel_widget() self.create_dl1_widgets() self.update_dl1_widget_values() # Setup layout self.layout = layout([ [self.viewer.layout], [ self.w_previous_event, self.w_next_event, self.w_goto_event_index, self.w_goto_event_id ], [self.w_event_index, self.w_event_id], [self.w_telid, self.w_channel], [self.wb_extractor] ]) def start(self): self.event_index = 0 def finish(self): if not self.disable_server: def modify_doc(doc): doc.add_root(self.layout) doc.title = self.name directory = os.path.abspath(os.path.dirname(__file__)) theme_path = os.path.join(directory, "theme.yaml") template_path = os.path.join(directory, "templates") doc.theme = Theme(filename=theme_path) env = jinja2.Environment( loader=jinja2.FileSystemLoader(template_path) ) doc.template = env.get_template('index.html') self.log.info('Opening Bokeh application on ' 'http://localhost:{}/'.format(self.port)) server = Server({'/': modify_doc}, num_procs=1, port=self.port) server.start() server.io_loop.add_callback(server.show, "/") server.io_loop.start() @property def event_index(self): return self._event_index @event_index.setter def event_index(self, val): try: self.event = self.seeker[val] except IndexError: self.log.warning("Event Index {} does not exist".format(val)) @property def event_id(self): return self._event_id @event_id.setter def event_id(self, val): try: self.event = self.seeker[str(val)] except IndexError: self.log.warning("Event ID {} does not exist".format(val)) @property def telid(self): return self._telid @telid.setter def telid(self, val): self.channel = 0 tels = list(self.event.r0.tels_with_data) if val not in tels: val = tels[0] self._telid = val self.viewer.telid = val self.update_telid_widget() @property def channel(self): return self._channel @channel.setter def channel(self, val): self._channel = val self.viewer.channel = val self.update_channel_widget() @property def event(self): return self._event @event.setter def event(self, val): # Calibrate self.r1.calibrate(val) self.dl0.reduce(val) self.dl1.calibrate(val) self._event = val self.viewer.event = val self._event_index = val.count self._event_id = val.r0.event_id self.update_event_index_widget() self.update_event_id_widget() self._telid = self.viewer.telid self.update_telid_widget() self._channel = self.viewer.channel self.update_channel_widget() def update_dl1_calibrator(self, extractor=None, cleaner=None): """ Recreate the dl1 calibrator with the specified extractor and cleaner Parameters ---------- extractor : ctapipe.image.charge_extractors.ChargeExtractor cleaner : ctapipe.image.waveform_cleaning.WaveformCleaner """ if extractor is None: extractor = self.dl1.extractor if cleaner is None: cleaner = self.dl1.cleaner self.extractor = extractor self.cleaner = cleaner kwargs = dict(config=self.config, tool=self) self.dl1 = CameraDL1Calibrator( extractor=self.extractor, cleaner=self.cleaner, **kwargs ) self.dl1.calibrate(self.event) self.viewer.refresh() def create_next_event_widget(self): self.w_next_event = Button(label=">", button_type="default", width=50) self.w_next_event.on_click(self.on_next_event_widget_click) def on_next_event_widget_click(self): self.event_index += 1 def create_previous_event_widget(self): self.w_previous_event = Button( label="<", button_type="default", width=50 ) self.w_previous_event.on_click(self.on_previous_event_widget_click) def on_previous_event_widget_click(self): self.event_index -= 1 def create_event_index_widget(self): self.w_event_index = TextInput(title="Event Index:", value='') def update_event_index_widget(self): if self.w_event_index: self.w_event_index.value = str(self.event_index) def create_event_id_widget(self): self.w_event_id = TextInput(title="Event ID:", value='') def update_event_id_widget(self): if self.w_event_id: self.w_event_id.value = str(self.event_id) def create_goto_event_index_widget(self): self.w_goto_event_index = Button( label="GOTO Index", button_type="default", width=100 ) self.w_goto_event_index.on_click(self.on_goto_event_index_widget_click) def on_goto_event_index_widget_click(self): self.event_index = int(self.w_event_index.value) def create_goto_event_id_widget(self): self.w_goto_event_id = Button( label="GOTO ID", button_type="default", width=70 ) self.w_goto_event_id.on_click(self.on_goto_event_id_widget_click) def on_goto_event_id_widget_click(self): self.event_id = int(self.w_event_id.value) def create_telid_widget(self): self.w_telid = Select(title="Telescope:", value="", options=[]) self.w_telid.on_change('value', self.on_telid_widget_change) def update_telid_widget(self): if self.w_telid: tels = [str(t) for t in self.event.r0.tels_with_data] self.w_telid.options = tels self.w_telid.value = str(self.telid) def on_telid_widget_change(self, _, __, ___): if self.telid != int(self.w_telid.value): self.telid = int(self.w_telid.value) def create_channel_widget(self): self.w_channel = Select(title="Channel:", value="", options=[]) self.w_channel.on_change('value', self.on_channel_widget_change) def update_channel_widget(self): if self.w_channel: try: n_chan = self.event.r0.tel[self.telid].waveform.shape[0] except AttributeError: n_chan = 1 channels = [str(c) for c in range(n_chan)] self.w_channel.options = channels self.w_channel.value = str(self.channel) def on_channel_widget_change(self, _, __, ___): if self.channel != int(self.w_channel.value): self.channel = int(self.w_channel.value) def create_dl1_widgets(self): self.w_dl1_dict = dict( cleaner=Select(title="Cleaner:", value='', width=5, options=WaveformCleanerFactory.subclass_names), extractor=Select(title="Extractor:", value='', width=5, options=ChargeExtractorFactory.subclass_names), extractor_t0=TextInput(title="T0:", value=''), extractor_window_width=TextInput(title="Window Width:", value=''), extractor_window_shift=TextInput(title="Window Shift:", value=''), extractor_sig_amp_cut_HG=TextInput(title="Significant Amplitude " "Cut (HG):", value=''), extractor_sig_amp_cut_LG=TextInput(title="Significant Amplitude " "Cut (LG):", value=''), extractor_lwt=TextInput(title="Local Pixel Weight:", value='')) for val in self.w_dl1_dict.values(): val.on_change('value', self.on_dl1_widget_change) self.wb_extractor = widgetbox( PreText(text="Charge Extractor Configuration"), self.w_dl1_dict['cleaner'], self.w_dl1_dict['extractor'], self.w_dl1_dict['extractor_t0'], self.w_dl1_dict['extractor_window_width'], self.w_dl1_dict['extractor_window_shift'], self.w_dl1_dict['extractor_sig_amp_cut_HG'], self.w_dl1_dict['extractor_sig_amp_cut_LG'], self.w_dl1_dict['extractor_lwt']) def update_dl1_widget_values(self): if self.w_dl1_dict: for key, val in self.w_dl1_dict.items(): if 'extractor' in key: if key == 'extractor': val.value = self.extractor.__class__.__name__ else: key = key.replace("extractor_", "") try: val.value = str(getattr(self.extractor, key)) except AttributeError: val.value = '' elif 'cleaner' in key: if key == 'cleaner': val.value = self.cleaner.__class__.__name__ else: key = key.replace("cleaner_", "") try: val.value = str(getattr(self.cleaner, key)) except AttributeError: val.value = '' def on_dl1_widget_change(self, _, __, ___): if self.event: if not self._updating_dl1: self._updating_dl1 = True cmdline = [] for key, val in self.w_dl1_dict.items(): if val.value: cmdline.append('--{}'.format(key)) cmdline.append(val.value) self.parse_command_line(cmdline) kwargs = dict(config=self.config, tool=self) extractor = ChargeExtractorFactory.produce(**kwargs) cleaner = WaveformCleanerFactory.produce(**kwargs) self.update_dl1_calibrator(extractor, cleaner) self.update_dl1_widget_values() self._updating_dl1 = False
] data_table = DataTable(source=source, columns=columns, width=300, height=600) def toggle_callback(attr): if tide_toggle.active: # Checked *after* press tide_toggle.label = "Disable Tides" else: tide_toggle.label = "Enable Tides" tide_toggle = Toggle(label="Enable Tides", callback=toggle_ocean) tide_toggle.on_click(toggle_callback) download_button = Button(label="Download data", callback=download_data) go_button = Button(label="Run model")#, callback=check_fish) go_button.on_click(update_plots) # Set up app layout prods = VBox(gas_exchange_slider, productivity_slider) river = VBox(river_flow_slider, river_N_slider) tide_run = HBox(tide_toggle, download_button, go_button) all_settings = VBox(prods, river, tide_run, width=400) # Add to current document curdoc().add_root(HBox(children=[all_settings, plots]))
ticker1.on_change('value', ticker1_change) ticker2.on_change('value', ticker2_change) def selection_change(attrname, old, new): t1, t2 = ticker1.value, ticker2.value data = get_data(t1, t2) selected = source.selected.indices if selected: data = data.iloc[selected, :] update_stats(data, t1, t2) source.selected.on_change('indices', selection_change) button = Button(label="Download", button_type="success") button.js_on_click( CustomJS(args=dict(source=source), code=open(join(dirname(__file__), "download.js")).read())) columns = [ TableColumn(field="t1", title="t1"), TableColumn(field="t2", title="t2"), TableColumn(field="t1_returns", title="t1_returns"), TableColumn(field="t2_returns", title="t2_returns") ] data_table = DataTable(source=source, columns=columns, width=900, auto_edit=True, editable=True)
# seasonal attenuation amplitude saa = Slider(title=SAA_LABEL, value=SAA_START, start=SAA_MIN, end=SAA_MAX, step=SAA_STEP) # baseline attenuation bat = Slider(title=BAT_LABEL, value=BAT_START, start=BAT_MIN, end=BAT_MAX, step=BAT_STEP) button = Button(label="Reset", button_type="default") button2 = Button(label="Vaccinate critical proportion", button_type="default") button3 = Button(label="Vaccinate 50%", button_type="default") # text widgets intro = Div(text='', width=TEXT_WIDTH) summary = Div(text='', width=TEXT_WIDTH) stats = Div(text='', width=TEXT_WIDTH) notes = Div(text='', width=TEXT_WIDTH) # Assign widgets to the call back function # updates are on value_throtled because this is too slow for realtime updates for w in [ population, iinfections, period, period_stdev, latent, h1, p1, drate, im, ddy, saa, bat ]:
class TimeSeries: def __init__(self, sources, range_categories, custom_title, data_tables): self.sources = sources self.range_categories = range_categories self.current_dvh_group = {n: [] for n in GROUP_LABELS} # Control Chart layout (Time-Series) tools = "pan,wheel_zoom,box_zoom,lasso_select,poly_select,reset,crosshair,save" self.plot = figure(plot_width=1050, plot_height=400, tools=tools, logo=None, active_drag="box_zoom", x_axis_type='datetime') self.plot.xaxis.axis_label_text_font_size = options.PLOT_AXIS_LABEL_FONT_SIZE self.plot.yaxis.axis_label_text_font_size = options.PLOT_AXIS_LABEL_FONT_SIZE self.plot.xaxis.major_label_text_font_size = options.PLOT_AXIS_MAJOR_LABEL_FONT_SIZE self.plot.yaxis.major_label_text_font_size = options.PLOT_AXIS_MAJOR_LABEL_FONT_SIZE # plot.min_border_left = min_border self.plot.min_border_bottom = options.MIN_BORDER self.plot_data_1 = self.plot.circle('x', 'y', size=options.TIME_SERIES_1_CIRCLE_SIZE, color=options.GROUP_1_COLOR, alpha=options.TIME_SERIES_1_CIRCLE_ALPHA, source=sources.time_1) self.plot_data_2 = self.plot.circle('x', 'y', size=options.TIME_SERIES_2_CIRCLE_SIZE, color=options.GROUP_2_COLOR, alpha=options.TIME_SERIES_2_CIRCLE_ALPHA, source=sources.time_2) self.plot_trend_1 = self.plot.line('x', 'y', color=options.GROUP_1_COLOR, source=sources.time_trend_1, line_width=options.TIME_SERIES_1_TREND_LINE_WIDTH, line_dash=options.TIME_SERIES_1_TREND_LINE_DASH) self.plot_trend_2 = self.plot.line('x', 'y', color=options.GROUP_2_COLOR, source=sources.time_trend_2, line_width=options.TIME_SERIES_2_TREND_LINE_WIDTH, line_dash=options.TIME_SERIES_2_TREND_LINE_DASH) self.plot_avg_1 = self.plot.line('x', 'avg', color=options.GROUP_1_COLOR, source=sources.time_bound_1, line_width=options.TIME_SERIES_1_AVG_LINE_WIDTH, line_dash=options.TIME_SERIES_1_AVG_LINE_DASH) self.plot_avg_2 = self.plot.line('x', 'avg', color=options.GROUP_2_COLOR, source=sources.time_bound_2, line_width=options.TIME_SERIES_2_AVG_LINE_WIDTH, line_dash=options.TIME_SERIES_2_AVG_LINE_DASH) self.plot_patch_1 = self.plot.patch('x', 'y', color=options.GROUP_1_COLOR, source=sources.time_patch_1, alpha=options.TIME_SERIES_1_PATCH_ALPHA) self.plot_patch_2 = self.plot.patch('x', 'y', color=options.GROUP_2_COLOR, source=sources.time_patch_2, alpha=options.TIME_SERIES_1_PATCH_ALPHA) self.plot.add_tools(HoverTool(show_arrow=True, tooltips=[('ID', '@mrn'), ('Date', '@x{%F}'), ('Value', '@y{0.2f}')], formatters={'x': 'datetime'})) self.plot.xaxis.axis_label = "Simulation Date" self.plot.yaxis.axis_label = "" # Set the legend legend_plot = Legend(items=[("Group 1", [self.plot_data_1]), ("Series Average", [self.plot_avg_1]), ("Rolling Average", [self.plot_trend_1]), ("Percentile Region", [self.plot_patch_1]), ("Group 2", [self.plot_data_2]), ("Series Average", [self.plot_avg_2]), ("Rolling Average", [self.plot_trend_2]), ("Percentile Region", [self.plot_patch_2])], location=(25, 0)) # Add the layout outside the plot, clicking legend item hides the line self.plot.add_layout(legend_plot, 'right') self.plot.legend.click_policy = "hide" plot_options = list(range_categories) plot_options.sort() plot_options.insert(0, '') self.y_axis = Select(value=plot_options[0], options=plot_options, width=300) self.y_axis.title = "Select a Range Variable" self.y_axis.on_change('value', self.update_y_axis_ticker) self.look_back_distance = TextInput(value='1', title="Lookback Distance", width=200) self.look_back_distance.on_change('value', self.update_plot_trend_ticker) self.plot_percentile = TextInput(value='90', title="Percentile", width=200) self.plot_percentile.on_change('value', self.update_plot_trend_ticker) look_back_units_options = ['Dates with a Sim', 'Days'] self.look_back_units = Select(value=look_back_units_options[0], options=look_back_units_options, width=200) self.look_back_units.title = 'Lookback Units' self.look_back_units.on_change('value', self.update_plot_ticker) # source_time.on_change('selected', plot_update_trend) self.trend_update_button = Button(label="Update Trend", button_type="primary", width=150) self.trend_update_button.on_click(self.plot_update_trend) self.download_time_plot = Button(label="Download Plot Data", button_type="default", width=150) self.download_time_plot.callback = CustomJS(args=dict(source_1=sources.time_1, source_2=sources.time_2), code=open(join(dirname(__file__), "download_time_plot.js")).read()) # histograms tools = "pan,wheel_zoom,box_zoom,reset,crosshair,save" self.histograms = figure(plot_width=1050, plot_height=400, tools=tools, logo=None, active_drag="box_zoom") self.histograms.xaxis.axis_label_text_font_size = options.PLOT_AXIS_LABEL_FONT_SIZE self.histograms.yaxis.axis_label_text_font_size = options.PLOT_AXIS_LABEL_FONT_SIZE self.histograms.xaxis.major_label_text_font_size = options.PLOT_AXIS_MAJOR_LABEL_FONT_SIZE self.histograms.yaxis.major_label_text_font_size = options.PLOT_AXIS_MAJOR_LABEL_FONT_SIZE self.histograms.min_border_left = options.MIN_BORDER self.histograms.min_border_bottom = options.MIN_BORDER self.hist_1 = self.histograms.vbar(x='x', width='width', bottom=0, top='top', source=sources.histogram_1, color=options.GROUP_1_COLOR, alpha=options.HISTOGRAM_1_ALPHA) self.hist_2 = self.histograms.vbar(x='x', width='width', bottom=0, top='top', source=sources.histogram_2, color=options.GROUP_2_COLOR, alpha=options.HISTOGRAM_2_ALPHA) self.histograms.xaxis.axis_label = "" self.histograms.yaxis.axis_label = "Frequency" self.histogram_bin_slider = Slider(start=1, end=100, value=10, step=1, title="Number of Bins") self.histogram_bin_slider.on_change('value', self.histograms_ticker) self.histogram_radio_group = RadioGroup(labels=["Absolute Y-Axis", "Relative Y-Axis (to Group Max)"], active=0) self.histogram_radio_group.on_change('active', self.histograms_ticker) self.histogram_normaltest_1_text = Div(text="Group 1 Normal Test p-value = ", width=400) self.histogram_normaltest_2_text = Div(text="Group 2 Normal Test p-value = ", width=400) self.histogram_ttest_text = Div(text="Two Sample t-Test (Group 1 vs 2) p-value = ", width=400) self.histogram_ranksums_text = Div(text="Wilcoxon rank-sum (Group 1 vs 2) p-value = ", width=400) self.histograms.add_tools(HoverTool(show_arrow=True, line_policy='next', tooltips=[('x', '@x{0.2f}'), ('Counts', '@top')])) # Set the legend legend_hist = Legend(items=[("Group 1", [self.hist_1]), ("Group 2", [self.hist_2])], location=(25, 0)) # Add the layout outside the plot, clicking legend item hides the line self.histograms.add_layout(legend_hist, 'right') self.histograms.legend.click_policy = "hide" self.layout = column(Div(text="<b>DVH Analytics v%s</b>" % options.VERSION), row(custom_title['1']['time_series'], Spacer(width=50), custom_title['2']['time_series']), row(self.y_axis, self.look_back_units, self.look_back_distance, Spacer(width=10), self.plot_percentile, Spacer(width=10), self.trend_update_button), self.plot, self.download_time_plot, Div(text="<hr>", width=1050), row(self.histogram_bin_slider, self.histogram_radio_group), row(self.histogram_normaltest_1_text, self.histogram_ttest_text), row(self.histogram_normaltest_2_text, self.histogram_ranksums_text), self.histograms, Spacer(width=1000, height=10)) def update_current_dvh_group(self, data): self.current_dvh_group = data def update_plot_ticker(self, attr, old, new): self.update_plot() def update_y_axis_ticker(self, attr, old, new): self.update_plot() def update_plot_trend_ticker(self, attr, old, new): self.plot_update_trend() def histograms_ticker(self, attr, old, new): self.update_histograms() def update_plot(self): new = str(self.y_axis.value) if new: clear_source_selection(self.sources, 'time_1') clear_source_selection(self.sources, 'time_2') if new.startswith('DVH Endpoint: '): y_var_name = new.split(': ')[1] y_source_values = self.sources.endpoint_calcs.data[y_var_name] y_source_uids = self.sources.endpoint_calcs.data['uid'] y_source_mrns = self.sources.endpoint_calcs.data['mrn'] elif new == 'EUD': y_source_values = self.sources.rad_bio.data['eud'] y_source_uids = self.sources.rad_bio.data['uid'] y_source_mrns = self.sources.rad_bio.data['mrn'] elif new == 'NTCP/TCP': y_source_values = self.sources.rad_bio.data['ntcp_tcp'] y_source_uids = self.sources.rad_bio.data['uid'] y_source_mrns = self.sources.rad_bio.data['mrn'] else: y_source = self.range_categories[new]['source'] y_var_name = self.range_categories[new]['var_name'] y_source_values = y_source.data[y_var_name] y_source_uids = y_source.data['uid'] y_source_mrns = y_source.data['mrn'] self.update_y_axis_label() sim_study_dates = self.sources.plans.data['sim_study_date'] sim_study_dates_uids = self.sources.plans.data['uid'] x_values = [] skipped = [] colors = [] for v in range(len(y_source_values)): uid = y_source_uids[v] try: sim_study_dates_index = sim_study_dates_uids.index(uid) current_date_str = sim_study_dates[sim_study_dates_index] if current_date_str == 'None': current_date = datetime.now() else: current_date = datetime(int(current_date_str[0:4]), int(current_date_str[5:7]), int(current_date_str[8:10])) x_values.append(current_date) skipped.append(False) except: skipped.append(True) # Get group color if not skipped[-1]: if new.startswith('DVH Endpoint') or new in {'EUD', 'NTCP/TCP'} \ or self.range_categories[new]['source'] == self.sources.dvhs: if new in {'EUD', 'NTCP/TCP'}: roi = self.sources.rad_bio.data['roi_name'][v] else: roi = self.sources.dvhs.data['roi_name'][v] found = {'Group 1': False, 'Group 2': False} color = None if self.current_dvh_group['1']: r1, r1_max = 0, len(self.current_dvh_group['1'].study_instance_uid) while r1 < r1_max and not found['Group 1']: if self.current_dvh_group['1'].study_instance_uid[r1] == uid and \ self.current_dvh_group['1'].roi_name[r1] == roi: found['Group 1'] = True color = options.GROUP_1_COLOR r1 += 1 if self.current_dvh_group['2']: r2, r2_max = 0, len(self.current_dvh_group['2'].study_instance_uid) while r2 < r2_max and not found['Group 2']: if self.current_dvh_group['2'].study_instance_uid[r2] == uid and \ self.current_dvh_group['2'].roi_name[r2] == roi: found['Group 2'] = True if found['Group 1']: color = options.GROUP_1_and_2_COLOR else: color = options.GROUP_2_COLOR r2 += 1 colors.append(color) else: if self.current_dvh_group['1'] and self.current_dvh_group['2']: if uid in self.current_dvh_group['1'].study_instance_uid and \ uid in self.current_dvh_group['2'].study_instance_uid: colors.append(options.GROUP_1_and_2_COLOR) elif uid in self.current_dvh_group['1'].study_instance_uid: colors.append(options.GROUP_1_COLOR) else: colors.append(options.GROUP_2_COLOR) elif self.current_dvh_group['1']: colors.append(options.GROUP_1_COLOR) else: colors.append(options.GROUP_2_COLOR) y_values = [] y_mrns = [] for v in range(len(y_source_values)): if not skipped[v]: y_values.append(y_source_values[v]) y_mrns.append(y_source_mrns[v]) if not isinstance(y_values[-1], (int, long, float)): y_values[-1] = 0 sort_index = sorted(range(len(x_values)), key=lambda k: x_values[k]) x_values_sorted, y_values_sorted, y_mrns_sorted, colors_sorted = [], [], [], [] for s in range(len(x_values)): x_values_sorted.append(x_values[sort_index[s]]) y_values_sorted.append(y_values[sort_index[s]]) y_mrns_sorted.append(y_mrns[sort_index[s]]) colors_sorted.append(colors[sort_index[s]]) source_time_1_data = {'x': [], 'y': [], 'mrn': [], 'date_str': []} source_time_2_data = {'x': [], 'y': [], 'mrn': [], 'date_str': []} for i in range(len(x_values_sorted)): if colors_sorted[i] in {options.GROUP_1_COLOR, options.GROUP_1_and_2_COLOR}: source_time_1_data['x'].append(x_values_sorted[i]) source_time_1_data['y'].append(y_values_sorted[i]) source_time_1_data['mrn'].append(y_mrns_sorted[i]) source_time_1_data['date_str'].append(x_values_sorted[i].strftime("%Y-%m-%d")) if colors_sorted[i] in {options.GROUP_2_COLOR, options.GROUP_1_and_2_COLOR}: source_time_2_data['x'].append(x_values_sorted[i]) source_time_2_data['y'].append(y_values_sorted[i]) source_time_2_data['mrn'].append(y_mrns_sorted[i]) source_time_2_data['date_str'].append(x_values_sorted[i].strftime("%Y-%m-%d")) self.sources.time_1.data = source_time_1_data self.sources.time_2.data = source_time_2_data else: clear_source_data(self.sources, 'time_1') clear_source_data(self.sources, 'time_2') self.plot_update_trend() def plot_update_trend(self): if self.y_axis.value: selected_indices = {n: getattr(self.sources, 'time_%s' % n).selected.indices for n in GROUP_LABELS} for n in GROUP_LABELS: if not selected_indices[n]: selected_indices[n] = range(len(getattr(self.sources, 'time_%s' % n).data['x'])) group = {n: {'x': [], 'y': []} for n in GROUP_LABELS} for n in GROUP_LABELS: for i in range(len(getattr(self.sources, 'time_%s' % n).data['x'])): if i in selected_indices[n]: for v in ['x', 'y']: group[n][v].append(getattr(self.sources, 'time_%s' % n).data[v][i]) try: avg_len = int(self.look_back_distance.value) except: avg_len = 1 try: percentile = float(self.plot_percentile.value) except: percentile = 90. # average daily data and keep track of points per day, calculate moving average group_collapsed = {n: [] for n in GROUP_LABELS} for n in GROUP_LABELS: if group[n]['x']: group_collapsed[n] = collapse_into_single_dates(group[n]['x'], group[n]['y']) if self.look_back_units.value == "Dates with a Sim": x_trend, moving_avgs = moving_avg(group_collapsed[n], avg_len) else: x_trend, moving_avgs = moving_avg_by_calendar_day(group_collapsed[n], avg_len) y_np = np.array(group[n]['y']) upper_bound = float(np.percentile(y_np, 50. + percentile / 2.)) average = float(np.percentile(y_np, 50)) lower_bound = float(np.percentile(y_np, 50. - percentile / 2.)) getattr(self.sources, 'time_trend_%s' % n).data = {'x': x_trend, 'y': moving_avgs, 'mrn': ['Avg'] * len(x_trend)} getattr(self.sources, 'time_bound_%s' % n).data = {'x': group[n]['x'], 'mrn': ['Bound'] * len(group[n]['x']), 'upper': [upper_bound] * len(group[n]['x']), 'avg': [average] * len(group[n]['x']), 'lower': [lower_bound] * len(group[n]['x'])} getattr(self.sources, 'time_patch_%s' % n).data = {'x': [group[n]['x'][0], group[n]['x'][-1], group[n]['x'][-1], group[n]['x'][0]], 'y': [upper_bound, upper_bound, lower_bound, lower_bound]} else: for v in ['trend', 'bound', 'patch']: clear_source_data(self.sources, 'time_%s_%s' % (v, n)) x_var = str(self.y_axis.value) if x_var.startswith('DVH Endpoint'): self.histograms.xaxis.axis_label = x_var.split("DVH Endpoint: ")[1] elif x_var == 'EUD': self.histograms.xaxis.axis_label = "%s (Gy)" % x_var elif x_var == 'NTCP/TCP': self.histograms.xaxis.axis_label = "NTCP or TCP" else: if self.range_categories[x_var]['units']: self.histograms.xaxis.axis_label = "%s (%s)" % (x_var, self.range_categories[x_var]['units']) else: self.histograms.xaxis.axis_label = x_var # Normal Test s, p = {n: '' for n in GROUP_LABELS}, {n: '' for n in GROUP_LABELS} for n in GROUP_LABELS: if group[n]['y']: s[n], p[n] = normaltest(group[n]['y']) p[n] = "%0.3f" % p[n] # t-Test and Rank Sums pt, pr = '', '' if group['1']['y'] and group['2']['y']: st, pt = ttest_ind(group['1']['y'], group['2']['y']) sr, pr = ranksums(group['1']['y'], group['2']['y']) pt = "%0.3f" % pt pr = "%0.3f" % pr self.histogram_normaltest_1_text.text = "Group 1 Normal Test p-value = %s" % p['1'] self.histogram_normaltest_2_text.text = "Group 2 Normal Test p-value = %s" % p['2'] self.histogram_ttest_text.text = "Two Sample t-Test (Group 1 vs 2) p-value = %s" % pt self.histogram_ranksums_text.text = "Wilcoxon rank-sum (Group 1 vs 2) p-value = %s" % pr else: for n in GROUP_LABELS: for k in ['trend', 'bound', 'patch']: clear_source_data(self.sources, "time_%s_%s" % (k, n)) self.histogram_normaltest_1_text.text = "Group 1 Normal Test p-value = " self.histogram_normaltest_2_text.text = "Group 2 Normal Test p-value = " self.histogram_ttest_text.text = "Two Sample t-Test (Group 1 vs 2) p-value = " self.histogram_ranksums_text.text = "Wilcoxon rank-sum (Group 1 vs 2) p-value = " self.update_histograms() def update_histograms(self): if self.y_axis.value != '': # Update Histograms bin_size = int(self.histogram_bin_slider.value) width_fraction = 0.9 for n in GROUP_LABELS: hist, bins = np.histogram(getattr(self.sources, 'time_%s' % n).data['y'], bins=bin_size) if self.histogram_radio_group.active == 1: hist = np.divide(hist, np.float(np.max(hist))) self.histograms.yaxis.axis_label = "Relative Frequency" else: self.histograms.yaxis.axis_label = "Frequency" width = [width_fraction * (bins[1] - bins[0])] * bin_size center = (bins[:-1] + bins[1:]) / 2. getattr(self.sources, 'histogram_%s' % n).data = {'x': center, 'top': hist, 'width': width} else: for n in GROUP_LABELS: clear_source_data(self.sources, 'histogram_%s' % n) def update_y_axis_label(self): new = str(self.y_axis.value) if new: # If new has something in parenthesis, extract and put in front new_split = new.split(' (') if len(new_split) > 1: new_display = "%s %s" % (new_split[1].split(')')[0], new_split[0]) else: new_display = new if new.startswith('DVH Endpoint'): self.plot.yaxis.axis_label = str(self.y_axis.value).split(': ')[1] elif new == 'EUD': self.plot.yaxis.axis_label = 'EUD (Gy)' elif new == 'NTCP/TCP': self.plot.yaxis.axis_label = 'NTCP or TCP' elif self.range_categories[new]['units']: self.plot.yaxis.axis_label = "%s (%s)" % (new_display, self.range_categories[new]['units']) else: self.plot.yaxis.axis_label = new_display def update_options(self): new_options = list(self.range_categories) new_options.extend(['EUD', 'NTCP/TCP']) for ep in self.sources.endpoint_calcs.data: if ep.startswith('V_') or ep.startswith('D_'): new_options.append("DVH Endpoint: %s" % ep) new_options.sort() new_options.insert(0, '') self.y_axis.options = new_options self.y_axis.value = ''
def KPI_developer_adoption_tab(page_width,DAYS_TO_LOAD=90): class Thistab(KPI): def __init__(self, table,cols=[]): KPI.__init__(self, table,name='developer',cols=cols) self.table = table self.df = None self.checkboxgroup = {} self.period_to_date_cards = { 'year': self.card('',''), 'quarter': self.card('', ''), 'month': self.card('', ''), 'week': self.card('', '') } self.ptd_startdate = datetime(datetime.today().year,1,1,0,0,0) self.timestamp_col = 'block_timestamp' self.variable = self.menus['developer_adoption_DVs'][0] self.datepicker_pop_start = DatePicker( title="Period start", min_date=self.initial_date, max_date=dashboard_config['dates']['last_date'], value=dashboard_config['dates']['last_date']) # ------- DIVS setup begin self.page_width = page_width self.KPI_card_div = self.initialize_cards(width=self.page_width,height=1000) txt = """<hr/><div style="text-align:center;width:{}px;height:{}px; position:relative;background:black;margin-bottom:200px"> <h1 style="color:#fff;margin-bottom:300px">{}</h1> </div>""".format(self.page_width, 50, 'Welcome') self.notification_div = { 'top': Div(text=txt, width=self.page_width, height=20), 'bottom': Div(text=txt, width=self.page_width, height=10), } self.section_divider = '-----------------------------------' self.section_headers = { 'cards': self.section_header_div( text='Period to date:{}'.format(self.section_divider), width=int(self.page_width*.5), html_header='h2', margin_top=5,margin_bottom=-155), 'pop': self.section_header_div( text='Period over period:{}'.format(self.section_divider), width=int(self.page_width*.5), html_header='h2', margin_top=5, margin_bottom=-155), 'sig_ratio': self.section_header_div( text='Time series of ratio of DV to significant IVs'.format(self.section_divider), width=int(self.page_width*.5), html_header='h2', margin_top=5, margin_bottom=-155), } # ---------------------- DIVS ---------------------------- def section_header_div(self, text, html_header='h2', width=600, margin_top=150, margin_bottom=-150): text = """<div style="margin-top:{}px;margin-bottom:-{}px;"><{} style="color:#4221cc;">{}</{}></div>""" \ .format(margin_top, margin_bottom, html_header, text, html_header) return Div(text=text, width=width, height=15) def information_div(self, width=400, height=300): div_style = """ style='width:350px;margin-right:-800px; border:1px solid #ddd;border-radius:3px;background:#efefef50;' """ txt = """ <div {}> <h4 {}>How to interpret relationships </h4> <ul style='margin-top:-10px;'> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> </ul> </div> """.format(div_style, self.header_style) div = Div(text=txt, width=width, height=height) return div # -------------------- CARDS ----------------------------------------- def initialize_cards(self, width, height=250): try: txt = '' for idx,period in enumerate(['year', 'quarter', 'month', 'week']): design = random.choice(list(KPI_card_css.keys())) txt += self.card(title='', data='', card_design=design) text = """<div style="margin-top:100px;display:flex;flex-direction:column;"> {} </div>""".format(txt) div = Div(text=text, width=width, height=height) return div except Exception: logger.error('initialize cards', exc_info=True) # -------------------- GRAPHS ------------------------------------------- def graph_periods_to_date(self,df1,timestamp_filter_col,variable): try: dct = {} for idx,period in enumerate(['week','month','quarter','year']): all_txt = """<div style="width:{}px;display:flex;flex-direction:row;">"""\ .format(int(self.page_width*.6)) # go to next row df = self.period_to_date(df1, timestamp=dashboard_config['dates']['last_date'], timestamp_filter_col=timestamp_filter_col, period=period) # get unique instances df = df.compute() df = df.drop_duplicates(keep='first') count = len(df) gc.collect() denom = df[variable].sum() if denom != 0: payroll_to_date = self.payroll_to_date(period) cost_per_var = round(payroll_to_date/denom,2) tmp_var = self.variable.split('_') title = "{} to date".format(period) title += "</br>${} per {}".format(cost_per_var,tmp_var[-1]) else: title = "{} to date".format(period) design = random.choice(list(KPI_card_css.keys())) all_txt += self.card(title=title,data=count,card_design=design) # add the statistically significant point estimates all_txt += self.calc_sig_effect_card_data(df,interest_var=self.variable, period=period) all_txt += """</div>""" print(all_txt) dct[period] = all_txt del df self.update_significant_DV_cards(dct) except Exception: logger.error('graph periods to date',exc_info=True) def graph_period_over_period(self,period): try: periods = [period] start_date = self.pop_start_date end_date = self.pop_end_date if isinstance(start_date,date): start_date = datetime.combine(start_date,datetime.min.time()) if isinstance(end_date,date): end_date = datetime.combine(end_date,datetime.min.time()) today = datetime.combine(datetime.today().date(),datetime.min.time()) ''' - if the start day is today (there is no data for today), adjust start date ''' if start_date == today: logger.warning('START DATE of WEEK IS TODAY.!NO DATA DATA') start_date = start_date - timedelta(days=7) self.datepicker_pop_start.value = start_date cols = [self.variable,self.timestamp_col, 'day'] df = self.load_df(start_date=start_date,end_date=end_date,cols=cols,timestamp_col='block_timestamp') if abs(start_date - end_date).days > 7: if 'week' in periods: periods.remove('week') if abs(start_date - end_date).days > 31: if 'month' in periods: periods.remove('month') if abs(start_date - end_date).days > 90: if 'quarter' in periods: periods.remove('quarter') for idx,period in enumerate(periods): df_period = self.period_over_period(df, start_date = start_date, end_date=end_date, period=period, history_periods=self.pop_history_periods, timestamp_col='block_timestamp') groupby_cols = ['dayset', 'period'] if len(df_period) > 0: df_period = df_period.groupby(groupby_cols).agg({self.variable: 'sum'}) df_period = df_period.reset_index() df_period = df_period.compute() else: df_period = df_period.compute() df_period = df_period.rename(index=str, columns={'day': 'dayset'}) prestack_cols = list(df_period.columns) logger.warning('Line 179:%s', df_period.head(10)) df_period = self.split_period_into_columns(df_period, col_to_split='period', value_to_copy=self.variable) # short term fix: filter out the unnecessary first day added by a corrupt quarter functionality if period == 'quarter': min_day = df_period['dayset'].min() logger.warning('LINE 252: MINIUMUM DAY:%s', min_day) df_period = df_period[df_period['dayset'] > min_day] logger.warning('line 180 df_period columns:%s', df_period.head(50)) poststack_cols = list(df_period.columns) title = "{} over {}".format(period, period) plotcols = list(np.setdiff1d(poststack_cols, prestack_cols)) df_period, plotcols = self.pop_include_zeros(df_period=df_period, plotcols=plotcols, period=period) if idx == 0: p = df_period.hvplot.bar('dayset',plotcols,rot=45,title=title, stacked=False,width=int(self.page_width*.8),height=400,value_label='#') else: p += df_period.hvplot.bar('dayset',plotcols,rot=45,title=title, stacked=False,width=int(self.page_width*.8),height=400,value_label='#') return p except Exception: logger.error('period over period to date', exc_info=True) # -------------------------------- PLOT TRENDS FOR SIGNIFICANT RATIOS -------------------------- def graph_significant_ratios_ts(self,launch=-1): try: df = self.make_significant_ratios_df(self.df,resample_period=self.resample_period, interest_var=self.variable, timestamp_col='block_timestamp') # clean if self.variable in df.columns: df = df.drop(self.variable,axis=1) #df = df.compute() # plot return df.hvplot.line(width=int(self.page_width*.8),height=400) except Exception: logger.error('graph significant ratios',exc_info=True) def update_variable(attrname, old, new): thistab.notification_updater("Calculations underway. Please be patient") thistab.variable = variable_select.value thistab.graph_periods_to_date(thistab.df,'block_timestamp',thistab.variable) thistab.section_header_updater('cards',label='') thistab.section_header_updater('pop',label='') thistab.trigger += 1 stream_launch.event(launch=thistab.trigger) stream_launch_sig_ratio.event(launch=thistab.trigger) thistab.notification_updater("ready") def update_period_over_period(): thistab.notification_updater("Calculations underway. Please be patient") thistab.pop_history_periods = pop_number_select.value thistab.pop_start_date = thistab.datepicker_pop_start.value # trigger period over period thistab.pop_end_date = datepicker_pop_end.value thistab.trigger += 1 stream_launch.event(launch=thistab.trigger) thistab.notification_updater("ready") def update_resample(attrname, old, new): thistab.notification_updater("Calculations underway. Please be patient") thistab.resample_period = resample_select.value thistab.trigger += 1 stream_launch_sig_ratio.event(launch=thistab.trigger) thistab.notification_updater("ready") def update_history_periods(attrname, old, new): thistab.notification_updater("Calculations underway. Please be patient") thistab.pop_history_periods = pop_number_select.value thistab.trigger += 1 stream_launch.event(launch=thistab.trigger) thistab.notification_updater("ready") try: cols = ['aion_fork','aion_watch','aion_release','aion_issue','aion_push','block_timestamp'] thistab = Thistab(table='account_ext_warehouse', cols=cols) # ------------------------------------- SETUP ---------------------------- # format dates first_date_range = thistab.initial_date last_date_range = datetime.now().date() last_date = dashboard_config['dates']['last_date'] first_date = datetime(last_date.year,1,1,0,0,0) thistab.df = thistab.load_df(first_date, last_date,cols,'block_timestamp') thistab.graph_periods_to_date(thistab.df,timestamp_filter_col='block_timestamp',variable=thistab.variable) thistab.section_header_updater('cards',label='') thistab.section_header_updater('pop',label='') # MANAGE STREAM # date comes out stream in milliseconds # --------------------------------CREATE WIDGETS --------------------------------- thistab.pop_end_date = last_date thistab.pop_start_date = thistab.first_date_in_period(thistab.pop_end_date, 'week') stream_launch = streams.Stream.define('Launch',launch=-1)() stream_launch_sig_ratio = streams.Stream.define('Launch_sigratio',launch=-1)() datepicker_pop_end = DatePicker(title="Period end", min_date=first_date_range, max_date=last_date_range, value=thistab.pop_end_date) pop_number_select = Select(title='Select # of comparative periods', value=str(thistab.pop_history_periods), options=thistab.menus['history_periods']) pop_button = Button(label="Select dates/periods, then click me!",width=15,button_type="success") variable_select = Select(title='Select variable', value=thistab.variable, options=thistab.menus['developer_adoption_DVs']) resample_select = Select(title='Select resample period', value=thistab.resample_period, options=thistab.menus['resample_period']) # --------------------------------- GRAPHS --------------------------- hv_sig_ratios = hv.DynamicMap(thistab.graph_significant_ratios_ts, streams=[stream_launch_sig_ratio]) sig_ratios= renderer.get_plot(hv_sig_ratios) hv_pop_week = hv.DynamicMap(thistab.pop_week,streams=[stream_launch]) pop_week = renderer.get_plot(hv_pop_week) hv_pop_month = hv.DynamicMap(thistab.pop_month,streams=[stream_launch]) pop_month = renderer.get_plot(hv_pop_month) hv_pop_quarter = hv.DynamicMap(thistab.pop_quarter, streams=[stream_launch]) pop_quarter = renderer.get_plot(hv_pop_quarter) # -------------------------------- CALLBACKS ------------------------ variable_select.on_change('value', update_variable) pop_button.on_click(update_period_over_period) # lags array resample_select.on_change('value', update_resample) pop_number_select.on_change('value',update_history_periods) # -----------------------------------LAYOUT ---------------------------- # put the controls in a single element controls_ptd = WidgetBox(variable_select, resample_select) controls_pop = WidgetBox(thistab.datepicker_pop_start, datepicker_pop_end, pop_number_select,pop_button) grid_data = [ [thistab.notification_div['top']], [Spacer(width=20, height=40)], [thistab.section_headers['sig_ratio']], [Spacer(width=20, height=25)], [sig_ratios.state, controls_ptd], [thistab.section_headers['cards']], [Spacer(width=20, height=2)], [thistab.KPI_card_div], [thistab.section_headers['pop']], [Spacer(width=20, height=25)], [pop_week.state,controls_pop], [pop_month.state], [pop_quarter.state], [thistab.notification_div['bottom']] ] grid = gridplot(grid_data) # Make a tab with the layout tab = Panel(child=grid, title='KPI: developer adoption') return tab except Exception: logger.error('rendering err:', exc_info=True) return tab_error_flag('KPI: developer adoption')
x = np.linspace(0, 2, 1000) y = 1 - (x-1)**2 source = ColumnDataSource(data=dict(x=x, y=y)) p = figure(title="initial title") p.circle(x=1, y=list(range(0, 11))) p.line('x', 'y', color="orange", source=source) slider = Slider(start=0, end=10, step=0.1, value=1) def scb(attr, old, new): source.data['y'] = new * y slider.on_change('value', scb) combine = Button(label="hold combine") combine.on_event(ButtonClick, lambda event: doc.hold("combine")) collect = Button(label="hold collect") collect.on_event(ButtonClick, lambda event: doc.hold("collect")) unhold = Button(label="unhold") unhold.on_event(ButtonClick, lambda event: doc.unhold()) doc.add_root(column(p, slider, combine, collect, unhold)) @repeat(np.linspace(0, 10, 100)) def update(v): slider.value = v curdoc().add_periodic_callback(update, 200)
def write_segmentation(): save_fiducials(new_pts,'./SEGMENTATIONS_NEW.csv') def change_range(attr, old, new): low, high = rangeslider.value for i in range(12): leads[i].x_range.start = low leads[i].x_range.end = high # Set widgets rangeslider = RangeSlider(start=0, end=1000, step=1, value=(0,1000), title="X range") file_selector = Select(value=None, options=nix(None,list_files_bokeh(DATA_DIR))) textboxold = PreText(text="Original points: \t[]") textboxnew = PreText(text="New points: \t[]") retrievebutton = Button(label='Retrieve Segmentation') storebutton = Button(label='Store Segmentation') writebutton = Button(label='Write to File') # Set callbacks file_selector.on_change('value', file_change) source.selected.on_change('indices', selection_change) retrievebutton.on_click(retrieve_segmentation) storebutton.on_click(save_segmentation) writebutton.on_click(write_segmentation) rangeslider.on_change('value',change_range) # set up layout textboxes = row(textboxold,textboxnew) buttons = row(retrievebutton,storebutton,writebutton,rangeslider)
title='Minimum Age (Inclusive)') max_age_select = Slider(start=0, end=max(df['age']), value=max(df['age']), step=1, title='Maximum Age (Inclusive)') # Create checkboxes for enabling each sex sex_select = CheckboxGroup(labels=['Male', 'Female'], active=[0, 1]) # Combine all the widgets above into a tabbed pane selectors = Tabs(tabs=[ Panel(child=HBox(category_select), title='Category'), Panel(child=HBox(min_size_select, max_size_select), title='Group Size'), Panel(child=HBox(min_age_select, max_age_select), title='Age'), Panel(child=HBox(sex_select), title='Sex') ]) generate = Button(label='Generate') renderer = plot.line([], [], line_width=2, line_alpha=0.75) def generate_plot(): # Perhaps `regenerate_plot`? """ Dynamically fit and plot a Kaplan-Meier curve. """ df_ = df.copy() # Use constraints for index in range(len(categories)): if index not in category_select.active: df_ = df_[df_.category != category_select.labels[index]] df_ = df_[min_size_select.value <= df_['size']] df_ = df_[df_['size'] <= max_size_select.value]
def produce_graphs(self, context, doc): """ Create timetool data timehistory, timetool vs ipm, and correlation timehistory graphs. Parameters ---------- context = zmq.Context() Creates zmq socket to receive data doc: bokeh.document (I think) Bokeh document to be displayed on webpage """ port = 5006 socket = context.socket(zmq.SUB) # MUST BE FROM SAME MACHINE, CHANGE IF NECESSARY!!! socket.connect("tcp://psanagpu114:%d" % port) socket.setsockopt(zmq.SUBSCRIBE, b"") # Note: Cannot name 'timetool' variables in hvTimeTool and hvIpmAmp the same thing # Otherwise, holoviews will try to sync the axis and throw off the ranges for the plots # since hvIpmAmp only deals with the last 1000 points whereas hvTimeTool deals with all # the points hvTimeTool = hv.DynamicMap(my_partial(hv.Points, kdims=['timestamp', 'timetool']), streams=[self.b_timetool]).options( width=1000, finalize_hooks=[apply_formatter], xrotation=45).redim.label( timestamp='Time in UTC', timetool='Timetool Data') hvIpmAmp = hv.DynamicMap( my_partial(hv.Scatter, kdims=['timetool', 'ipm']), streams=[self.b_IpmAmp]).options(width=500).redim.label( timetool='Last 1000 Timetool Data Points', ipm='Last 1000 Ipm Data Points') hvCorrTimeHistory = hv.DynamicMap( my_partial(hv.Scatter, kdims=['timestamp', 'correlation']), streams=[self.b_corr_timehistory ]).options(width=500, finalize_hooks=[apply_formatter], xrotation=45).redim.label(time='Time in UTC') layout = (hvIpmAmp + hvCorrTimeHistory + hvTimeTool).cols(2) hvplot = renderer.get_plot(layout) def push_data_timetool(buffer): """ Push data to timetool time history graph """ timetool_d = deque(maxlen=self.maxlen) timetool_t = deque(maxlen=self.maxlen) if socket.poll(timeout=0): data_dict = socket.recv_pyobj() timetool_d = data_dict['tt__FLTPOS_PS'] # Get time from data_dict timeData = deque(maxlen=self.maxlen) for time in data_dict['event_time']: num1 = str(time[0]) num2 = str(time[1]) fullnum = num1 + "." + num2 timeData.append(float(fullnum)) timetool_t = timeData # Convert time to seconds so bokeh formatter can get correct datetime times = [1000 * time for time in list(timetool_t)] data = pd.DataFrame({'timestamp': times, 'timetool': timetool_d}) buffer.send(data) def push_data_amp_ipm(buffer): """ Push data into timetool amp vs ipm graph """ timetool_d = deque(maxlen=self.maxlen) ipm_d = deque(maxlen=self.maxlen) if socket.poll(timeout=0): data_dict = socket.recv_pyobj() timetool_d = data_dict['tt__AMPL'] ipm_d = data_dict[self.switchButton] data = pd.DataFrame({'timetool': timetool_d, 'ipm': ipm_d}) buffer.send(data) def push_data_corr_time_history(buffer): """ Calculate correlation between timetool amp and ipm and push to correlation time history graph """ timetool_d = deque(maxlen=self.maxlen) timetool_t = deque(maxlen=self.maxlen) ipm_d = deque(maxlen=self.maxlen) if socket.poll(timeout=0): data_dict = socket.recv_pyobj() timetool_d = data_dict['tt__FLTPOS_PS'] ipm_d = data_dict[self.switchButton] # Get time from data_dict timeData = deque(maxlen=self.maxlen) for time in data_dict['event_time']: num1 = str(time[0]) num2 = str(time[1]) fullnum = num1 + "." + num2 timeData.append(float(fullnum)) timetool_t = timeData # Convert time to seconds so bokeh formatter can get correct datetime times = [1000 * time for time in list(timetool_t)] data = pd.DataFrame({'timetool': timetool_d, 'ipm': ipm_d}) data_corr = data['timetool'].rolling(window=120).corr( other=data['ipm']) # Start at index 119 so we don't get null data final_df = pd.DataFrame({ 'timestamp': times[119:], 'correlation': data_corr[119:] }) buffer.send(final_df) def switch(attr, old, new): """ Update drop down menu value """ self.switchButton = select.value self.clear_buffer() def stop(): """ Add pause and play functionality to graph """ if stopButton.label == 'Play': stopButton.label = 'Pause' self.cb_id_timetool = doc.add_periodic_callback( partial(push_data_timetool, buffer=self.b_timetool), 1000) self.cb_id_amp_ipm = doc.add_periodic_callback( partial(push_data_amp_ipm, buffer=self.b_IpmAmp), 1000) self.cb_id_corr_timehistory = doc.add_periodic_callback( partial(push_data_corr_time_history, buffer=self.b_corr_timehistory), 1000) else: stopButton.label = 'Play' doc.remove_periodic_callback(self.cb_id_timetool) doc.remove_periodic_callback(self.cb_id_amp_ipm) doc.remove_periodic_callback(self.cb_id_corr_timehistory) # Start the callback self.cb_id_timetool = doc.add_periodic_callback( partial(push_data_timetool, buffer=self.b_timetool), 1000) self.cb_id_amp_ipm = doc.add_periodic_callback( partial(push_data_amp_ipm, buffer=self.b_IpmAmp), 1000) self.cb_id_corr_timehistory = doc.add_periodic_callback( partial(push_data_corr_time_history, buffer=self.b_corr_timehistory), 1000) # Use this to test since ipm2 and ipm3 are too similar to see any differences # select = Select(title='ipm value:', value='ipm2__sum', options=['ipm2__sum', 'tt__FLTPOS_PS']) select = Select(title='ipm value:', value='ipm2__sum', options=['ipm2__sum', 'ipm3__sum']) select.on_change('value', switch) stopButton = Button(label='Pause') stopButton.on_click(stop) plot = column(select, stopButton, hvplot.state) doc.add_root(plot)
doc = curdoc() ''' Variables ''' renderer = None render_callback = None speed = 0.1 viz_dt = 50 # update every ms ''' UI ''' t1 = Div(text='Time:', style={'font-size': '150%'}) t2 = Div(text='N/A', style={'font-size': '150%'}) reset_button = Button(label='⟲ Reset', width=60) pp_button = Button(label='► Play', width=60, margin=(5, 5, 5, 15)) rec_button = Button(label='⏺️ Record', width=75, margin=(5, 15, 5, 5)) speed_slider = Slider(start=-2.0, end=1.0, value=-1.0, step=0.02, title='Speed', width=300) ''' Callbacks ''' def update(): global renderer, viz_dt, render_callback
myStream = tweepy.Stream(auth=api.auth, listener=callback) myStream.filter(track=topic, async=True) ######## Creating Visualizations ############### # Heading heading = PreText(text="""\bANALYZING REAL TIME TWITTER DATA\b""", height=50, width=1500) #------------------------------------------------------------------------------------------------------------------ # Catergory text search search_1 = TextInput(value="default", title="Search Term 1:") search_2 = TextInput(value="default", title="Search Term 2:") button_go = Button(label="Compare", width=100, button_type="success") #------------------------------------------------------------------------------------------------------------------ # Tweets display text = "Real Time Tweets-- \n" current_tweets_plot = PreText(text=text, width=400, height=900) #------------------------------------------------------------------------------------------------------------------ # Line chart for tweet rate df_tweet_1 = pd.DataFrame(columns=['Timestamp', 'Tweet', 'rounded_time']) df_tweet_1 = df_tweet_1.fillna(0) df_tweet_2 = pd.DataFrame(columns=['Timestamp', 'Tweet', 'rounded_time']) df_tweet_2 = df_tweet_2.fillna(0) tweet_rate_plot = figure(title='Tweet Rate(per 5 seconds)', x_axis_type="datetime",
def __init__(self, sources, range_categories, custom_title, data_tables): self.sources = sources self.range_categories = range_categories self.current_dvh_group = {n: [] for n in GROUP_LABELS} # Control Chart layout (Time-Series) tools = "pan,wheel_zoom,box_zoom,lasso_select,poly_select,reset,crosshair,save" self.plot = figure(plot_width=1050, plot_height=400, tools=tools, logo=None, active_drag="box_zoom", x_axis_type='datetime') self.plot.xaxis.axis_label_text_font_size = options.PLOT_AXIS_LABEL_FONT_SIZE self.plot.yaxis.axis_label_text_font_size = options.PLOT_AXIS_LABEL_FONT_SIZE self.plot.xaxis.major_label_text_font_size = options.PLOT_AXIS_MAJOR_LABEL_FONT_SIZE self.plot.yaxis.major_label_text_font_size = options.PLOT_AXIS_MAJOR_LABEL_FONT_SIZE # plot.min_border_left = min_border self.plot.min_border_bottom = options.MIN_BORDER self.plot_data_1 = self.plot.circle('x', 'y', size=options.TIME_SERIES_1_CIRCLE_SIZE, color=options.GROUP_1_COLOR, alpha=options.TIME_SERIES_1_CIRCLE_ALPHA, source=sources.time_1) self.plot_data_2 = self.plot.circle('x', 'y', size=options.TIME_SERIES_2_CIRCLE_SIZE, color=options.GROUP_2_COLOR, alpha=options.TIME_SERIES_2_CIRCLE_ALPHA, source=sources.time_2) self.plot_trend_1 = self.plot.line('x', 'y', color=options.GROUP_1_COLOR, source=sources.time_trend_1, line_width=options.TIME_SERIES_1_TREND_LINE_WIDTH, line_dash=options.TIME_SERIES_1_TREND_LINE_DASH) self.plot_trend_2 = self.plot.line('x', 'y', color=options.GROUP_2_COLOR, source=sources.time_trend_2, line_width=options.TIME_SERIES_2_TREND_LINE_WIDTH, line_dash=options.TIME_SERIES_2_TREND_LINE_DASH) self.plot_avg_1 = self.plot.line('x', 'avg', color=options.GROUP_1_COLOR, source=sources.time_bound_1, line_width=options.TIME_SERIES_1_AVG_LINE_WIDTH, line_dash=options.TIME_SERIES_1_AVG_LINE_DASH) self.plot_avg_2 = self.plot.line('x', 'avg', color=options.GROUP_2_COLOR, source=sources.time_bound_2, line_width=options.TIME_SERIES_2_AVG_LINE_WIDTH, line_dash=options.TIME_SERIES_2_AVG_LINE_DASH) self.plot_patch_1 = self.plot.patch('x', 'y', color=options.GROUP_1_COLOR, source=sources.time_patch_1, alpha=options.TIME_SERIES_1_PATCH_ALPHA) self.plot_patch_2 = self.plot.patch('x', 'y', color=options.GROUP_2_COLOR, source=sources.time_patch_2, alpha=options.TIME_SERIES_1_PATCH_ALPHA) self.plot.add_tools(HoverTool(show_arrow=True, tooltips=[('ID', '@mrn'), ('Date', '@x{%F}'), ('Value', '@y{0.2f}')], formatters={'x': 'datetime'})) self.plot.xaxis.axis_label = "Simulation Date" self.plot.yaxis.axis_label = "" # Set the legend legend_plot = Legend(items=[("Group 1", [self.plot_data_1]), ("Series Average", [self.plot_avg_1]), ("Rolling Average", [self.plot_trend_1]), ("Percentile Region", [self.plot_patch_1]), ("Group 2", [self.plot_data_2]), ("Series Average", [self.plot_avg_2]), ("Rolling Average", [self.plot_trend_2]), ("Percentile Region", [self.plot_patch_2])], location=(25, 0)) # Add the layout outside the plot, clicking legend item hides the line self.plot.add_layout(legend_plot, 'right') self.plot.legend.click_policy = "hide" plot_options = list(range_categories) plot_options.sort() plot_options.insert(0, '') self.y_axis = Select(value=plot_options[0], options=plot_options, width=300) self.y_axis.title = "Select a Range Variable" self.y_axis.on_change('value', self.update_y_axis_ticker) self.look_back_distance = TextInput(value='1', title="Lookback Distance", width=200) self.look_back_distance.on_change('value', self.update_plot_trend_ticker) self.plot_percentile = TextInput(value='90', title="Percentile", width=200) self.plot_percentile.on_change('value', self.update_plot_trend_ticker) look_back_units_options = ['Dates with a Sim', 'Days'] self.look_back_units = Select(value=look_back_units_options[0], options=look_back_units_options, width=200) self.look_back_units.title = 'Lookback Units' self.look_back_units.on_change('value', self.update_plot_ticker) # source_time.on_change('selected', plot_update_trend) self.trend_update_button = Button(label="Update Trend", button_type="primary", width=150) self.trend_update_button.on_click(self.plot_update_trend) self.download_time_plot = Button(label="Download Plot Data", button_type="default", width=150) self.download_time_plot.callback = CustomJS(args=dict(source_1=sources.time_1, source_2=sources.time_2), code=open(join(dirname(__file__), "download_time_plot.js")).read()) # histograms tools = "pan,wheel_zoom,box_zoom,reset,crosshair,save" self.histograms = figure(plot_width=1050, plot_height=400, tools=tools, logo=None, active_drag="box_zoom") self.histograms.xaxis.axis_label_text_font_size = options.PLOT_AXIS_LABEL_FONT_SIZE self.histograms.yaxis.axis_label_text_font_size = options.PLOT_AXIS_LABEL_FONT_SIZE self.histograms.xaxis.major_label_text_font_size = options.PLOT_AXIS_MAJOR_LABEL_FONT_SIZE self.histograms.yaxis.major_label_text_font_size = options.PLOT_AXIS_MAJOR_LABEL_FONT_SIZE self.histograms.min_border_left = options.MIN_BORDER self.histograms.min_border_bottom = options.MIN_BORDER self.hist_1 = self.histograms.vbar(x='x', width='width', bottom=0, top='top', source=sources.histogram_1, color=options.GROUP_1_COLOR, alpha=options.HISTOGRAM_1_ALPHA) self.hist_2 = self.histograms.vbar(x='x', width='width', bottom=0, top='top', source=sources.histogram_2, color=options.GROUP_2_COLOR, alpha=options.HISTOGRAM_2_ALPHA) self.histograms.xaxis.axis_label = "" self.histograms.yaxis.axis_label = "Frequency" self.histogram_bin_slider = Slider(start=1, end=100, value=10, step=1, title="Number of Bins") self.histogram_bin_slider.on_change('value', self.histograms_ticker) self.histogram_radio_group = RadioGroup(labels=["Absolute Y-Axis", "Relative Y-Axis (to Group Max)"], active=0) self.histogram_radio_group.on_change('active', self.histograms_ticker) self.histogram_normaltest_1_text = Div(text="Group 1 Normal Test p-value = ", width=400) self.histogram_normaltest_2_text = Div(text="Group 2 Normal Test p-value = ", width=400) self.histogram_ttest_text = Div(text="Two Sample t-Test (Group 1 vs 2) p-value = ", width=400) self.histogram_ranksums_text = Div(text="Wilcoxon rank-sum (Group 1 vs 2) p-value = ", width=400) self.histograms.add_tools(HoverTool(show_arrow=True, line_policy='next', tooltips=[('x', '@x{0.2f}'), ('Counts', '@top')])) # Set the legend legend_hist = Legend(items=[("Group 1", [self.hist_1]), ("Group 2", [self.hist_2])], location=(25, 0)) # Add the layout outside the plot, clicking legend item hides the line self.histograms.add_layout(legend_hist, 'right') self.histograms.legend.click_policy = "hide" self.layout = column(Div(text="<b>DVH Analytics v%s</b>" % options.VERSION), row(custom_title['1']['time_series'], Spacer(width=50), custom_title['2']['time_series']), row(self.y_axis, self.look_back_units, self.look_back_distance, Spacer(width=10), self.plot_percentile, Spacer(width=10), self.trend_update_button), self.plot, self.download_time_plot, Div(text="<hr>", width=1050), row(self.histogram_bin_slider, self.histogram_radio_group), row(self.histogram_normaltest_1_text, self.histogram_ttest_text), row(self.histogram_normaltest_2_text, self.histogram_ranksums_text), self.histograms, Spacer(width=1000, height=10))
def home(): bokeh_width, bokeh_height = 1000, 600 lat, lon = 46.2437, 6.0251 api_key = "AIzaSyB4y5u1q0_-4kVQpSMGkH_dxpnzn8PL-dQ" print(str(api_key)) def plot(lat, lng, zoom=10, map_type='roadmap'): from bokeh.io import show from bokeh.plotting import gmap from bokeh.models import GMapOptions gmap_options = GMapOptions(lat=lat, lng=lng, map_type=map_type, zoom=zoom) p = gmap(api_key, gmap_options, title='Pays de Gex', width=bokeh_width, height=bokeh_height) # beware, longitude is on the x axis ;-) center = p.circle([lng], [lat], size=10, alpha=0.5, color='red') return p p = plot(lat, lon, map_type='roadmap') #--------------------------------------------------- from bokeh.io import curdoc from bokeh.layouts import column from bokeh.models import Button, ColumnDataSource from bokeh.plotting import Figure from bokeh.embed import components from bokeh.resources import CDN from numpy.random import random xs = [] ys = [] points = ColumnDataSource(data={'x_coord': xs, 'y_coord': ys}) plot = Figure(title="Random Lines", x_range=(0, 1), y_range=(0, 1)) plot.line('x_coord', 'y_coord', source=points) button = Button(label="Click Me!") def add_random_line(): """ Adds a new random point to the line. """ x, y = random(2) newxs = [*points.data['x_coord'], x] newys = [*points.data['y_coord'], y] points.data = {'x_coord': newxs, 'y_coord': newys} button.on_click(add_random_line) layout = column(button, plot) curdoc().add_root(layout) script1, div1, = components(p) cdn_js = CDN.js_files[0] cdn_css = CDN.css_files print(script1) print('\n============================================') print(div1) print('\n============================================') print(cdn_css) print('\n============================================') print(cdn_js) # return render_template("combine.html",script1=script1,div1=div1, cdn_css=cdn_css,cdn_js=cdn_js) data_val1 = 'Hard Coded value 1' data_val2 = 'Hard coded value 2' templateData = {'data1': data_val1, 'data2': data_val2} return render_template("combine.html", **templateData, script1=script1, div1=div1, cdn_css=cdn_css, cdn_js=cdn_js)
def slider_update(attrname, old, new): year = slider.value label.text = str(year) source.data = data[year] slider = Slider(start=years[0], end=years[-1], value=years[0], step=1, title="Year") slider.on_change('value', slider_update) callback_id = None def animate(): global callback_id if button.label == '► Play': button.label = '❚❚ Pause' callback_id = curdoc().add_periodic_callback(animate_update, 200) else: button.label = '► Play' curdoc().remove_periodic_callback(callback_id) button = Button(label='► Play', width=60) button.on_click(animate) layout = layout([ [plot], [slider, button], ], sizing_mode='scale_width') curdoc().add_root(layout) curdoc().title = "Gapminder"
class ProfileTimePlot(DashboardComponent): """Time plots of the current resource usage on the cluster This is two plots, one for CPU and Memory and another for Network I/O """ def __init__(self, server, doc=None, **kwargs): if doc is not None: self.doc = weakref.ref(doc) try: self.key = doc.session_context.request.arguments.get("key", None) except AttributeError: self.key = None if isinstance(self.key, list): self.key = self.key[0] if isinstance(self.key, bytes): self.key = self.key.decode() self.task_names = ["All", self.key] if self.key else ["All"] else: self.key = None self.task_names = ["All"] self.server = server self.start = None self.stop = None self.ts = {"count": [], "time": []} self.state = profile.create() data = profile.plot_data(self.state, profile_interval) self.states = data.pop("states") self.profile_plot, self.source = profile.plot_figure(data, **kwargs) changing = [False] # avoid repeated changes from within callback @without_property_validation def cb(attr, old, new): if changing[0] or len(new) == 0: return with log_errors(): data = profile.plot_data(self.states[new[0]], profile_interval) del self.states[:] self.states.extend(data.pop("states")) changing[0] = True # don't recursively trigger callback update(self.source, data) self.source.selected.indices = old changing[0] = False self.source.selected.on_change("indices", cb) self.ts_source = ColumnDataSource({"time": [], "count": []}) self.ts_plot = figure( title="Activity over time", height=150, x_axis_type="datetime", active_drag="xbox_select", tools="xpan,xwheel_zoom,xbox_select,reset", sizing_mode="stretch_width", toolbar_location="above", ) self.ts_plot.line("time", "count", source=self.ts_source) self.ts_plot.circle( "time", "count", source=self.ts_source, color=None, selection_color="orange" ) self.ts_plot.yaxis.visible = False self.ts_plot.grid.visible = False def ts_change(attr, old, new): with log_errors(): selected = self.ts_source.selected.indices if selected: start = self.ts_source.data["time"][min(selected)] / 1000 stop = self.ts_source.data["time"][max(selected)] / 1000 self.start, self.stop = min(start, stop), max(start, stop) else: self.start = self.stop = None self.trigger_update(update_metadata=False) self.ts_source.selected.on_change("indices", ts_change) self.reset_button = Button(label="Reset", button_type="success") self.reset_button.on_click(lambda: self.update(self.state)) self.update_button = Button(label="Update", button_type="success") self.update_button.on_click(self.trigger_update) self.select = Select(value=self.task_names[-1], options=self.task_names) def select_cb(attr, old, new): if new == "All": new = None self.key = new self.trigger_update(update_metadata=False) self.select.on_change("value", select_cb) self.root = column( row( self.select, self.reset_button, self.update_button, sizing_mode="scale_width", height=250, ), self.profile_plot, self.ts_plot, **kwargs, ) @without_property_validation def update(self, state, metadata=None): with log_errors(): self.state = state data = profile.plot_data(self.state, profile_interval) self.states = data.pop("states") update(self.source, data) if metadata is not None and metadata["counts"]: self.task_names = ["All"] + sorted(metadata["keys"]) self.select.options = self.task_names if self.key: ts = metadata["keys"][self.key] else: ts = metadata["counts"] times, counts = zip(*ts) self.ts = {"count": counts, "time": [t * 1000 for t in times]} self.ts_source.data.update(self.ts) @without_property_validation def trigger_update(self, update_metadata=True): async def cb(): with log_errors(): prof = await self.server.get_profile( key=self.key, start=self.start, stop=self.stop ) if update_metadata: metadata = await self.server.get_profile_metadata() else: metadata = None if isinstance(prof, gen.Future): prof, metadata = await asyncio.gather(prof, metadata) self.doc().add_next_tick_callback(lambda: self.update(prof, metadata)) self.server.loop.add_callback(cb)
# remove.py import numpy as np from bokeh.io import curdoc from bokeh.models import Button from bokeh.plotting import figure, curdoc, vplot xs = np.random.normal(loc=1.0, size=100) ys = np.random.normal(loc=1.0, size=100) TOOLS="pan,wheel_zoom,box_select,lasso_select" p = figure(tools=TOOLS, plot_width=600, plot_height=600, title=None, min_border=10, min_border_left=50) r = p.scatter(xs.tolist(), ys.tolist(), size=3, color="#3A5785", alpha=0.6) source = r.data_source empty_selection = r.data_source.selected def callback(): source.selected = empty_selection button = Button(label="Remove Points", width=20) button.on_click(callback) # put the button and plot in a layout and add to the document curdoc().add_root(vplot(button, p))
y = np.random.random(size=N) * 100 radii = np.random.random(size=N) * 1.5 colors = [ "#%02x%02x%02x" % (int(r), int(g), 150) for r, g in zip(50+2*x, 30+2*y) ] p = figure(tools="pan,wheel_zoom,zoom_in,zoom_out,reset") p.scatter(x, y, radius=radii, fill_color=colors, fill_alpha=0.6, line_color=None) # Add a div to display events and a button to trigger button click events div = Div(width=1000) button = Button(label="Button", button_type="success") layout = column(button, row(p, div)) point_attributes = ['x','y','sx','sy'] pan_attributes = point_attributes + ['delta_x', 'delta_y'] pinch_attributes = point_attributes + ['scale'] wheel_attributes = point_attributes+['delta'] ## Register Javascript event callbacks # Button event button.js_on_event(events.ButtonClick, display_event(div)) # LOD events p.js_on_event(events.LODStart, display_event(div))
pass #### WIDGET CREATIONS #### # OLD VANILLA # add a button widget and configure with the call back # button_basic = Button(label="Press Me") # button_basic.on_click(callback) #make_bokeh_crossfilter() # create a button for Select button for input #menu = [("Bulk Modulus", "B"), ("B'", "dB"), ("Lattice Constant", "a0")] #select_property = Select(name="Selection", options=menu, value="B") #select_property.on_click(make_bokeh_crossfilter(axis=value)) # create a button for make crossfilter app button_crossfilter = Button(label="Make Crossfilter") button_crossfilter.on_click(make_bokeh_crossfilter) #create a button for crossfilter_workflwo button_w_crossfilter = Button(label="Make Crossfilter Workflow") button_w_crossfilter.on_click(make_wflow_crossfilter) # put the button and plot in a layout and add to the document curdoc().add_root(column(button_crossfilter, button_w_crossfilter, p))
def modify_doc(doc): plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_tools(CustomAction(callback=CustomJS(args=dict(s=source), code=RECORD("data", "s.data")))) button = Button(css_classes=["foo"]) button.js_on_click(CustomJS(args=dict(s=source), code="s.patch({'x': [[1, 100]]})")) doc.add_root(column(button, plot))
def root(): # add a button widget and configure with the call back button = Button(label="Press Me") button.on_click(scrape_prices(url)) p = make_hist(prices) #layout = vform(button, p) #script, div = embed.components(layout) script, div = embed.components(p,button) return render_template('histograms.html',script = script,div = div)