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_click(cb) doc.add_root(column(button, plot))
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 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 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 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 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)
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 bkapp(doc): def fitButtonCallback(new): x_range = [p.x_range.start, p.x_range.end] y_range = [p.y_range.start, p.y_range.end] x_inds = np.where(np.logical_and(bin_mids >= x_range[0], bin_mids <= x_range[1]), bin_mids, np.nan) x = x_inds[np.isfinite(x_inds)] y = hist[np.isfinite(x_inds)] x_fit = np.linspace(x_range[0], x_range[1], 10000) p0 = [y.max(), x[np.argmax(y)], x[np.argmax(y)], 0] p_fit = curve_fit(_gaus, x, y, p0, ftol=1e-2)[0] y_fit = _gaus(x_fit, *p_fit) # p.line(x_fit, y_fit, legend_label='Amp. = %5.2f, Mean = %5.2f, Std. = %5.2f, Base = %5.2f' % p_fit) fitDataSource.patch(dict(x=[(slice(0, len(x_fit)), x_fit)], y=[(slice(0, len(y_fit)), y_fit)])) fit_str = 'Amp. = %5.2f, Mean = %5.2f, Std. = %5.2f, Base = %5.2f' % (p_fit[0], p_fit[1], p_fit[2], p_fit[3]) #p.line(x=x_fit, y=y_fit, legend_label=new_data['legend_label'], color='black') p.x_range = Range1d(bins[0], bins[-1]) p.y_range = Range1d(0, hists[0].max()) p.legend.items = [(settings['sz_key'], [hist_line]), (fit_str, [fit_line])] def SzDropDownCallback(new): settings['sz_key'] = new.item bins = np.linspace(0, 130000, 1000) size_datasets = pysp2.util.calc_diams_masses(my_cal_data[settings['sz_key']]) hist, bins = np.histogram(size_datasets[settings['variable']].where(size_datasets.ScatRejectKey == 0).values, bins=bins) histDataSource.patch(dict(x=[(slice(0, len(bin_mids)), bin_mids)], y=[(slice(0, len(hist)), hist)])) p.legend.items = [(settings['sz_key'], [hist_line]), ("", [fit_line])] def VariableCallback(new): settings['variable'] = new.item bins = np.linspace(0, 130000, 1000) size_datasets = pysp2.util.calc_diams_masses(my_cal_data[settings['sz_key']]) hist, bins = np.histogram(size_datasets[settings['variable']].where(size_datasets.ScatRejectKey == 0).values, bins=bins) histDataSource.patch(dict(x=[(slice(0, len(bin_mids)), bin_mids)], y=[(slice(0, len(hist)), hist)])) p.legend.items = [(settings['sz_key'], [hist_line]), ("", [fit_line])] settings = {'sz_key':'scat_200', 'variable': 'PkHt_ch0'} sizes = np.array([350, 300, 269, 220, 200, 170]) scat_mean = np.ones_like(sizes, dtype=float) size_datasets = {} i = 0 # bins = np.logspace(-13, -10, 120) bins = np.linspace(0, 130000, 1000) hists = np.zeros((len(sizes), len(bins) - 1)) size_datasets = pysp2.util.calc_diams_masses(my_cal_data[settings['sz_key']]) hist, bins = np.histogram(size_datasets[settings['variable']].where(size_datasets.ScatRejectKey == 0).values, bins=bins) p = figure(tools="pan,box_zoom,reset,save", x_range=(bins[0], bins[-1]), y_range=(0, hist.max())) bin_mids = (bins[:-1] + bins[1:])/2.0 histDataSource = ColumnDataSource(data=dict(x=bin_mids, y=hist)) x_fit = np.linspace(0, 130000, 10000) fitDataSource = ColumnDataSource(data=dict(x=x_fit, y=np.nan*np.ones_like(x_fit))) hist_line = p.line('x', 'y', source=histDataSource, legend_label=settings['sz_key']) fit_line = p.line('x', 'y', source=fitDataSource, legend_label="") button = Button(label="Curve fit") button.on_click(fitButtonCallback) size_menu = [] for keys in my_cal_data.keys(): size_menu.append((keys, keys)) SzDropDown = Dropdown(label="Calibration data", menu=size_menu) SzDropDown.on_click(SzDropDownCallback) vars = ["PkHt_ch0", "PkHt_ch1", "PkHt_ch4", "PkHt_ch5", "FtAmp_ch0", 'FtAmp_ch4'] vars = [(x, x) for x in vars] VarDropDown = Dropdown(label="Variable", menu=vars) VarDropDown.on_click(VariableCallback) doc.add_root(column(button, SzDropDown, VarDropDown, p))
def createGapMinder(pds, features, curdoc): """Generates a gap minder plot. :param pds: list of dicitionaries. :param features: the list of features :param curdoc: The curdoc instance :returns: The gapminder plot and a slider :rtype: bokeh.layouts.row, bokeh.models.Slider """ mysource = ColumnDataSource(data=pds[0]) myplot = figure(x_range=(0, 10), y_range=(0, 10), title='Word Frequencies with Ratings', plot_height=300) myplot.xgrid.grid_line_color = None myplot.ygrid.grid_line_color = None myplot.toolbar.logo = None myplot.toolbar_location = None myplot.xaxis.axis_label = "Hover on Circles to see the words" color_mapper = CategoricalColorMapper(palette=['red','blue',"green","yellow","black"], factors=["1","2","3","4","5"]) myplot.circle( x="xval", y="yval", size="freq", source=mysource, fill_color={'field': 'sentiment', 'transform': color_mapper}, fill_alpha=0.8, line_color='#7c7e71', line_width=0.5, line_alpha=0.2, legend=field('sentiment') ) myplot.add_tools(HoverTool(tooltips="@word", show_arrow=False, point_policy='follow_mouse')) myslider = Slider(start=0, end=2, value=0, step=1, title=features[0]) mybutton = Button(label='Play', width=60) def animate(): """The slider animate function :returns: nothing :rtype: None """ global callback_id if mybutton.label == 'Play' : mybutton.label = 'Pause' callback_id = curdoc.add_periodic_callback(animate_update, 1000) else: mybutton.label = 'Play' curdoc.remove_periodic_callback(callback_id) def slider_update(attrname, old, new): """The slider update function """ val = myslider.value myslider.title = features[val] mysource.data = pds[val] def animate_update(): val = myslider.value + 1 if val > 2: val = 0 myslider.value = val myslider.on_change('value', slider_update) mybutton.on_click(animate) inputs = widgetbox(myslider,mybutton) r = row(myplot,inputs) # layout = layout([[myplot], [myslider, mybutton]], sizing_mode='fixed') return r, myslider
rangeslider = RangeSlider(start=0, end=10000, step=1, value=(0, rs_width + 30), title="X range") file_selector = Select(value=None, options=nix(None, files)) waveselector = RadioButtonGroup(labels=["P wave", "QRS wave", "T wave"], active=0) 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) waveselector.on_change('active', wave_change) # set up layout buttons = row(waveselector, retrievebutton, storebutton, writebutton) layout = column(file_selector, textboxnew, rangeslider, buttons, grid) # initialize # update() curdoc().add_root(layout) curdoc().title = "Shareedb annotator"
options=wrf_model_options) wrf_model_select.on_change('value', update_datasource) # Time Select widget time_slider = Slider(start=0, end=1, value=0, step=1, title="Timestep") time_slider.on_change('value', update_datasource) # Width select widget width_slider = Slider(start=10, end=190, value=20, step=10, title="Cross section width") # button to apply width changes width_button = Button(label="Apply Width") width_button.on_click(click_update_datasource) # INITIALIZATION DATA # Location Data location_dict = {} location_dict['Tucson - UA'] = {'lat': 32.2319, 'lon': -110.9501, 'elevation': 728} location_dict['Red Horse Wind'] = {'lat': 32.285461, 'lon': -110.090711, 'elevation': 1580} location_dict['Chiricahua Gap'] = {'lat': 31.9, 'lon': -108.5, 'elevation': 1666} location_dict['San Pedro River - US/Mexico Border'] = {'lat': 31.334,
def gapminder_plot(doc): # Apply dimension labels and ranges kdims = ['Fertility', 'Life expectancy'] vdims = ['Country', 'Population', 'Group'] dimensions = { 'Fertility': dict(label='Children per woman (total fertility)', range=(0, 10)), 'Life expectancy': dict(label='Life expectancy at birth (years)', range=(15, 100)), 'Population': ('population', 'Population') } # Create Points plotting fertility vs life expectancy indexed by Year gapminder_ds = ds.redim(**dimensions).to(hv.Points, kdims, vdims, 'Year') # Define annotations text = gapminder_ds.clone({ yr: hv.Text(1.2, 25, str(int(yr)), fontsize=30) for yr in gapminder_ds.keys() }) # Define options opts = { 'plot': dict(width=950, height=450, tools=['hover'], size_index='Population', color_index='Group', size_fn=np.sqrt, title_format="{label}"), 'style': dict(cmap='Set1', size=0.3, line_color='black', alpha=0.6) } text_opts = {'style': dict(text_font_size='52pt', text_color='lightgray')} # Combine Points and Text hvgapminder = (gapminder_ds({'Points': opts}) * text({'Text': text_opts})).relabel('Gapminder Demo') # Define custom widgets def animate_update(): year = slider.value + 1 if year > end: year = start slider.value = year # Update the holoviews plot by calling update with the new year. def slider_update(attrname, old, new): hvplot.update((new, )) def animate(): if button.label == '► Play': button.label = '❚❚ Pause' doc.add_periodic_callback(animate_update, 200) else: button.label = '► Play' doc.remove_periodic_callback(animate_update) start, end = ds.range('Year') slider = Slider(start=start, end=end, value=start, step=1, title="Year") slider.on_change('value', slider_update) button = Button(label='► Play', width=60) button.on_click(animate) # Get HoloViews plot hvplot = BokehRenderer.get_plot(hvgapminder, doc) # Make a bokeh layout and add it as the Document root plot = layout([[hvplot.state], [slider, button]], sizing_mode='fixed') doc.add_root(plot) return doc
columns = [ TableColumn(field="symbol", title="symbol"), TableColumn(field="price", title="price") ] tblPrices = DataTable(source=currentData, columns=columns, width=400, height=280) def callback(): # test button callback #currentData.stream(generatePrice()) symbols = ['AAA', 'BBB', 'CCC'] prices = np.random.rand(len(symbols)).round(2) data = [(idx, val) for idx, val in enumerate(prices)] print('patch: ', data) patch = {'price': data} print(patch) currentData.patch(patch) # add a button widget and configure with the call back button = Button(label="Press Me", button_type='primary') button.on_click(callback) # put the button and plot in a layout and add to the document curdoc().add_root(column(button, tblPrices))
if not Active: if t != 0: Reset() # if simulation is not already started # release branch and start simulation space = True if grav_select.value == "Earth" or grav_select.value == "Erde": space = False monkeyLetGo(monkey, space) g1Projectiles = curdoc().add_periodic_callback(evolve, 50) glob_callback.data = dict(cid=[g1Projectiles]) # /output glob_active.data = dict(Active=[True]) fire_button = Button(label="Fire!", button_type="success") fire_button.on_click(Fire) def Reset(): [Active] = glob_active.data["Active"] # input/output [g1Projectiles] = glob_callback.data["cid"] # input/ [Done] = glob_done.data["Done"] # input/output # if simulation is in progress, stop simulation if Active: curdoc().remove_periodic_callback(g1Projectiles) glob_active.data = dict(Active=[False]) elif Done: glob_done.data = dict(Done=[False]) # return banana, monkey and cannon to original positions banana_current_position = (banana_init_pos[0], banana_init_pos[1] + height_slider.value)
code.on_change('value', lambda attr, old, new: CF.update_code()) exchange = Select(title='ExchangeCorrelation', value=exchanges[0], options=exchanges) exchange.on_change('value', lambda attr, old, new: CF.update_exchange()) struct = Select(title='Structure', value=structures[0], options=structures) struct.on_change('value', lambda attr, old, new: CF.update_struct()) element = CheckboxButtonGroup(labels=_elements, active=[1]) element.on_click(CF.update_element) prop = Select(title='Property', value=properties[0], options=properties) prop.on_change('value', lambda attr, old, new: CF.update_prop()) apply_crossfilter = Button(label='CrossFilter and Plot') apply_crossfilter.on_click(CF.update_crossfilter) clean_crossfilter = Button(label='Clear') clean_crossfilter.on_click(CF.clear_crossfilter) x_select.on_change('value', lambda attr, old, new: CF.update_x()) y_select.on_change('value', lambda attr, old, new: CF.update_y()) analyse_crossfilt = Button(label='PadeAnalysis') analyse_crossfilt.on_click(CF.analysis_callback) code_df = CF.crossfilter_by_tag(df_obs, {'code':code.value}) exchange_df = CF.crossfilter_by_tag(code_df, {'exchange':exchange.value}) struct_df = CF.crossfilter_by_tag(exchange_df, {'structure':struct.value}) elem_df = CF.crossfilter_by_tag(struct_df, {'element':_elements[0]})
class FlexOrientation(object): """ Manage the Orientation of a Nano """ #__slots__ = [''] # add legal instance variables # (setq properties `("" "")) def __init__(self, flexname: str = "Default", name="IMU", display=fakedisplay, pangle: str = "0.0", width=200): # FlexOrientation::__init__() """Initialize this class.""" #super().__init__() # (wg-python-property-variables) self.flexname = flexname self.name = name self.display = display self.wwidth = width self.pangle = float(pangle) self.home = 0 self.read = 0 self.spacer = Spacer(width=self.wwidth, height=5, background='black') self.parallacticangle = Slider(title=f"Parallactic Angle", bar_color='firebrick', value=self.pangle, start=0, end=180, step=0.1, width=self.wwidth) self.readbutton = Button(label="Read", disabled=False, button_type="warning", width=self.wwidth // 2) self.homebutton = Button(label="Home", disabled=False, button_type="danger", width=self.wwidth // 2) self.parallacticangle.on_change( 'value', lambda attr, old, new: self.update_parallacticangle( attr, old, new)) self.readbutton.on_click(lambda: self.update_readbutton()) self.homebutton.on_click(lambda: self.update_homebutton()) ### FlexOrientation.__init__() def update_homebutton(self): # FlexOrientation::update_homebutton() """Update the home command. """ self.home = 1 self.send_state() self.home = 0 ### FlexOrientation.update_homebutton() def update_readbutton(self): # FlexOrientation::update_readbutton() """Update the read command. """ self.read = 1 self.send_state() self.read = 0 ### FlexOrientation.update_readbutton() def debug(self, msg="", skip=[], os=sys.stderr): # FlexOrientation::debug() """Help with momentary debugging, file to fit. msg -- special tag for this call skip -- the member variables to ignore os -- output stream: may be IOStream etc. """ import pprint print("FlexOrientation - %s " % msg, file=os) for key, value in self.__dict__.items(): if (key in skip): continue print(f'{key:20s} =', file=os, end='') pprint.pprint(value, stream=os, indent=4) return self ### FlexOrientation.debug() def update_parallacticangle( self, attr, old, new): # FlexOrientation::update_parallacticangle() """Update the parallactic angle. Disabled in interface""" self.pangle = new ### FlexOrientation.update_parallacticangle() def ExtProcess(self, newvalue): # FlexOrientation::ExtProcess() """Process JSON string to update the display. Called from external process.""" self.parallacticangle.value = float(new) self.display.display(newvalue) ### FlexOrientation.ExtProcess() def send_state(self): # ParallacticAngle::send_state() """Several ways to send things """ devstate = dict([("read", self.read), ("home", self.home), ("pangle", self.pangle)]) slitcmd = dict([("Process", devstate), ("Receipt", 0)]) slitcmd['Receipt'] = 1 # set the receipt as desired d2 = dict([(f"{self.name}", slitcmd)]) d3 = dict([(f"{self.flexname}", d2)]) jdict = json.dumps(d3) self.display.display(f'{jdict}') ### ParallacticAngle.send_state() def layout(self): # FlexOrientation::layout() """Create the layout""" return (row( column(self.parallacticangle, row(self.homebutton, self.readbutton))))
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 """ socket = context.socket(zmq.REQ) socket.connect("tcp://%s:%d" % (self.master_server, self.master_port)) # 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=self.plot_width, 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=int(self.plot_width / 2.)).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=int(self.plot_width / 2), finalize_hooks=[apply_formatter], xrotation=45).redim.label(time='Time in UTC') layout = (hvIpmAmp + hvCorrTimeHistory + hvTimeTool).cols(2) hvplot = renderer.get_plot(layout) def request_data_timetool(buffer): """ Push data to timetool time history graph """ socket.send_string("Request_%s" % self.plotName.replace(' ', '_')) nowStr = time.strftime("%b %d %Y %H:%M:%S", time.localtime()) print("Timetool requested data at %s, plot %g seconds " % (nowStr, time.time() - self.plotStartTime)) data_dict = socket.recv_pyobj() timetool_d = deque(maxlen=self.number_of_events) timetool_t = deque(maxlen=self.number_of_events) timetool_d = data_dict['tt__FLTPOS_PS'] # Get time from data_dict timeData = deque(maxlen=self.number_of_events) 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 request_data_amp_ipm(buffer): """ Push data into timetool amp vs ipm graph """ socket.send_string("Request_%s" % self.plotName.replace(' ', '_')) nowStr = time.strftime("%b %d %Y %H:%M:%S", time.localtime()) print("Timetool ampl-ipm requested data at %s, plot %g seconds " % (nowStr, time.time() - self.plotStartTime)) data_dict = socket.recv_pyobj() timetool_d = deque(maxlen=self.number_of_events) ipm_d = deque(maxlen=self.number_of_events) timetool_d = data_dict['tt__AMPL'] ipm_d = data_dict[self.i0var] data = pd.DataFrame({'timetool': timetool_d, 'ipm': ipm_d}) buffer.send(data) def request_data_corr_time_history(buffer): """ Calculate correlation between timetool amp and ipm and push to correlation time history graph """ socket.send_string("Request_%s" % self.plotName.replace(' ', '_')) nowStr = time.strftime("%b %d %Y %H:%M:%S", time.localtime()) print("Timetool corr_time requested data at %s, plot %g seconds " % (nowStr, time.time() - self.plotStartTime)) data_dict = socket.recv_pyobj() timetool_d = deque(maxlen=self.number_of_events) timetool_t = deque(maxlen=self.number_of_events) ipm_d = deque(maxlen=self.number_of_events) timetool_d = data_dict['tt__FLTPOS_PS'] ipm_d = data_dict[self.i0var] # Get time from data_dict timeData = deque(maxlen=self.number_of_events) 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 stop(): """ Add pause and play functionality to graph """ if stopButton.label == 'Play': stopButton.label = 'Pause' self.cb_id_timetool = doc.add_periodic_callback( partial(request_data_timetool, buffer=self.b_timetool), 1000) self.cb_id_amp_ipm = doc.add_periodic_callback( partial(request_data_amp_ipm, buffer=self.b_IpmAmp), 1000) self.cb_id_corr_timehistory = doc.add_periodic_callback( partial(requeset_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) stopButton = Button(label='Pause') stopButton.on_click(stop) plot = column(stopButton, hvplot.state) doc.add_root(plot)
def callback_add_number_2(): global y # BEST PRACTICE --- update .data in one step with a new dict new_data = dict() new_data['x'] = ds2.data['x'] + [random() * 70 + 100] new_data['y'] = ds2.data['y'] + [random() * 70 + 100] new_data['text_color'] = ds2.data['text_color'] + [RdYlBu3[y % 3]] new_data['text'] = ds2.data['text'] + [str(y)] ds2.data = new_data y += 1 # add a btn_press_1 widget and configure with the call back btn_press_1 = Button(label="Press Me") btn_press_1.on_click(callback_add_number_1) # add a btn_press_2 widget and configure with the call back btn_press_2 = Button(label="Press Me too!") btn_press_2.on_click(callback_add_number_2) document = curdoc() # put the btn_press_1 and plot in a layout and add to the document document.add_root(row(column(btn_press_1, p1), column(btn_press_2, p2))) document.add_root( row(column(inputs, plot, width=400, height=500, css_classes=["plot_demo"])))
def produce_correlation_graphs(doc, diode_t_dict, diode_dict): """ Produce correlation graphs and push them onto the web page document. Parameters ---------- doc: bokeh.document (I think) Bokeh document to be displayed on webpage diode_t_dict: dictionary diciontary with deques containing timestamps of the diode readings diode_dict: dictionary dictionary with deques containing diode readins """ # Initialize formatting variables buffer_length = 40000 width = 500 # Initialize Streams b_dcc_dco = Buffer(pd.DataFrame({ 'x_diode': [], 'y_diode': [] }), length=buffer_length) b_t4d_dd = Buffer(pd.DataFrame({ 'x_diode': [], 'y_diode': [] }), length=buffer_length) b_do_di = Buffer(pd.DataFrame({ 'x_diode': [], 'y_diode': [] }), length=buffer_length) b_t4d_dco = Buffer(pd.DataFrame({ 'x_diode': [], 'y_diode': [] }), length=buffer_length) # Initialize dynamic maps hvPoint_dcc_dco = hv.DynamicMap( partial(hv.Scatter, kdims=['x_diode', 'y_diode'], group='DCC vs DCO'), streams=[b_dcc_dco]).options(width=width).redim.label(x_diode='DCC', y_diode='DCO') hvPoint_t4d_dd = hv.DynamicMap( partial(hv.Scatter, kdims=['x_diode', 'y_diode'], group='T4D vs DD'), streams=[b_t4d_dd]).options(width=width).redim.label(x_diode='T4D', y_diode='DD') hvPoint_do_di = hv.DynamicMap( partial(hv.Scatter, kdims=['x_diode', 'y_diode'], group='DO vs DI'), streams=[b_do_di]).options(width=width).redim.label(x_diode='DO', y_diode='DI') hvPoint_t4d_dco = hv.DynamicMap( partial(hv.Scatter, kdims=['x_diode', 'y_diode'], group='T4D vs DCO'), streams=[b_t4d_dco]).options(width=width).redim.label(x_diode='T4D', y_diode='DCO') #plots_col = (hvPoint_dcc_dco + hvPoint_t4d_dco + hvPoint_do_di + hvPoint_t4d_dd).cols(2) # Render plot with bokeh hvplot = renderer.get_plot(plots_col, doc) # Initialize callbacks cb_id_dcc_dco = None cb_id_t4d_dd = None cb_id_do_di = None cb_id_t4d_dco = None # Push data into buffers def push_data(x_diode, y_diode, x_diode_t, y_diode_t, buffer): """ Push data from x and y diode into buffer to be graphed. """ x_diode_data = pd.Series(x_diode, index=x_diode_t) y_diode_data = pd.Series(y_diode, index=y_diode_t) zipped = basic_event_builder(x_diode=x_diode_data, y_diode=y_diode_data) buffer.send(zipped) # def play_graph(): """ Provide play and pause functionality to the graph """ nonlocal cb_id_dcc_dco, cb_id_t4d_dd, cb_id_do_di, cb_id_t4d_dco cb_time = 1000 if startButton.label == '► Play': startButton.label = '❚❚ Pause' cb_id_dcc_dco = doc.add_periodic_callback( partial(push_data, x_diode=diode_dict['dcc_d'], y_diode=diode_dict['dco_d'], x_diode_t=diode_t_dict['dcc_t'], y_diode_t=diode_t_dict['dco_t'], buffer=b_dcc_dco), cb_time) cb_id_t4d_dd = doc.add_periodic_callback( partial(push_data, x_diode=diode_dict['t4d_d'], y_diode=diode_dict['dd_d'], x_diode_t=diode_t_dict['t4d_t'], y_diode_t=diode_t_dict['dd_t'], buffer=b_t4d_dd), cb_time) cb_id_do_di = doc.add_periodic_callback( partial(push_data, x_diode=diode_dict['do_d'], y_diode=diode_dict['di_d'], x_diode_t=diode_t_dict['do_t'], y_diode_t=diode_t_dict['di_t'], buffer=b_do_di), cb_time) cb_id_t4d_dco = doc.add_periodic_callback( partial(push_data, x_diode=diode_dict['t4d_d'], y_diode=diode_dict['dco_d'], x_diode_t=diode_t_dict['t4d_t'], y_diode_t=diode_t_dict['dco_t'], buffer=b_t4d_dco), cb_time) else: startButton.label = '► Play' doc.remove_periodic_callback(cb_id_dcc_dco) doc.remove_periodic_callback(cb_id_t4d_dd) doc.remove_periodic_callback(cb_id_do_di) doc.remove_periodic_callback(cb_id_t4d_dco) # Create widgets startButton = Button(label='► Play') startButton.on_click(play_graph) plot = layout([startButton, row([hvplot.state])]) doc.title = "Correlation Graphs" doc.add_root(plot)
def produce_curve(doc, diode_t_dict, diode_dict): """ Produce time history graphs and push them onto the web page document. Parameters ---------- doc: bokeh.document (I think) Bokeh document to be displayed on webpage diode_t_dict: dictionary diciontary with deques containing timestamps of the diode readings diode_dict: dictionary dictionary with deques containing diode readings """ # Initialize formatting variables buffer_length = 40000 width = 500 xrotation = 45 transparent_line_value = 0.1 # Initialize streams buffer_dcc = Buffer(pd.DataFrame({'diode': []}), length=buffer_length) buffer_dci = Buffer(pd.DataFrame({'diode': []}), length=buffer_length) buffer_dco = Buffer(pd.DataFrame({'diode': []}), length=buffer_length) buffer_dd = Buffer(pd.DataFrame({'diode': []}), length=buffer_length) buffer_di = Buffer(pd.DataFrame({'diode': []}), length=buffer_length) buffer_do = Buffer(pd.DataFrame({'diode': []}), length=buffer_length) buffer_t1d = Buffer(pd.DataFrame({'diode': []}), length=buffer_length) buffer_t4d = Buffer(pd.DataFrame({'diode': []}), length=buffer_length) b_dcc_std = Buffer(pd.DataFrame({ 'lowerbound': [], 'higherbound': [] }), length=buffer_length) b_dci_std = Buffer(pd.DataFrame({ 'lowerbound': [], 'higherbound': [] }), length=buffer_length) b_dco_std = Buffer(pd.DataFrame({ 'lowerbound': [], 'higherbound': [] }), length=buffer_length) b_dd_std = Buffer(pd.DataFrame({ 'lowerbound': [], 'higherbound': [] }), length=buffer_length) b_di_std = Buffer(pd.DataFrame({ 'lowerbound': [], 'higherbound': [] }), length=buffer_length) b_do_std = Buffer(pd.DataFrame({ 'lowerbound': [], 'higherbound': [] }), length=buffer_length) b_t1d_std = Buffer(pd.DataFrame({ 'lowerbound': [], 'higherbound': [] }), length=buffer_length) b_t4d_std = Buffer(pd.DataFrame({ 'lowerbound': [], 'higherbound': [] }), length=buffer_length) # Weird bug where if you leave the beginning of the Curve graph in buffer zone, # there will be lines connecting to beginning # Generate dynamic map for medians hvPoint_dcc = hv.DynamicMap(partial(hv.Points, group='Diode', label='DCC'), streams=[buffer_dcc]).options( width=width, finalize_hooks=[apply_formatter], xrotation=xrotation).redim.label( index='Time in UTC', diode='DCC Reading') hvPoint_dci = hv.DynamicMap(partial(hv.Points, group='Diode', label='DCI'), streams=[buffer_dci]).options( width=width, finalize_hooks=[apply_formatter], xrotation=xrotation).redim.label( index='Time in UTC', diode='DCI Reading') hvPoint_dco = hv.DynamicMap(partial(hv.Points, group='Diode', label='DCO'), streams=[buffer_dco]).options( width=width, finalize_hooks=[apply_formatter], xrotation=xrotation).redim.label( index='Time in UTC', diode='DCO Reading') hvPoint_dd = hv.DynamicMap(partial(hv.Points, group='Diode', label='DD'), streams=[buffer_dd]).options( width=width, finalize_hooks=[apply_formatter], xrotation=xrotation).redim.label( index='Time in UTC', diode='DD Reading') hvPoint_di = hv.DynamicMap(partial(hv.Points, group='Diode', label='DI'), streams=[buffer_di]).options( width=width, finalize_hooks=[apply_formatter], xrotation=xrotation).redim.label( index='Time in UTC', diode='DI Reading') hvPoint_do = hv.DynamicMap(partial(hv.Points, group='Diode', label='DO'), streams=[buffer_do]).options( width=width, finalize_hooks=[apply_formatter], xrotation=xrotation).redim.label( index='Time in UTC', diode='DO Reading') hvPoint_t1d = hv.DynamicMap(partial(hv.Points, group='Diode', label='T1D'), streams=[buffer_t1d]).options( width=width, finalize_hooks=[apply_formatter], xrotation=xrotation).redim.label( index='Time in UTC', diode='T1D Reading') hvPoint_t4d = hv.DynamicMap(partial(hv.Points, group='Diode', label='T4D'), streams=[buffer_t4d]).options( width=width, finalize_hooks=[apply_formatter], xrotation=xrotation).redim.label( index='Time in UTC', diode='T4D Reading') # Same bug with weird connecting lines, but doesn't happen for std Curve graphs (happens for Area graphs) # Generate dynamic map for standard deviation hvStd_dcc_low = hv.DynamicMap( partial(hv.Curve, kdims=['index', 'lowerbound']), streams=[b_dcc_std ]).options(width=width, line_alpha=transparent_line_value, line_color='red').redim.label(index='Time in UTC') hvStd_dcc_high = hv.DynamicMap( partial(hv.Curve, kdims=['index', 'higherbound']), streams=[b_dcc_std ]).options(width=width, line_alpha=transparent_line_value, line_color='red').redim.label(index='Time in UTC') hvStd_dci_low = hv.DynamicMap( partial(hv.Curve, kdims=['index', 'lowerbound']), streams=[b_dci_std ]).options(width=width, line_alpha=transparent_line_value, line_color='red').redim.label(index='Time in UTC') hvStd_dci_high = hv.DynamicMap( partial(hv.Curve, kdims=['index', 'higherbound']), streams=[b_dci_std ]).options(width=width, line_alpha=transparent_line_value, line_color='red').redim.label(index='Time in UTC') hvStd_dco_low = hv.DynamicMap( partial(hv.Curve, kdims=['index', 'lowerbound']), streams=[b_dco_std ]).options(width=width, line_alpha=transparent_line_value, line_color='red').redim.label(index='Time in UTC') hvStd_dco_high = hv.DynamicMap( partial(hv.Curve, kdims=['index', 'higherbound']), streams=[b_dco_std ]).options(width=width, line_alpha=transparent_line_value, line_color='red').redim.label(index='Time in UTC') hvStd_dd_low = hv.DynamicMap( partial(hv.Curve, kdims=['index', 'lowerbound']), streams=[b_dd_std ]).options(width=width, line_alpha=transparent_line_value, line_color='red').redim.label(index='Time in UTC') hvStd_dd_high = hv.DynamicMap( partial(hv.Curve, kdims=['index', 'higherbound']), streams=[b_dd_std ]).options(width=width, line_alpha=transparent_line_value, line_color='red').redim.label(index='Time in UTC') hvStd_di_low = hv.DynamicMap( partial(hv.Curve, kdims=['index', 'lowerbound']), streams=[b_di_std ]).options(width=width, line_alpha=transparent_line_value, line_color='red').redim.label(index='Time in UTC') hvStd_di_high = hv.DynamicMap( partial(hv.Curve, kdims=['index', 'higherbound']), streams=[b_di_std ]).options(width=width, line_alpha=transparent_line_value, line_color='red').redim.label(index='Time in UTC') hvStd_do_low = hv.DynamicMap( partial(hv.Curve, kdims=['index', 'lowerbound']), streams=[b_do_std ]).options(width=width, line_alpha=transparent_line_value, line_color='red').redim.label(index='Time in UTC') hvStd_do_high = hv.DynamicMap( partial(hv.Curve, kdims=['index', 'higherbound']), streams=[b_do_std ]).options(width=width, line_alpha=transparent_line_value, line_color='red').redim.label(index='Time in UTC') hvStd_t1d_low = hv.DynamicMap( partial(hv.Curve, kdims=['index', 'lowerbound']), streams=[b_t1d_std ]).options(width=width, line_alpha=transparent_line_value, line_color='red').redim.label(index='Time in UTC') hvStd_t1d_high = hv.DynamicMap( partial(hv.Curve, kdims=['index', 'higherbound']), streams=[b_t1d_std ]).options(width=width, line_alpha=transparent_line_value, line_color='red').redim.label(index='Time in UTC') hvStd_t4d_low = hv.DynamicMap( partial(hv.Curve, kdims=['index', 'lowerbound']), streams=[b_t4d_std ]).options(width=width, line_alpha=transparent_line_value, line_color='red').redim.label(index='Time in UTC') hvStd_t4d_high = hv.DynamicMap( partial(hv.Curve, kdims=['index', 'higherbound']), streams=[b_t4d_std ]).options(width=width, line_alpha=transparent_line_value, line_color='red').redim.label(index='Time in UTC') # Ideally, we would have wanted to plot the standard deviations as an area curve # I didn't do it beceause there's a bug, but this would theoretically be the code # to make a dynamic map with hv.Area # hvArea = hv.DynamicMap(partial( # hv.Area, vdims=['lowerbound', 'higherbound']), streams=[buffer_std_test]).options( # width=1000).redim.label(index='Time in UTC') # Put plots into two columns in layout plots = (hvPoint_dcc * hvStd_dcc_low * hvStd_dcc_high + hvPoint_dci * hvStd_dci_low * hvStd_dci_high + hvPoint_dco * hvStd_dco_low * hvStd_dco_high + hvPoint_dd * hvStd_dd_low * hvStd_dd_high + hvPoint_di * hvStd_di_low * hvStd_di_high + hvPoint_do * hvStd_do_low * hvStd_do_high + hvPoint_t1d * hvStd_t1d_low * hvStd_t1d_high + hvPoint_t4d * hvStd_t4d_low * hvStd_t4d_high).cols(2) # Use bokeh to render the plot hvplot = renderer.get_plot(plots, doc) # Initialize callbacks cb_id_dcc = None cb_id_dci = None cb_id_dco = None cb_id_dd = None cb_id_di = None cb_id_do = None cb_id_t1d = None cb_id_t4d = None cb_id_dcc_std = None cb_id_dci_std = None cb_id_dco_std = None cb_id_dd_std = None cb_id_di_std = None cb_id_do_std = None cb_id_t1d_std = None cb_id_t4d_std = None def push_data_median(diode_t, diode, buffer): """ Push rolling median of diode readings and push resulting list into buffer to be graphed. """ timeStuff = list(diode_t) # Convert time to seconds so bokeh formatter can get correct datetime times = [1000 * time for time in timeStuff] diodeData = pd.Series(diode, index=times) zipped = basic_event_builder(diode=diodeData) median = zipped.rolling(120, min_periods=1).median() # Exclude first 119 points because of binning issues and sparsing the data (Doesn't seem to really work though) buffer.send(median[119::2]) zipped.to_csv('testData2.csv') def push_data_std(diode_t, diode, buffer): """ Calculate rolling standard deviation of diode readings. Generate lists containing values one standard deviation away from the median (lower and higher) and push resulting list into buffer to be graphed. """ timeStuff = list(diode_t) times = [ 1000 * time for time in timeStuff ] # Convert time to seconds so bokeh formatter can get correct datetime diodeData = pd.Series(diode, index=times) zipped = basic_event_builder(diode=diodeData) median = zipped.rolling(120, min_periods=1).median() std = zipped.rolling(120, min_periods=1).std() lowerbound = median - std higherbound = median + std df = pd.DataFrame({ 'lowerbound': lowerbound['diode'], 'higherbound': higherbound['diode'] }) buffer.send(df[119::2]) def play_graph(): """ Provide play and pause functionality to the graph """ nonlocal cb_id_dcc, cb_id_dci, cb_id_dco, cb_id_dd, cb_id_di, cb_id_do, cb_id_t1d, cb_id_t4d nonlocal cb_id_dcc_std, cb_id_dci_std, cb_id_dco_std, cb_id_dd_std nonlocal cb_id_di_std, cb_id_do_std, cb_id_t1d_std, cb_id_t4d_std if startButton.label == '► Play': startButton.label = '❚❚ Pause' cb_time = 3000 # Callbacks for median lines cb_id_dcc = doc.add_periodic_callback( partial(push_data_median, diode_t=diode_t_dict['dcc_t'], diode=diode_dict['dcc_d'], buffer=buffer_dcc), cb_time) cb_id_dci = doc.add_periodic_callback( partial(push_data_median, diode_t=diode_t_dict['dci_t'], diode=diode_dict['dci_d'], buffer=buffer_dci), cb_time) cb_id_dco = doc.add_periodic_callback( partial(push_data_median, diode_t=diode_t_dict['dco_t'], diode=diode_dict['dco_d'], buffer=buffer_dco), cb_time) cb_id_dd = doc.add_periodic_callback( partial(push_data_median, diode_t=diode_t_dict['dd_t'], diode=diode_dict['dd_d'], buffer=buffer_dd), cb_time) cb_id_di = doc.add_periodic_callback( partial(push_data_median, diode_t=diode_t_dict['di_t'], diode=diode_dict['di_d'], buffer=buffer_di), cb_time) cb_id_do = doc.add_periodic_callback( partial(push_data_median, diode_t=diode_t_dict['do_t'], diode=diode_dict['do_d'], buffer=buffer_do), cb_time) cb_id_t1d = doc.add_periodic_callback( partial(push_data_median, diode_t=diode_t_dict['t1d_t'], diode=diode_dict['t1d_d'], buffer=buffer_t1d), cb_time) cb_id_t4d = doc.add_periodic_callback( partial(push_data_median, diode_t=diode_t_dict['t4d_t'], diode=diode_dict['t4d_d'], buffer=buffer_t4d), cb_time) # Callbacks for std lines cb_id_dcc_std = doc.add_periodic_callback( partial(push_data_std, diode_t=diode_t_dict['dcc_t'], diode=diode_dict['dcc_d'], buffer=b_dcc_std), cb_time) cb_id_dci_std = doc.add_periodic_callback( partial(push_data_std, diode_t=diode_t_dict['dci_t'], diode=diode_dict['dci_d'], buffer=b_dci_std), cb_time) cb_id_dco_std = doc.add_periodic_callback( partial(push_data_std, diode_t=diode_t_dict['dco_t'], diode=diode_dict['dco_d'], buffer=b_dco_std), cb_time) cb_id_dd_std = doc.add_periodic_callback( partial(push_data_std, diode_t=diode_t_dict['dd_t'], diode=diode_dict['dd_d'], buffer=b_dd_std), cb_time) cb_id_di_std = doc.add_periodic_callback( partial(push_data_std, diode_t=diode_t_dict['di_t'], diode=diode_dict['di_d'], buffer=b_di_std), cb_time) cb_id_do_std = doc.add_periodic_callback( partial(push_data_std, diode_t=diode_t_dict['do_t'], diode=diode_dict['do_d'], buffer=b_do_std), cb_time) cb_id_t1d_std = doc.add_periodic_callback( partial(push_data_std, diode_t=diode_t_dict['t1d_t'], diode=diode_dict['t1d_d'], buffer=b_t1d_std), cb_time) cb_id_t4d_std = doc.add_periodic_callback( partial(push_data_std, diode_t=diode_t_dict['t4d_t'], diode=diode_dict['t4d_d'], buffer=b_t4d_std), cb_time) else: startButton.label = '► Play' doc.remove_periodic_callback(cb_id_dcc) doc.remove_periodic_callback(cb_id_dci) doc.remove_periodic_callback(cb_id_dco) doc.remove_periodic_callback(cb_id_dd) doc.remove_periodic_callback(cb_id_di) doc.remove_periodic_callback(cb_id_do) doc.remove_periodic_callback(cb_id_t1d) doc.remove_periodic_callback(cb_id_t4d) doc.remove_periodic_callback(cb_id_dcc_std) doc.remove_periodic_callback(cb_id_dci_std) doc.remove_periodic_callback(cb_id_dco_std) doc.remove_periodic_callback(cb_id_dd_std) doc.remove_periodic_callback(cb_id_di_std) doc.remove_periodic_callback(cb_id_do_std) doc.remove_periodic_callback(cb_id_t1d_std) doc.remove_periodic_callback(cb_id_t4d_std) # Create widgets startButton = Button(label='► Play') startButton.on_click(play_graph) plot = layout([startButton, hvplot.state]) doc.title = "Time History" doc.add_root(plot)
# 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, duration1, duration2, transition1, transition2, beta1, beta2, beta3, drate ]: w.on_change('value_throttled', update_data) # reset button call back button.on_click(reset_data) # initial plot x = np.linspace(1, DAYS, DAYS) y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, y11, ar_stats = get_data( x, population.value, iinfections.value, period.value, period_stdev.value, latent.value, duration1.value, duration2.value, transition1.value, transition2.value, beta1.value, beta2.value, beta3.value, DAYS, drate.value, True) # Active, New, Recovered, Dead, Rt, % Immunine source_active = ColumnDataSource(data=dict(x=x, y=y1)) source_new = ColumnDataSource(data=dict(x=x, y=y2)) source_rec = ColumnDataSource(data=dict(x=x, y=y3)) source_dead = ColumnDataSource(data=dict(x=x, y=y4)) source_rt = ColumnDataSource(data=dict(x=x, y=y5))
title="Clean task parameters:", width=config_main['plot_config']['tab_ToClean']['input_tCLN_wdth']) tab2_Div_tCLN = Div( text='', width=config_main['plot_config']['tab_ToClean']['tab2_Div_tCLN_wdth']) tab2_Div_tCLN2 = Div( text='', width=config_main['plot_config']['tab_ToClean']['input_tCLN_wdth']) tab2_BUT_tCLN_param_default() tab2_BUT_tCLN_param_ADD = Button( label='Add to Param', width=config_main['plot_config']['tab_ToClean']['button_wdth'], button_type='primary') tab2_BUT_tCLN_param_ADD.on_click(tab2_BUT_tCLN_param_add) tab2_BUT_tCLN_param_DEL = Button( label='Delete Param', width=config_main['plot_config']['tab_ToClean']['button_wdth'], button_type='warning') tab2_BUT_tCLN_param_DEL.on_click(tab2_BUT_tCLN_param_delete) tab2_BUT_tCLN_param_Default = Button( label='Default Param', width=config_main['plot_config']['tab_ToClean']['button_wdth']) tab2_BUT_tCLN_param_Default.on_click(tab2_BUT_tCLN_param_default) tab2_SPCR_LFT_BUT_tCLN_param_DEL = Spacer( width=config_main['plot_config']['tab_ToClean']['space_wdth10']) tab2_SPCR_LFT_BUT_tCLN_param_RELOAD = Spacer( width=config_main['plot_config']['tab_ToClean']['space_wdth10']) tab2_SPCR_LFT_BUT_tCLN_param_SAVE = Spacer( width=config_main['plot_config']['tab_ToClean']['space_wdth10'])
class HyperloopClusteringServer: def __init__(self): self.MODULE = "{} v{}".format(__library__, __version__) self._logger("INIT " + self.MODULE) pd.options.display.float_format = '{:,.3f}'.format pd.set_option('expand_frame_repr', False) self.FULL_DEBUG = False self.s_prefix = dt.strftime(dt.now(), '%Y%m%d') self.s_prefix += "_" self.s_prefix += dt.strftime(dt.now(), '%H%M') self.s_prefix += "_" self.save_folder = "saved_data/" self.base_tree_file = "_tree.png" self.tree_file = "" self.current_X = 'N/A' self.current_Y = 'N/A' self.default_cluster_view = "F1/F2" self.nr_shown_records = 10 self.ClusterDescription = '' self.text_ClusterDesc = None self.cds_select = None self.dot_alpha = 0.5 self.dot_size = 4 self.nr_downsample = 1000 self.TableViewText = None self.nr_inits = 30 self.cds = None self._logger(self.s_prefix) self._logger("__name__: {}".format(__name__)) self._logger("__file__: {}".format(__file__)) self.current_cluster_glph_renderer = None self.initialize_data() self.initialize_layout() return def upper_config_str(self, mydict): newdict = dict() for k, v in mydict.items(): newdict[k.upper()] = v return newdict def _logger(self, logstr, show=True): if not hasattr(self, 'log'): self.log = list() nowtime = dt.now() strnowtime = nowtime.strftime( "[{}][%Y-%m-%d %H:%M:%S] ".format(__lib__)) logstr = strnowtime + logstr self.log.append(logstr) if show: print(logstr, flush=True) return def ClusterDownSampler(self, source_df, label_field, cluster_fields, nr_samples): if self.DownSample: t0 = tm.time() self._logger("DOWNSAMPLING ...") labels = list(source_df[label_field].unique()) if label_field in cluster_fields: cluster_fields.remove(label_field) all_fields = list(cluster_fields) all_fields.append(label_field) downsampled = pd.DataFrame() for label in labels: cluster_df = pd.DataFrame( source_df[source_df[label_field] == label]) if cluster_df.shape[0] > nr_samples: nr_cl = nr_samples else: nr_cl = cluster_df.shape[0] self._logger("Downsampling {} in {} points".format( label, nr_samples)) clf = KMeans(n_clusters=nr_cl, n_jobs=-1, n_init=5) clf.fit(np.array(cluster_df[cluster_fields])) cluster_df['DownCluster'] = clf.labels_ down_df = pd.DataFrame() i = 0 for fld in cluster_fields: down_df[fld] = clf.cluster_centers_[:, i] i += 1 down_df[label_field] = label self._logger("Downsampled data {}\n{}".format( down_df.shape, down_df.head(3))) downsampled = downsampled.append(down_df) t1 = tm.time() self._logger('Done in {:.1f}s downsampling {}\n{}'.format( t1 - t0, downsampled.shape, downsampled.head(3))) df_result = downsampled else: self._logger("NO DOWNSAMPLE !!!") df_result = source_df return df_result def UploadCluster(self, df, cluster_dict): clRep = ClusterRepository() clRep.UploadCluster(df, cluster_dict, self.sql) return def _upload_cluster(self, sClusterName, sClusterObs, sClusterGrade, nCentroidNo, nCustomerNo, sClusterAuthor, sClusterAlgorithm, sF1_Obs, sF2_Obs, sF3_Obs, sF4_Obs, sF5_Obs, df_cluster, df_desc): cConfig = self.cluster_config clRep = ClusterRepository() clRep.UploadClusterDetail(sClusterName, sClusterObs, sClusterGrade, nCentroidNo, nCustomerNo, sClusterAuthor, sClusterAlgorithm, sF1_Obs, sF2_Obs, sF3_Obs, sF4_Obs, sF5_Obs, df_cluster, df_desc, cConfig, self.sql) return def _loadconfig(self, config_file="cluster_config.txt"): self._logger("Loading config '{}'...".format(config_file)) cfg_file = open(config_file) self.config_data = json.load(cfg_file) if self.FULL_DEBUG: self._logger(self.config_data) self.cluster_config_list = list() for cluster_key in self.config_data.keys(): cluster_def = self.config_data[cluster_key] cluster_fields = cluster_def["Fields"] cluster_ID = cluster_def["ID"] cluster_name = cluster_def["Name"] if self.FULL_DEBUG: self._logger( "Loading definition for cluster: {}".format(cluster_key)) self._logger(" ID: {} / Name: {} / Fields: {}".format( cluster_ID, cluster_name, cluster_fields)) cluster_def["DATA"] = None self.cluster_config_list.append(cluster_def) return def _setup_fields(self, cluster_dict): self.cID = cluster_dict["ID"] #'PartnerId' #'CustID' self.cf = list() for i in range(5): if cluster_dict["Fields"][i] != '': self.cf.append(cluster_dict["Fields"][i]) #self.cf1 = cluster_dict["Fields"][0] #'RecencyScore' #R #self.cf2 = cluster_dict["Fields"][1] #'NrTransactions' #F #self.cf3 = cluster_dict["Fields"][2] # 'TotalAmount' #'TotalValue' #M self.nr_fields = len(self.cf) if self.nr_fields == 3: self.scale_cf = [1, 2] #[0,1,2] #log-scale fields by nr else: self.scale_cf = [0, 1] self.cfc = 'Segment' # cluster label column self.AssignmentID = "CentroidID" if "SEGMENTS" in cluster_dict.keys(): self.nr_clusters = int(cluster_dict["SEGMENTS"]) self._logger("Starting with {} clusters".format(self.nr_clusters)) else: self.nr_clusters = 4 self._logger("Defaulting to {} clusters".format(self.nr_clusters)) self.nr_tree_lvl = 3 self.hover_fields = dict() self.hover_fields['Tranzactii (avg)'] = "TranCount" self.hover_fields['Valoare totala (avg)'] = "TotalAmount" self.scaling_method = 'MinMax' self.refresh_tooltips(self.hover_fields) return def _load_db_cluster(self, strqry): df_temp = self.sql.Select(strqry) self.df_rfm = pd.DataFrame(df_temp[df_temp[self.cID] != -1]) self._logger("Loaded dataset {} rows with head(3) \n{}".format( self.df_rfm.shape[0], self.df_rfm.head(3))) self.origin_fields = list() self.cluster_fields = list() for i in range(len(self.cf)): if self.cf[i] != '': self.origin_fields.append(self.cf[i]) self.cluster_fields.append('F' + str(i + 1)) return def LoadDBClusterByID(self, sID): self._logger("Loading cluster by ID: {}".format(sID)) strqry = self.config_data[sID]["SQL"] self.cluster_config = self.config_data[sID] self.FastSave = False self.DownSample = True if "DOWNSAMPLE" in self.cluster_config.keys(): self.DownSample = int(self.cluster_config["DOWNSAMPLE"]) if not self.DownSample: self._logger("DOWNSAMPLING DISABLED !") if "FASTSAVE" in self.cluster_config.keys(): self.FastSave = int(self.cluster_config["FASTSAVE"]) if self.FastSave: self._logger("FASTSAVE ENABLED !") self._setup_fields(self.cluster_config) self._load_db_cluster(strqry) return def LoadDBClusterByName(self, sName): strqry = None cluster_dict = None for i in range(len(self.cluster_config_list)): if sName == self.cluster_config_list[i]["Name"]: strqry = self.cluster_config_list[i]["SQL"] cluster_dict = self.cluster_config_list[i] if strqry != None: self.cluster_config = cluster_dict self._logger("Loading cluster by Name: {}".format(sName)) self._setup_fields(self.cluster_config) self._load_db_cluster(strqry) else: self._logger("\nERROR LOADING CLUSTER CONFIGURATION FILE\n") return def refresh_tooltips(self, dict_tooltips): self.hover_fields = dict_tooltips self.tooltip1 = list(self.hover_fields.keys())[0] self.tooltip2 = list(self.hover_fields.keys())[1] self.tip1_fld = self.hover_fields[self.tooltip1] self.tip2_fld = self.hover_fields[self.tooltip2] return def refresh_cds(self, cluster=False, x_col=None, y_col=None): self._logger("Refreshing ColumnDataSource ...") df_downsamp = self.df_downrfm if x_col != None and y_col != None: if self.FULL_DEBUG: self._logger("Old X: {} Y: {} / New X: {} Y: {}".format( self.current_X, self.current_Y, x_col, y_col)) self.current_X = x_col self.current_Y = y_col if cluster and (x_col == None and y_col == None): if self.FULL_DEBUG: self._logger(" refreshing labels field '{}' only".format( self.cfc)) self.cds.data[self.cfc] = np.array(df_downsamp[self.cfc]) else: data_dict = dict(X=np.array(df_downsamp[self.current_X]), Y=np.array(df_downsamp[self.current_Y])) data_dict[self.cfc] = np.array(df_downsamp[self.cfc]) if False: data_dict[self.tip1_fld] = np.array(self.df_rfm[self.tip1_fld]) data_dict[self.tip2_fld] = np.array(self.df_rfm[self.tip2_fld]) data_dict[self.cID] = np.array(self.df_rfm[self.cID]) if self.FULL_DEBUG: self._logger(" refreshing full cds: {}".format( list(data_dict.keys()))) if self.cds == None: self.cds = ColumnDataSource(data_dict) else: self.cds.data = data_dict if self.FULL_DEBUG: self._logger("Done refreshing ColumnDataSource.") return def analyze_segments(self): self.segment_id_fld = "Cluster" self.segment_samples_fld = "Clienti" self.segment_value_fld = "Scor" self.segment_name_fld = self.cfc # default always self.df_clusters = pd.DataFrame() cluster_norm = np.zeros(self.nr_clusters) cluster_vals = np.zeros(self.nr_clusters) for i in range(self.nr_clusters): cluster_norm[i] = np.mean(self.cluster_centers[i, :]) if self.FULL_DEBUG: self._logger(" cluster {} vals {}".format( i, (self.df_rfm[self.cfc] == i).head(3))) cluster_vals[i] = (self.df_rfm[self.cfc] == i).sum() self.df_clusters[self.segment_id_fld] = np.arange( 0, self.nr_clusters, 1) self.df_clusters[self.segment_value_fld] = cluster_norm self.df_clusters[self.segment_samples_fld] = cluster_vals self.df_clusters.sort_values(by=self.segment_value_fld, ascending=False, inplace=True) self.df_clusters = self.df_clusters.reset_index() clfields = [ self.segment_id_fld, self.segment_value_fld, self.segment_samples_fld ] self.df_clusters = self.df_clusters[clfields] lev_2 = ["MOST VALUED CUSTOMERS", "LOWER RANGE CUSTOMERS"] lev_3 = [ "MOST VALUED CUSTOMERS", "AVERAGE CUSTOMERS", "LOWER RANGE CUSTOMERS" ] lev_4 = [ "MOST VALUED CUSTOMERS", "GOOD CUSTOMERS", "AVERAGE CUSTOMERS", "LOWER RANGE CUSTOMERS", "BOTTOM CUSTOMERS", "WORST CUSTOMERS" ] new_ids = list() for i in range(self.nr_clusters): new_ids.append(100 * (i + 1)) if self.nr_clusters == 2: self.levels = lev_2 elif self.nr_clusters == 3: self.levels = lev_3 else: self.levels = list() for i in range(self.nr_clusters): self.levels.append(lev_4[i]) self.df_clusters[self.cfc] = self.levels self.df_clusters['NewID'] = new_ids self._logger("Customer segmentation structure:\n {}".format( self.df_clusters)) self.clusters_dict = dict() for i in range(self.nr_clusters): self.clusters_dict[self.df_clusters.loc[ i, self.segment_id_fld]] = self.df_clusters.loc[i, self.cfc] if self.FULL_DEBUG: self._logger("Cluster dict: {}".format(self.clusters_dict)) self.class_names = list() for i in range(self.nr_clusters): self.class_names.append(self.clusters_dict[i]) if self.FULL_DEBUG: self._logger("Class names: {}".format(self.class_names)) # df_rfm[cfc] must be working #self.df_rfm["TEMP_SEGMENT"] = self.df_rfm[self.cfc].astype(str) #self.df_rfm["TEMP_SEGMENT"] = self.df_rfm["TEMP_SEGMENT"].map(self.map_func) self.df_rfm[self.AssignmentID] = self.df_rfm[self.cfc] self.df_rfm[self.cfc] = self.df_rfm[self.cfc].map(self.map_func) old_clusters_list = self.df_rfm[self.AssignmentID].unique() strDesc = '' for i in range(self.nr_clusters): old_cluster = old_clusters_list[i] pos = self.df_clusters[self.segment_id_fld] == old_cluster new_cluster = self.df_clusters[pos]["NewID"].values[0] sNrClients = str(self.df_clusters[pos]['Clienti'].values[0]) sLabel = self.df_clusters[pos]['Segment'].values[0] strDesc += " " + sNrClients + " clients in segment " + sLabel + "," self._logger('Replacing ClusterID {} with {}'.format( old_cluster, new_cluster)) self.df_rfm[self.AssignmentID].replace(old_cluster, new_cluster, inplace=True) self._logger('Found: {}'.format(strDesc)) self.ClusterDescription = self.cluster_config['Description'] + strDesc if self.text_ClusterDesc != None: self.text_ClusterDesc.value = self.ClusterDescription self._logger("Top and bottom 3:\nTop 3:\n{}\nBottom 3:\n{}\n".format( self.df_rfm.head(3), self.df_rfm.tail(3))) return def map_func(self, val): vvv = int(val) lvl = self.clusters_dict[vvv] return lvl def _deprecated_update_tree_figure(self, s_png): img = mat_Image.imread(s_png) img = (img * 255).astype(np.uint8) N, M, _ = img.shape img = img.view(dtype=np.uint32).reshape( (N, M)) #convert image NxM dtype=uint32 img = img[::-1] self._logger('IMG SHAPE {}'.format(img.shape)) y_rng = 10 xfact = float(M / N) x_rng = int(y_rng * xfact) self._logger("X:{} Y:{}".format(x_rng, y_rng)) # fig = self.tab2_layout.children[1] fig = figure(x_range=(0, x_rng), y_range=(0, y_rng)) # prepare tree display tab fig.plot_width = 900 fig.plot_height = int(fig.plot_width / xfact) # done tree display tab fig.image_rgba(image=[img], x=0, y=0, dw=x_rng, dh=y_rng) self.tab2_layout.children[1] = fig #self.tab2_empty_tree_fig.plot_width = 900 #self.tab2_empty_tree_fig.plot_height = int(900 / xfact) #self.tab2_empty_tree_fig.image_rgba(image=[img], # x=0, y=0, # dw=x_rng, dh=y_rng) self.update_cluster_image(self.current_cluster_view) return img def update_png(self): s_file = self.tree_file self.DivText3.text = self.DivText3.text + " {}".format( self.class_names) self._logger("Update tree view {} ...".format(s_file)) #img = self.update_tree_figure(s_png) image_url = "http://*****:*****@" + self.cfc), ("Client", "@" + self.cID), (tip1, "@" + self.hover_fields[tip1]), (tip2, "@" + self.hover_fields[tip2]), ]) if self.FULL_DEBUG: self._logger(" Tooltips: {}".format(self.hover.tooltips)) self.cluster_figure.add_tools(self.hover) self.update_cluster_image(self.current_cluster_view) self.empty_selection = self.current_cluster_glph_renderer.data_source.selected self.btn_reset = Button(label="Deselectare", width=20) self.btn_reset.on_click(self.on_reset_selection) self.btn_save = Button(label="Salvare", width=50) self.btn_save.on_click(self.on_save) self.btn_save_local = Button(label="Salvare doar local", width=50) self.btn_save_local.on_click(self.on_save_local) columns = list() for col in self.df_rfm.columns: if col == self.cfc: tblcol = TableColumn( field=col, title=col, width=200, formatter=StringFormatter(font_style="bold")) else: tblcol = TableColumn( field=col, title=col, width=50, formatter=NumberFormatter(format="0[.]00")) columns.append(tblcol) self.data_table = DataTable(source=self.cds_select, columns=columns, width=1200, height=500, fit_columns=False) self.cb_select_k = Select(title="Vizualizare segment:", value=self.current_segment, options=self.segments) self.cb_select_k.on_change("value", self.on_view_cluster) self.cb_scaling = Select(title="Metoda de scalare/normalizare:", value="MinMax", options=['MinMax', 'ZScore']) self.cb_scaling.on_change("value", self.on_cb_scaling) self.TableViewText = Div(text="N/A") self.ckbox_transf = CheckboxGroup( labels=["F1 LogTransform", "F2 LogTransform", "F3 LogTransform"], active=self.scale_cf) self.ckbox_transf.on_click(self.on_log_check) self.text_ClusterName = TextInput( value=self.cluster_config['Name'] + " ({} segments)".format(self.nr_clusters), title="Nume model:", width=400) self.cb_ClusterGrade = Select(title="Calitatea output:", value='PRODUCTION', width=300, options=['TESTS', 'PRODUCTION']) self.text_ClusterDesc = TextInput(value=self.ClusterDescription, title="Descriere:", width=700) self.text_Author = TextInput(value='Andrei Ionut Damian', title="Autor:") self.text_Algorithm = TextInput(value=self.sAlgorithm, title="Algoritm:", width=700) self.text_F1 = TextInput(value=self.cluster_config['Fields'][0], title="Descriere camp F1:") self.text_F2 = TextInput(value=self.cluster_config['Fields'][1], title="Descriere camp F2:") self.text_F3 = TextInput(value=self.cluster_config['Fields'][2], title="Descriere camp F3:") ## ## done with the controls ## ## ## now to layout preparation ## self.row_btns = row(self.btn_reset, self.btn_save) self.mytabs = list() # tab1: clusters self.tab1_col1_controls = column(widgetbox(self.slider), widgetbox(self.cb_select_rfm), widgetbox(self.slider_tree), widgetbox(self.cb_scaling), widgetbox(self.ckbox_transf), self.DivText1, self.DivText2, self.btn_reset, self.text_ClusterName, widgetbox(self.cb_ClusterGrade), self.text_Author) self.tab1_col2_controls = column(self.cluster_figure, self.text_ClusterDesc, self.text_Algorithm, self.text_F1, self.text_F2, self.text_F3, self.btn_save, self.btn_save_local) self.tab1_layout = row(self.tab1_col1_controls, self.tab1_col2_controls) self.tab1 = widgets.Panel(child=self.tab1_layout, title='Segmentare') self.mytabs.append(self.tab1) #tab 2 table view self.tab2_controls = row(widgetbox(self.slider_table), widgetbox(self.cb_select_k), self.TableViewText) self.tab2_layout = column(self.tab2_controls, self.data_table) self.tab2 = widgets.Panel(child=self.tab2_layout, title='Vizualizare date') self.mytabs.append(self.tab2) # tab 3 tree view #self.tab3_empty_tree_fig = figure(x_range=(0,40), y_range=(0,10)) self.DivTreeImage = Div(text="") dt3 = "Arborele de decizie al segmentarii clientilor." #dt3+= " 'Value' reprezinta numarul de elemente din clasele {}".format(self.class_names) self.DivText3 = Div(text=dt3, width=1000, height=50) self.tab3_layout = column(self.DivText3, self.DivTreeImage) self.tab3 = widgets.Panel(child=self.tab3_layout, title='Vizualizare arbore') self.mytabs.append(self.tab3) # finalizare layout self.update_png() self.update_texts(self.last_tree_accuracy, self.last_clustering_error) self.final_layout = widgets.Tabs(tabs=self.mytabs) self._logger("!!! DONE LAYOUT PREPARATION.\n") if self.FastSave: self.on_save() self._logger("SHUTTING DOWN ...") os.kill(os.getpid(), 9) return
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))
slide_height, slide_width, slide_thick, slide_desired_temp, calculate_button) selecters = column(location_select, time_select, select_material) sliders = column(slide_length, slide_height, slide_width, slide_thick, slide_desired_temp) #organizing panels of diaply tab2 = Panel(child=column(row(diff_temps, hourly_temps), row(humid, mapp)), title="Climate Data") tab1 = Panel(child=column(row(selecters, sliders), row(g4, g1), calculate_button, data_table), title="Heat Transfer & Essential Temps") tab3 = Panel(child=column(p_ZECC, p_LHV, p_HT, p_Heat, p_dp), title="Information") tabs = Tabs(tabs=[tab1, tab2, tab3]) updates = [ location_select, time_select, select_material, slide_length, slide_height, slide_width, slide_thick, slide_desired_temp ] for u in updates: #when any of the slider values are changed or drop down menu has a new selection, this will then call the update_data function which will then make appropriate adjustments to graphs and table u.on_change('value', update_data) calculate_button.on_click( button_updates ) #calls button_updates function when the calculate button is clicked #generated output curdoc().add_root(tabs) curdoc().title = "Zero Energy Cooling Chamber"
step=1, title='Maximum Age') sex_select = CheckboxButtonGroup(labels=['Male', 'Female'], active=[0, 1]) selectors = Tabs(tabs=[ Panel(child=HBox(category_select), title='Category'), Panel(child=HBox(size_select), title='Group Size'), Panel(child=HBox(age_min_select, age_max_select), title='Age'), Panel(child=sex_select, title='Sex') ]) def callback(): """ Dynamically generate a Kaplan-Meier plot. """ """ df_ = df[age_min_select.value <= df.age] df_ = df_[df_.age <= age_max_select.value] if 0 not in sex_select.active: df_ = df_[df_.sex_as_str != 'male'] if 1 not in sex_select.active: df_ = df_ """ callback() generate = Button(label='Generate') generate.on_click(callback) document = curdoc() document.add_root(vplot(plot, selectors, generate))
stream.event(hour=new) start, end = 0, 23 slider = Slider(start=start, end=end, value=0, step=1, title="Hour") slider.on_change('value', slider_update) callback_id = None def animate(): global callback_id if button.label == '\u25B6 Play': button.label = '\u23F8 Pause' callback_id = curdoc().add_periodic_callback(animate_update, 50) else: button.label = '\u25B6 Play' curdoc().remove_periodic_callback(callback_id) button = Button(label='\u25B6 Play', width=60) button.on_click(animate) # Combine the bokeh plot on plot.state with the widgets layout = layout([ [plot.state], [slider, button], ], sizing_mode='fixed') curdoc().add_root(layout)
add_line_plot(profit_plot, 'date', 'profit', results_dic, color[index], label) add_line_plot(loss_plot, 'date', 'loss', results_dic, color[index], label) index += 1 setup_legend(symbol_win_rate_plot) setup_legend(symbol_gain_plot) setup_legend(total_trades_plot) setup_legend(profit_plot) setup_legend(loss_plot) symbol_layout = layout([symbol_win_rate_plot, symbol_gain_plot, total_trades_plot, profit_plot, loss_plot]) symbol_tab = Panel(child=symbol_layout, title=symbol) symbol_tabs.append(symbol_tab) dashboard_layout = layout([[symbol_input, from_date_picker, to_date_picker, version_input, run_button], Tabs(tabs=symbol_tabs)]) doc.clear() doc.add_root(dashboard_layout) run_button = Button(label='Run', width=100, css_classes=['bk-custom-btn']) run_button.on_click(button_run) dashboard_layout = layout([[symbol_input, from_date_picker, to_date_picker, version_input, run_button]]) doc.add_root(dashboard_layout)
""" d3['debt'] = debt_input.value d3['monthly_repayment'] = debt_repay.value d5['value'] = cash_start.value d5['max_cash'] = cash_max.value d1['monthly_income'] = s1_input.value d2['monthly_income'] = s2_input.value d1['monthly_expenses'] = expense_input.value if select.labels[select.active] == "base repayments only": d3['pay_debt_asap'] = False elif select.labels[select.active] == "repay ASAP": d3['pay_debt_asap'] = True else: raise ValueError("select variable gave unexpected value: {0}".format( select.labels[select.active])) update_text("Placeholder text...") update_graphic() widget_list = widgetbox(select, debt_input, debt_repay, expense_input, cash_start, cash_max, s1_input, s2_input, button, width=300) button.on_click(update) # Set up layouts and add to document bottomrow = row(stats) toprow = row(widget_list, plot) layout = column(toprow, bottomrow) curdoc().add_root(layout)
def setDocumentLanguage(lang): flags.patch({'lang': [(0, lang)]}) for s in strings: if 'checkFlag' in strings[s]: flag = flags.data[strings[s]['checkFlag']][0] exec((s + '=\"' + strings[s][flag][lang] + '\"').encode(encoding='utf-8')) elif 'isCode' in strings[s] and strings[s]['isCode']: exec((s + '=' + strings[s][lang]).encode(encoding='utf-8')) else: exec( (s + '=\"' + strings[s][lang] + '\"').encode(encoding='utf-8')) lang_button = Button(button_type="success", label="Zu Deutsch wechseln") lang_button.on_click(changeLanguage) ################################################################################ #Create Reset Button: button = Button(label="Reset", button_type="success", width=50) #Let program know what functions button calls when clicked: weight_slide.on_change('value', fun_check1) button.on_click(init) #Initialization at the beginning: init() # add app description description_filename = join(dirname(__file__), "description.html")
# create a plot and style its properties fig = figure(width=plot_width, height=plot_height, x_axis_type="datetime", toolbar_location='above', tools="pan,box_zoom,xwheel_zoom,reset,save"); fig.quad(top='price_max', bottom='price_min', left='time_left', right='time_right', source=plot_data, color=Blues3[1]) fig.line(x='time_mid', y='price_mean', source=plot_data, color=Blues3[0]); # add widgets title=Div(text="<h1>Stock Price</h1>") description=Paragraph(text='Type in a symbol or select one from Dow 30 \ and Nasdaq 100, and its price on 5/6/2010 will be plotted shortly. Due to its \ high frequency, the series plotted is downsampled, with the shaded area denoting \ the min/max prices at every time point. Details can be revealed by zoom in with \ tools above the plot.') symbol_box=TextInput(value='', title='Type Symbol', width=100) market_select = Select(value='', title='Select ', width=100, options=['', 'Dow 30', 'Nasdaq 100']) symbol_select = Select(value='', title='Symbol ', width=100, options=[]) button = Button(label="GO", button_type='success', width=100) progress_bar=PreText() # add callbacks and interactions button.callback=CustomJS(code=dims_jscode, args=dict(plot=fig, dims=dims)) button.on_click(button_click) fig.x_range.on_change('start', update_plot) #fig.x_range.on_change('end', update_plot) fig.x_range.callback = CustomJS(code=dims_jscode, args=dict(plot=fig, dims=dims)) market_select.on_change('value', update_symbol_select) symbol_select.on_change('value', update_symbol_box) # put the button and plot in a layout and add to the document doc=curdoc() doc.add_root(column([widgetbox([title, description]), row([widgetbox(symbol_box), market_select,symbol_select]), button, progress_bar, fig], sizing_mode='scale_width'))
from bokeh.io import curdoc from bokeh.models import Button, Tabs, Panel, TextInput from bokeh.layouts import column from bokeh.models import ColumnDataSource from bokeh.plotting import figure def update_options(): source.data = {'x': [x for x in range(5)], 'y': [y**2 for y in range(5)]} button = Button(label='Update Data') button.on_click(update_options) source = ColumnDataSource(data=dict(x=[], y=[])) plot = figure() plot.circle('x', 'y', source=source) layout1 = column(TextInput(title='Text Input:'), plot) layout2 = column(TextInput(title='Text Input:'), button) tab1 = Panel(child=layout1, title='tab1') tab2 = Panel(child=layout2, title='tab2') tabs = Tabs(tabs=[tab1, tab2]) curdoc().add_root(tabs)
sys.exit(0) def update(): m.client.loop(timeout=0.5) #~ dtall = [datetime.datetime.fromtimestamp(k) for k in ds.data['x']] #~ #~ #~ #~ daydata = dict( #~ [datetime.datetime.fromtimestamp(k) for k in ds.data['x']), #~ [datetime.datetime.fromtimestamp(k) for k in ds.data['y']) #~ ) #~ source = ColumnDataSource(data) #~ #~ columns = [ #~ TableColumn(field="dates", title="Date", formatter=DateFormatter()), #~ TableColumn(field="downloads", title="Downloads"), #~ ] #~ data_table = DataTable(source=source, columns=columns, width=400, height=280) #~ #~ show(vform(data_table)) # add a button widget and configure with the call back button = Button(label="Stop") button.on_click(callstop) # put the button and plot in a layout and add to the document curdoc().add_root(vplot(button, p)) curdoc().add_periodic_callback(update, 500) # call client.loop to update if data available
'x': xlist, 'y': ylist, 'colors': colors, 'labels': new_ngrams } main_line.visible = True p.legend.visible = True def clear_lines(): global new_ngrams, lookup_list, box new_ngrams = [] main_line.visible = False p.legend.visible = False lookup_list = list(group.columns) # set up autocomplete box and trigger box = AutocompleteInput(completions=lookup_list, placeholder='Enter text') #box = TextInput(placeholder='Enter text') box.on_change('value', update_plot) clear = Button(label='clear all lines') clear.on_click(clear_lines) # create layout box_widget = widgetbox(box) clear_widget = widgetbox(clear) layout = column(p, row(box_widget, clear_widget)) curdoc().add_root(layout)
if len(df_) == 0: # Bad constraints status.text = 'No cases found. Try different constraints.' return doa = [not survived for survived in df_.survived] kmf = KaplanMeierFitter() fit = kmf.fit(df_.days, event_observed=doa, label='prob_of_surv') # Here, we are using the smoothed version of the Kaplan-Meier curve # The stepwise version would work just as well data, surv_func = renderer.data_source.data, fit.survival_function_ data.update(x=surv_func.index, y=surv_func.prob_of_surv) start, end = 0, max(df_.days) # bounds='auto' doesn't work? plot.x_range.update(start=start, end=end, bounds=(start, end)) status.text = '{} cases found.'.format(len(df_)) plot.xaxis.axis_label = 'Time (days)' plot.yaxis.axis_label = 'Probability of Survival' generate.on_click(generate_plot) generate_plot() # Start with Hikers, both sexes, all ages and group sizes document = curdoc() document.add_root(vplot(plot, status, generate, selectors))
def build_lockdown_tab(): # Get data for lockdown tab lockdown_data = get_lockdown_data() lockdown_data = prep_lockdown_data(lockdown_data) source_gantt = ColumnDataSource(lockdown_data.dropna()) source_points = ColumnDataSource(lockdown_data) # Create lockdown figure lockdown_fig = figure( y_range=FactorRange(factors=lockdown_data.Country.unique().tolist()), x_axis_type='datetime', title="Lockdown Status by Nation", x_range=(lockdown_data['start_date'].min() - timedelta(days=3), lockdown_data['end_date'].max() + timedelta(days=3)), outline_line_color=None, width=1000, height=650) # Adding hbar glyph of lockdown dates gantt_plot = lockdown_fig.hbar(y="Country", left='start_date', right='end_date', height=0.4, source=source_gantt, color='color') # Adding start point circle glyph start_point = lockdown_fig.circle(x='start_date', y='Country', source=source_points, size=5, line_color='blue', fill_color='white') # Adding end point circle glyph end_point = lockdown_fig.circle(x='end_date', y='Country', source=source_points, size=5, line_color='blue', fill_color='white') # Formatting x-axis lockdown_fig.xaxis.axis_label = "Date" lockdown_fig.xaxis.formatter = DatetimeTickFormatter(days='%d/%m/%Y') lockdown_fig.xaxis.ticker = DaysTicker(days=np.arange(5, 365, 7)) lockdown_fig.xaxis.major_label_orientation = math.pi / 6 # Formatting y-axis lockdown_fig.yaxis.axis_label = "Country" lockdown_fig.yaxis.major_label_orientation = math.pi / 12 lockdown_fig.yaxis.major_label_text_font_size = "7pt" lockdown_fig.yaxis.major_label_text_font_style = "bold" lockdown_fig.ygrid.grid_line_color = None lockdown_fig.y_range.range_padding = 0.05 # Align grid and axis tickers lockdown_fig.xgrid[0].ticker = lockdown_fig.xaxis[0].ticker # Adding hover tools gantt_hover = HoverTool(renderers=[gantt_plot], tooltips=[('Country', '@Country'), ('Start Date', '@start_date{%d/%m/%Y}'), ('End Date', '@end_date{%d/%m/%Y}'), ('Length', '@length{%d days}')], formatters={ '@start_date': 'datetime', '@end_date': 'datetime', '@length': 'printf' }) start_hover = HoverTool(renderers=[start_point], tooltips=[('Country', '@Country'), ('Start Date', '@start_date{%d/%m/%Y}')], formatters={'@start_date': 'datetime'}) end_hover = HoverTool(renderers=[end_point], tooltips=[('Country', '@Country'), ('End Date', '@end_date{%d/%m/%Y}')], formatters={'@end_date': 'datetime'}) lockdown_fig.add_tools(gantt_hover, start_hover, end_hover) # Adding vertical span for today's date today_date_span = Span(location=datetime.today(), dimension='height', line_color='blue', line_width=3, line_dash=[6, 6]) lockdown_fig.add_layout(today_date_span) # Labelling span span_label = Label(x=datetime.today() + timedelta(hours=12), y=-1.2, y_units='screen', text='Current Date', text_font_size='12pt') lockdown_fig.add_layout(span_label) # Adding CheckboxButtonGroup for continents continents = lockdown_data['continent'].unique().tolist() continent_rbg = RadioButtonGroup(labels=continents, active=None, width=500) def continent_rbg_callback(attr, old, new): if continent_rbg.active != None: selected_continent = continent_rbg.labels[continent_rbg.active] filtered_df = lockdown_data.loc[lockdown_data.continent == selected_continent] gantt_cds = ColumnDataSource(filtered_df.dropna()) points_cds = ColumnDataSource(filtered_df) source_gantt.data.update(gantt_cds.data) source_points.data.update(points_cds.data) lockdown_fig.y_range.factors = filtered_df.Country.unique().tolist( ) # Synchronise country filter country_multiselect.options = filtered_df['Country'].unique( ).tolist() country_multiselect.value = filtered_df['Country'].unique().tolist( ) continent_rbg.on_change('active', continent_rbg_callback) # Adding MultiSelect Widget for filtering by country countries = lockdown_data['Country'].unique().tolist() country_multiselect = MultiSelect(title='Countries:', options=countries, value=countries, height=500) def country_multiselect_callback(attr, old, new): selected_countries = country_multiselect.value filter_condition = lockdown_data.Country.isin(selected_countries) filtered_df = lockdown_data.loc[filter_condition] gantt_cds = ColumnDataSource(filtered_df.dropna()) points_cds = ColumnDataSource(filtered_df) source_gantt.data.update(gantt_cds.data) source_points.data.update(points_cds.data) lockdown_fig.y_range.factors = filtered_df.Country.unique().tolist() # Synchronise continent filter continent_rbg.active = None country_multiselect.on_change('value', country_multiselect_callback) # Creating Clear All, Select All Buttons def clear_button_callback(event): country_multiselect.options = countries country_multiselect.value = [] continent_rbg.active = None lockdown_fig.y_range.factors = lockdown_data.Country.unique().tolist() def select_all_button_callback(event): country_multiselect.options = countries country_multiselect.value = countries continent_rbg.active = None lockdown_fig.y_range.factors = lockdown_data.Country.unique().tolist() clear_button = Button(label="Clear Selection", button_type="success") clear_button.on_click(clear_button_callback) select_all_button = Button(label="Select All", button_type="success") select_all_button.on_click(select_all_button_callback) # Add the plot to the current document and add a title layout = row( widgetbox(clear_button, select_all_button, continent_rbg, country_multiselect), lockdown_fig) layout.sizing_mode = 'scale_width' # Creating lockdown tab lockdown_tab = Panel(child=layout, title='Lockdown') return (lockdown_tab)
] 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]))
button_cache = Button(label="Save id data in cache (parquet file)") selectbox_id = Select(title="ID", value="1", options=[str(i) for i in dbclient.ids()]) def selection(): "returns the pandas dataframe matching the selection criteria" idx_min = slider_start.value idx_max = slider_end.value id = int(selectbox_id.value) df = dbclient.read_index(id, idx_min, idx_max) return df.reset_index()[['DATETIME', 'var0']] def update(): plotdata.data = selection() def fill_cache(): dbclient.fill_cache(int(selectbox_id.value)) # control actions button_update.on_click(update) button_cache.on_click(fill_cache) # initial creation of data update() # put the button and plot in a layout and add to the document curdoc().add_root(column(slider_start, slider_end, button_update, plot_time))
# update layout layout.pop(node) # update nodes ColumnDataSource new_source_data = dict() for column in nodes_source.column_names: new_source_data[column] = [e for i, e in enumerate(nodes_source.data[column]) if i != idx] nodes_source.data = new_source_data # update lines ColumnDataSource lines_source.data = get_edges_specs(network, layout) drop_button = Button(label="Remove Node") drop_button.on_click(remove_node) def remove_unbound_nodes(): unbound_nodes = [] for node in network.nodes_iter(): if not network.edges(node): unbound_nodes.append(node) for node in unbound_nodes: network.remove_node(node) layout.pop(node) nodes, nodes_coordinates = zip(*sorted(layout.items())) nodes_xs, nodes_ys = list(zip(*nodes_coordinates)) nodes_source.data = dict(x=nodes_xs, y=nodes_ys, name=nodes, community_color=[], community=[], centrality=[])
width=250, height=218) pa.line(x="eta", y="PhaseShift", source=phase_angle, color="#a2ad00") pa.circle(x='eta', y='PhaseShift', size=10, color="#e37222", source=current_eta_PhaseShift) pa.yaxis.axis_label = "Phase angle [rad]" pa.toolbar.logo = None #removes bokeh logo pa.xaxis.axis_label = "Excitation Frequency Ratio" pa.axis.axis_label_text_font_style = "normal" # Define buttons and what happens when clicked play_pause_button = Button(label="Play", button_type="success", width=100) play_pause_button.on_click(play_pause) reset_button = Button(label="Reset", button_type="success", width=100) reset_button.on_click(reset) stop_button = Button(label="Stop", button_type="success", width=100) stop_button.on_click(stop) ###################################### # Change language ###################################### def changeLanguage(): [lang] = flags.data["lang"] if lang == "en": setDocumentLanguage('de') elif lang == "de":
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
############# # Create New OSM button button_new = Button(label="Create New Polygon", type='primary') def on_new_click(): #global poly_url #global poly_string # run some function #OpenURL(url=poly_url) #os.system(poly_url) webbrowser.open(poly_url) #print "poly_url", poly_url #session.store_objects(source1) #session.store_document(document) button_new.on_click(on_new_click) ############# ############# # Open screenshot of GDELT data button_gdelt = Button(label="Show GDELT Example", type='warning') def on_gdelt_click(): global gdelt_sample gdeltstr = 'open ' + gdelt_sample os.system(gdeltstr) button_gdelt.on_click(on_gdelt_click) ############# #############
def prepare_server(doc, input_data, cell_stack, cell_markers=None, default_cell_marker=None): @lru_cache() def image_markers(lower=False, mapping=False): if mapping: return { y: j for j, y in sorted( ((i, x) for i, x in enumerate( image_markers(lower=lower, mapping=False))), key=lambda x: x[1].lower(), ) } if lower: return [ x.lower() for x in image_markers(lower=False, mapping=False) ] return (cell_markers if cell_markers is not None else [f"Marker {i + 1}" for i in range(cell_stack.shape[1])]) # Data sources ########################################################################### def prepare_data(input_data): data = input_data.copy() if "contour" in data and not all(x in data for x in ["contour_x", "contour_y"]): contour = parse_contour(data["contour"]) data["contour_x"] = contour[0] data["contour_y"] = contour[1] if "marked" not in data: data["marked"] = np.full(data.shape[0], "") source.data = data source = ColumnDataSource(data={}) prepare_data(input_data) image_source = ColumnDataSource( data=dict(image=[], dw=[], dh=[], contour_x=[], contour_y=[])) # Cell picture plot ########################################################################### def add_outline(): data = source.data if all(x in data for x in ["contour_x", "contour_y"]): cell_outline = cell_figure.patches( xs="contour_x", ys="contour_y", fill_color=None, line_color="red", name="cell_outline", source=image_source, ) cell_outline.level = "overlay" else: cell_outline = cell_figure.select(name="cell_outline") for x in cell_outline: cell_figure.renderers.remove(x) default_cell_marker = (0 if default_cell_marker is None else image_markers( mapping=True)[default_cell_marker]) cell_markers_select = Select( value=str(default_cell_marker), options=list( (str(i), x) for x, i in image_markers(mapping=True).items()), title="Marker cell image", ) cell_marker_input = AutocompleteInput( completions=list(image_markers()) + list(image_markers(lower=True)), min_characters=1, placeholder="Search for marker", ) cell_slider = RangeSlider(start=0, end=1, value=(0, 1), orientation="vertical", direction="rtl") metric_select = RadioButtonGroup(active=0, labels=CELL_IMAGE_METRICS[0]) stats = PreText(text="", width=100) cell_mapper = bokeh.models.mappers.LinearColorMapper(viridis(20), low=0, high=1000, high_color=None) cell_color_bar = ColorBar(color_mapper=cell_mapper, width=12, location=(0, 0)) cell_figure = figure( plot_width=450, plot_height=350, tools="pan,wheel_zoom,reset", toolbar_location="left", ) cell_image = cell_figure.image( image="image", color_mapper=cell_mapper, x=0, y=0, dw="dw", dh="dh", source=image_source, ) add_outline() cell_figure.add_layout(cell_color_bar, "right") # Edit data of selected cells ########################################################################### marker_edit_container = column() marker_edit_instances = [] def add_marker_edit_callback(): editor = ColumnEditor( source, marker_edit_container, log_widget=edit_selecton_log, editor_delete_callback=delete_marker_edit_callback, external_edit_callback=edit_selection_callback, ) marker_edit_instances.append(editor) def delete_marker_edit_callback(editor): idx = next(i for i, x in enumerate(marker_edit_instances) if x is editor) del marker_edit_instances[idx] file_name_text = Div() add_marker_edit_button = Button(label="+", button_type="success", align=("start", "end"), width=50) add_marker_edit_button.on_click(add_marker_edit_callback) edit_selection_submit = Button(label="Submit change", button_type="primary", align=("start", "end")) download_button = Button(label="Download edited data", button_type="success", align=("start", "end")) download_button.js_on_click( CustomJS(args=dict(source=source), code=DOWNLOAD_JS)) edit_selecton_log = TextAreaInput(value="", disabled=True, css_classes=["edit_log"], cols=30, rows=10) upload_file_input = FileInput(accept="text/csv", align=("end", "end")) # Cell table ########################################################################### default_data_table_cols = [ TableColumn(field="marked", title="Seen", width=20) ] data_table = DataTable(source=source, columns=default_data_table_cols, width=800) # Callbacks for buttons and widgets ########################################################################### def cell_slider_change(attrname, old, new): cell_mapper.low = new[0] cell_mapper.high = new[1] def selection_change(attrname, old, new): selected = source.selected.indices data = source.data if not selected: return mean_image = CELL_IMAGE_METRICS[1][metric_select.active]( cell_stack[selected, int(cell_markers_select.value), :, :], axis=0) image_data = { "image": [mean_image], "dw": [cell_stack.shape[2]], "dh": [cell_stack.shape[3]], } for coord in ["contour_x", "contour_y"]: try: image_data[coord] = list(data[coord][selected]) except KeyError: pass image_source.data = image_data image_extr = round_signif(mean_image.min()), round_signif( mean_image.max()) cell_slider.start = image_extr[0] cell_slider.end = image_extr[1] cell_slider.step = round_signif((image_extr[1] - image_extr[0]) / 50) cell_slider.value = image_extr stats.text = "n cells: " + str(len(selected)) def autocomplete_cell_change(attrname, old, new): try: idx = image_markers(mapping=True)[new] except KeyError: try: idx = image_markers(lower=True, mapping=True)[new] except KeyError: return cell_markers_select.value = str(idx) cell_marker_input.value = None def data_change(attrname, old, new): new_keys = [n for n in new.keys() if n not in set(old.keys())] for n in new_keys: data_table.columns.append(TableColumn(field=n, title=n)) def edit_selection_submit_click(): for x in marker_edit_instances: x.edit_callback() def edit_selection_callback(): idx = source.selected.indices try: if len(idx) == 1 and all( source.data[x.widgets["input_col"].value][idx] != "NA" for x in marker_edit_instances): source.selected.indices = [idx[0] + 1] except KeyError: pass def upload_file_callback(attrname, old, new): try: data_text = b64decode(new) data = pd.read_csv(BytesIO(data_text)) except Exception: file_name_text.text = f"Error loading file {upload_file_input.filename}" return file_name_text.text = f"Editing file {upload_file_input.filename}" # Have to regenerate contours try: del data["contour_x"] del data["contour_y"] except KeyError: pass data_table.columns = default_data_table_cols prepare_data(data) add_outline() source.selected.on_change("indices", selection_change) source.on_change("data", data_change) cell_slider.on_change("value", cell_slider_change) metric_select.on_change("active", selection_change) cell_markers_select.on_change("value", selection_change) cell_marker_input.on_change("value", autocomplete_cell_change) edit_selection_submit.on_click(edit_selection_submit_click) upload_file_input.on_change("value", upload_file_callback) style_div = Div(text=CUSTOM_CSS) # set up layout layout = column( row( column(data_table), column( cell_markers_select, cell_marker_input, metric_select, row(cell_figure, cell_slider), stats, ), ), file_name_text, marker_edit_container, add_marker_edit_button, row(edit_selection_submit, download_button, upload_file_input), edit_selecton_log, style_div, ) doc.add_root(layout) doc.title = "Cell classifier"
def __init__(self, n_nodes): self.i = 0 kps = [crypto_sign_keypair() for _ in range(n_nodes)] stake = {kp[0]: 1 for kp in kps} network = {} self.nodes = [Node(kp, network, n_nodes, stake) for kp in kps] for n in self.nodes: network[n.pk] = n.ask_sync self.ids = {kp[0]: i for i, kp in enumerate(kps)} self.main_its = [n.main() for n in self.nodes] for m in self.main_its: next(m) def toggle(): if play.label == '► Play': play.label = '❚❚ Pause' curdoc().add_periodic_callback(self.animate, 50) else: play.label = '► Play' curdoc().remove_periodic_callback(self.animate) play = Button(label='► Play', width=60) play.on_click(toggle) def sel_node(new): self.active = new node = self.nodes[new] self.tbd = {} self.tr_src.data, self.links_src.data = self.extract_data( node, bfs((node.head,), lambda u: node.hg[u].p), 0) for u, j in tuple(self.tbd.items()): self.tr_src.data['line_alpha'][j] = 1 if node.famous.get(u) else 0 if u in node.idx: self.tr_src.data['round_color'][j] = idx_color(node.idx[u]) self.tr_src.data['idx'][j] = node.idx.get(u) if u in node.idx and u in node.famous: del self.tbd[u] print('updated') self.tr_src.trigger('data', None, self.tr_src.data) selector = RadioButtonGroup( labels=['Node %i' % i for i in range(n_nodes)], active=0, name='Node to inspect') selector.on_click(sel_node) plot = figure( plot_height=700, plot_width=900, y_range=(0, 30), tools=[PanTool(dimensions=['height']), HoverTool(tooltips=[ ('round', '@round'), ('hash', '@hash'), ('timestamp', '@time'), ('payload', '@payload'), ('number', '@idx')])]) plot.xgrid.grid_line_color = None plot.xaxis.minor_tick_line_color = None plot.ygrid.grid_line_color = None plot.yaxis.minor_tick_line_color = None self.links_src = ColumnDataSource(data={'x0': [], 'y0': [], 'x1': [], 'y1': [], 'width': []}) #self.links_rend = plot.add_layout( # Arrow(end=NormalHead(fill_color='black'), x_start='x0', y_start='y0', x_end='x1', # y_end='y1', source=self.links_src)) self.links_rend = plot.segment(color='#777777', x0='x0', y0='y0', x1='x1', y1='y1', source=self.links_src, line_width='width') self.tr_src = ColumnDataSource( data={'x': [], 'y': [], 'round_color': [], 'idx': [], 'line_alpha': [], 'round': [], 'hash': [], 'payload': [], 'time': []}) self.tr_rend = plot.circle(x='x', y='y', size=20, color='round_color', line_alpha='line_alpha', source=self.tr_src, line_width=5) sel_node(0) curdoc().add_root(row([widgetbox(play, selector, width=300), plot], sizing_mode='fixed'))
class BokehFileViewer(Tool): name = "BokehFileViewer" description = "Interactively explore an event file" aliases = Dict( dict( r='EventFileReaderFactory.reader', f='EventFileReaderFactory.input_path', max_events='EventFileReaderFactory.max_events', ped='CameraR1CalibratorFactory.pedestal_path', tf='CameraR1CalibratorFactory.tf_path', pe='CameraR1CalibratorFactory.pe_path', ff='CameraR1CalibratorFactory.ff_path', extractor='ChargeExtractorFactory.extractor', 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', clip_amplitude='CameraDL1Calibrator.clip_amplitude', radius='CameraDL1Calibrator.radius', cleaner='WaveformCleanerFactory.cleaner', cleaner_t0='WaveformCleanerFactory.t0', )) flags = Dict( dict(id=({ 'DisplayDL1Calib': { 'use_event_index': True } }, 'event_index will obtain an event using ' 'event_id instead of index.'))) classes = List([ EventFileReaderFactory, 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._extractor = None self._cleaner = 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.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) reader_factory = EventFileReaderFactory(**kwargs) reader_class = reader_factory.get_class() self.reader = reader_class(**kwargs) extractor_factory = ChargeExtractorFactory(**kwargs) extractor_class = extractor_factory.get_class() self._extractor = extractor_class(**kwargs) cleaner_factory = WaveformCleanerFactory(**kwargs) cleaner_class = cleaner_factory.get_class() self._cleaner = cleaner_class(**kwargs) r1_factory = CameraR1CalibratorFactory(origin=self.reader.origin, **kwargs) r1_class = r1_factory.get_class() self.r1 = r1_class(**kwargs) self.dl0 = CameraDL0Reducer(**kwargs) self.dl1 = CameraDL1Calibrator(extractor=self.extractor, cleaner=self.cleaner, **kwargs) self.viewer = EventViewer(**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): curdoc().add_root(self.layout) curdoc().title = "Event Viewer" @property def event_index(self): return self._event_index @event_index.setter def event_index(self, val): try: self.event = self.reader.get_event(val, False) except RuntimeError: 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.reader.get_event(val, True) except RuntimeError: self.log.warning("Event ID {} does not exist".format(val)) @property def telid(self): return self._telid @telid.setter def telid(self, val): n_chan = self.event.inst.num_channels[val] if self.channel is None or self.channel >= n_chan: 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() @property def extractor(self): return self._extractor @extractor.setter def extractor(self, val): self._extractor = val kwargs = dict(config=self.config, tool=self) self.dl1 = CameraDL1Calibrator(extractor=val, cleaner=self.cleaner, **kwargs) self.dl1.calibrate(self.event) self.viewer.refresh() @property def cleaner(self): return self._cleaner @cleaner.setter def cleaner(self, val): self._cleaner = val kwargs = dict(config=self.config, tool=self) self.dl1 = CameraDL1Calibrator(extractor=self.extractor, cleaner=val, **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): # TODO don't allow negative 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, attr, old, new): 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.channel: n_chan = self.event.inst.num_channels[self.telid] 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, attr, old, new): 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 key, val in self.w_dl1_dict.items(): 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': key = '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': key = 'name' else: key = key.replace("cleaner_", "") try: val.value = str(getattr(self.cleaner, key)) except AttributeError: val.value = '' def on_dl1_widget_change(self, attr, old, new): 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_factory = ChargeExtractorFactory(**kwargs) extractor_class = extractor_factory.get_class() self.extractor = extractor_class(**kwargs) cleaner_factory = WaveformCleanerFactory(**kwargs) cleaner_class = cleaner_factory.get_class() self.cleaner = cleaner_class(**kwargs) self.update_dl1_widget_values() self._updating_dl1 = False
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 plot.line('rx', 'ry',
question = question_field.value # div.text = source print('calling answer_question') answer = answer_question(question) print('update columnDataSource') print('before df shape={}'.format(summary_df.shape)) summary_df = summary_df.append({ 'Question': question, 'Answer': answer }, ignore_index=True) print('after df shape={}'.format(summary_df.shape)) columnDataSource.data = summary_df button.on_click(update_table) # show(row(inputs, column, width=800)) curdoc().add_root(row(inputs, column, width=800)) curdoc().title = "QA-Agent" # In[ ]: def answer_question(question): print('calling agent to answer') answer = covid_agent.answer(question) print('got answer: {}'.format(answer)) return answer
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) if __name__ == "__main__": link = session.object_link(document.context) print("Please visit %s to see the plots" % link) view(link) print("\npress ctrl-C to exit") session.poll_document(document)
def main(): global sources global all_column_names global counter global consumer global all_names global unem_options global unem_values global source_unem global update_time global sleep_time global velocity_options # def update_select_unem1(attr, old, new): # global unem_values # # unem1_value = select_unem1.value # unem_values[0] = unem1_value # # print("Changing unem 1 ", unem_values[0]) def update_select_vel(attr, old, new): global sleep_time global velocity_options speed = select_vel.value print("Changing speed to ", speed, velocity_options[speed]) sleep_time = velocity_options[speed] figure_info1 = { "names": ["time", "EEUU_Unem", "EEUU_DJI"], "x_name": "time", "line_widths": [2, 2, 2, 2], "alphas": [0.85, 0.85, 0.85, 0.85], "colors": ["blue", "red", "black", "orange"], "legends": ["Unem", "DJI"], "y_range": [0, 30], "plot_width": 450, "plot_height": 350, "title": "EEUU", "legend_location": "top_left", "xaxis_label": "x", "yaxis_label": "y", "title_align": "center", "max_unemployment": 15 } figure_info2 = { "names": ["time", "Spain_Unem", "Spain_IBEX35"], "x_name": "time", "line_widths": [2, 2, 2, 2], "alphas": [0.85, 0.85, 0.85, 0.85], "colors": ["blue", "red", "black", "orange"], "legends": ["Unem", "IBEX35"], "y_range": [0, 30], "plot_width": 450, "plot_height": 350, "title": "Spain", "legend_location": "top_left", "xaxis_label": "x", "yaxis_label": "y", "title_align": "center", "max_unemployment": 30 } figure_info3 = { "names": ["time", "Japan_Unem", "Japan_N225"], "x_name": "time", "line_widths": [2, 2, 2, 2], "alphas": [0.85, 0.85, 0.85, 0.85], "colors": ["blue", "red", "black", "orange"], "legends": ["Unem", "N255"], "y_range": [0, 30], "plot_width": 450, "plot_height": 350, "title": "Japan", "legend_location": "top_left", "xaxis_label": "x", "yaxis_label": "y", "title_align": "center", "max_unemployment": 8 } figure_info4 = { "names": ["time", "UK_Unem", "UK_LSE"], "x_name": "time", "line_widths": [2, 2, 2, 2], "alphas": [0.85, 0.85, 0.85, 0.85], "colors": ["blue", "red", "black", "orange"], "legends": ["Unem", "LSE"], "y_range": [0, 30], "plot_width": 450, "plot_height": 350, "title": "UK", "legend_location": "top_left", "xaxis_label": "x", "yaxis_label": "y", "title_align": "center", "max_unemployment": 10 } figure_info5 = { "names": ["time", "EEUU_Unem", "Spain_Unem", "Japan_Unem", "UK_Unem"], "x_name": "time", "line_widths": [2, 2, 2, 2], "alphas": [0.85, 0.85, 0.85, 0.85], "colors": ["blue", "red", "black", "orange"], "legends": ["EEUU_Unem", "Spain_Unem", "Japan_Unem", "UK_Unem"], "y_range": [0, 30], "plot_width": 450, "plot_height": 350, "title": "Unemployment comparison", "legend_location": "top_left", "xaxis_label": "x", "yaxis_label": "y", "title_align": "center" } figure_info6 = { "names": ["time", "EEUU_DJI", "Spain_IBEX35", "Japan_N225", "UK_LSE"], "x_name": "time", "line_widths": [2, 2, 2, 2], "alphas": [0.85, 0.85, 0.85, 0.85], "colors": ["blue", "red", "black", "orange"], "legends": ["EEUU_DJI", "Spain_IBEX35", "Japan_N225", "UK_LSE"], "y_range": [0, 30], "plot_width": 450, "plot_height": 350, "title": "Stock exchange comparison", "legend_location": "top_left", "xaxis_label": "x", "yaxis_label": "y", "title_align": "center" } # figure_info5 = {"names":["time", unem_values[0], unem_values[1]], # "x_name":"time", "line_widths":[2,2] , # "alphas":[0.85, 0.85], # "colors":["blue", "red"], # "plot_width":450, "plot_height":350, # "title":"UK", "legend_location":"top_left", # "xaxis_label":"x", "yaxis_label":"y", # "title_align":"center", # "max_unemployment":10} # figure_info1 = {"names":["time", "EEUU_Unem", "Spain_Unem", "Japan_Unem", "UK_Unem"], # "x_name":"time", "line_widths":[2,2,2,2] , # "alphas":[0.85, 0.85, 0.85, 0.85], # "colors":["blue", "red", "black", "orange"], # "legends":["EEUU", "Spain", "Japan", "UK"], # "y_range":[0, 30], # "plot_width":450, "plot_height":350, # "title":"Title for figure", "legend_location":"bottom_left", # "xaxis_label":"x", "yaxis_label":"y", # "title_align":"center"} # figure_info2 = {"names":["time", "EEUU_DJI", "Spain_IBEX35", "Japan_N225", "UK_LSE"], # "x_name":"time", "line_widths":[2,2,2,2] , # "alphas":[0.85, 0.85, 0.85, 0.85], # "colors":["blue", "red", "black", "orange"], # "legends":["DJI", "IBEX35", "N225", "LSE"], # "y_range":[0, 22000], # "plot_width":450, "plot_height":350, # "title":"Title for figure", "legend_location":"bottom_left", # "xaxis_label":"x", "yaxis_label":"y", # "title_align":"center"} source_all = source_bokeh_kafka(all_names) dict_unem = { "time": source_all.data["time"], unem_values[0]: source_all.data[unem_values[0]], unem_values[0]: source_all.data[unem_values[0]] } source_unem = ColumnDataSource(dict_unem) fig1 = multi_plot(figure_info1, source_all) fig2 = multi_plot(figure_info2, source_all) fig3 = multi_plot(figure_info3, source_all) fig4 = multi_plot(figure_info4, source_all) fig5 = multiline_plot(figure_info5, source_all) fig6 = multiline_plot(figure_info6, source_all) select_vel = Select(value='Slow', options=vel_options) select_vel.on_change('value', update_select_vel) def update_buttom_increase(): global sleep_time sleep_time -= 0.15 print("increasing velocity") def update_buttom_decrease(): global sleep_time sleep_time += 0.15 print("increasing velocity") buttom_increase = Button(label="Increase velocity") buttom_increase.on_click(update_buttom_increase) buttom_decrease = Button(label="Decrease velocity") buttom_decrease.on_click(update_buttom_decrease) sources.append(source_all) all_column_names.append(all_names) # select_unem1.on_change('value', update_select_unem1) curdoc().add_periodic_callback(update_data, update_time) curdoc().add_root(layout([[fig1, fig2, fig5], [fig3, fig4, fig6]]))
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 cleaner_product = tool_utils.enum_trait(WaveformCleaner, default='NullWaveformCleaner') extractor_product = tool_utils.enum_trait( ChargeExtractor, default='NeighbourPeakIntegrator') aliases = Dict( dict( port='BokehFileViewer.port', disable_server='BokehFileViewer.disable_server', f='EventSource.input_url', max_events='EventSource.max_events', extractor='BokehFileViewer.extractor_product', cleaner='BokehFileViewer.cleaner_product', simpleintegrator_t0='SimpleIntegrator.t0', window_width='WindowIntegrator.window_width', window_shift='WindowIntegrator.window_shift', sig_amp_cut_HG='PeakFindingIntegrator.sig_amp_cut_HG', sig_amp_cut_LG='PeakFindingIntegrator.sig_amp_cut_LG', lwt='NeighbourPeakIntegrator.lwt', )) classes = List([ EventSource, CameraDL1Calibrator, ] + tool_utils.classes_with_traits(WaveformCleaner) + tool_utils.classes_with_traits(ChargeExtractor) + tool_utils.classes_with_traits(CameraR1Calibrator)) 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]" self.reader = EventSource.from_config(parent=self) self.seeker = EventSeeker(self.reader, parent=self) self.extractor = ChargeExtractor.from_name(self.extractor_product, parent=self) self.cleaner = WaveformCleaner.from_name(self.cleaner_product, parent=self) self.r1 = CameraR1Calibrator.from_eventsource(eventsource=self.reader, parent=self) self.dl0 = CameraDL0Reducer(parent=self) self.dl1 = CameraDL1Calibrator(extractor=self.extractor, cleaner=self.cleaner, parent=self) self.viewer = BokehEventViewer(parent=self) # 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): # 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 self.dl1 = CameraDL1Calibrator(extractor=self.extractor, cleaner=self.cleaner, parent=self) 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=BokehFileViewer.cleaner_product.values), extractor=Select(title="Extractor:", value='', width=5, options=BokehFileViewer.extractor_product.values), 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(f'--{key}') cmdline.append(val.value) self.parse_command_line(cmdline) extractor = ChargeExtractor.from_name(self.extractor_product, parent=self) cleaner = WaveformCleaner.from_name(self.cleaner_product, parent=self) self.update_dl1_calibrator(extractor, cleaner) self.update_dl1_widget_values() self._updating_dl1 = False
def create(palm): energy_min = palm.energy_range.min() energy_max = palm.energy_range.max() energy_npoints = palm.energy_range.size current_results = (0, 0, 0, 0) doc = curdoc() # Streaked and reference waveforms plot waveform_plot = Plot( title=Title(text="eTOF waveforms"), x_range=DataRange1d(), y_range=DataRange1d(), plot_height=PLOT_CANVAS_HEIGHT, plot_width=PLOT_CANVAS_WIDTH, toolbar_location='right', ) # ---- tools waveform_plot.toolbar.logo = None waveform_plot.add_tools(PanTool(), BoxZoomTool(), WheelZoomTool(), ResetTool()) # ---- axes waveform_plot.add_layout(LinearAxis(axis_label='Photon energy, eV'), place='below') waveform_plot.add_layout(LinearAxis(axis_label='Intensity', major_label_orientation='vertical'), place='left') # ---- grid lines waveform_plot.add_layout(Grid(dimension=0, ticker=BasicTicker())) waveform_plot.add_layout(Grid(dimension=1, ticker=BasicTicker())) # ---- line glyphs waveform_source = ColumnDataSource( dict(x_str=[], y_str=[], x_ref=[], y_ref=[])) waveform_ref_line = waveform_plot.add_glyph( waveform_source, Line(x='x_ref', y='y_ref', line_color='blue')) waveform_str_line = waveform_plot.add_glyph( waveform_source, Line(x='x_str', y='y_str', line_color='red')) # ---- legend waveform_plot.add_layout( Legend(items=[("reference", [waveform_ref_line]), ("streaked", [waveform_str_line])])) waveform_plot.legend.click_policy = "hide" # Cross-correlation plot xcorr_plot = Plot( title=Title(text="Waveforms cross-correlation"), x_range=DataRange1d(), y_range=DataRange1d(), plot_height=PLOT_CANVAS_HEIGHT, plot_width=PLOT_CANVAS_WIDTH, toolbar_location='right', ) # ---- tools xcorr_plot.toolbar.logo = None xcorr_plot.add_tools(PanTool(), BoxZoomTool(), WheelZoomTool(), ResetTool()) # ---- axes xcorr_plot.add_layout(LinearAxis(axis_label='Energy shift, eV'), place='below') xcorr_plot.add_layout(LinearAxis(axis_label='Cross-correlation', major_label_orientation='vertical'), place='left') # ---- grid lines xcorr_plot.add_layout(Grid(dimension=0, ticker=BasicTicker())) xcorr_plot.add_layout(Grid(dimension=1, ticker=BasicTicker())) # ---- line glyphs xcorr_source = ColumnDataSource(dict(lags=[], xcorr1=[], xcorr2=[])) xcorr_plot.add_glyph( xcorr_source, Line(x='lags', y='xcorr1', line_color='purple', line_dash='dashed')) xcorr_plot.add_glyph(xcorr_source, Line(x='lags', y='xcorr2', line_color='purple')) # ---- vertical span xcorr_center_span = Span(location=0, dimension='height') xcorr_plot.add_layout(xcorr_center_span) # Delays plot pulse_delay_plot = Plot( title=Title(text="Pulse delays"), x_range=DataRange1d(), y_range=DataRange1d(), plot_height=PLOT_CANVAS_HEIGHT, plot_width=PLOT_CANVAS_WIDTH, toolbar_location='right', ) # ---- tools pulse_delay_plot.toolbar.logo = None pulse_delay_plot.add_tools(PanTool(), BoxZoomTool(), WheelZoomTool(), ResetTool()) # ---- axes pulse_delay_plot.add_layout(LinearAxis(axis_label='Pulse number'), place='below') pulse_delay_plot.add_layout( LinearAxis(axis_label='Pulse delay (uncalib), eV', major_label_orientation='vertical'), place='left', ) # ---- grid lines pulse_delay_plot.add_layout(Grid(dimension=0, ticker=BasicTicker())) pulse_delay_plot.add_layout(Grid(dimension=1, ticker=BasicTicker())) # ---- line glyphs pulse_delay_source = ColumnDataSource(dict(pulse=[], delay=[])) pulse_delay_plot.add_glyph( pulse_delay_source, Line(x='pulse', y='delay', line_color='steelblue')) # ---- vertical span pulse_delay_plot_span = Span(location=0, dimension='height') pulse_delay_plot.add_layout(pulse_delay_plot_span) # Pulse lengths plot pulse_length_plot = Plot( title=Title(text="Pulse lengths"), x_range=DataRange1d(), y_range=DataRange1d(), plot_height=PLOT_CANVAS_HEIGHT, plot_width=PLOT_CANVAS_WIDTH, toolbar_location='right', ) # ---- tools pulse_length_plot.toolbar.logo = None pulse_length_plot.add_tools(PanTool(), BoxZoomTool(), WheelZoomTool(), ResetTool()) # ---- axes pulse_length_plot.add_layout(LinearAxis(axis_label='Pulse number'), place='below') pulse_length_plot.add_layout( LinearAxis(axis_label='Pulse length (uncalib), eV', major_label_orientation='vertical'), place='left', ) # ---- grid lines pulse_length_plot.add_layout(Grid(dimension=0, ticker=BasicTicker())) pulse_length_plot.add_layout(Grid(dimension=1, ticker=BasicTicker())) # ---- line glyphs pulse_length_source = ColumnDataSource(dict(x=[], y=[])) pulse_length_plot.add_glyph(pulse_length_source, Line(x='x', y='y', line_color='steelblue')) # ---- vertical span pulse_length_plot_span = Span(location=0, dimension='height') pulse_length_plot.add_layout(pulse_length_plot_span) # Folder path text input def path_textinput_callback(_attr, _old, new): save_textinput.value = new path_periodic_update() path_textinput = TextInput(title="Folder Path:", value=os.path.join(os.path.expanduser('~')), width=510) path_textinput.on_change('value', path_textinput_callback) # Saved runs dropdown menu def h5_update(pulse, delays, debug_data): prep_data, lags, corr_res_uncut, corr_results = debug_data waveform_source.data.update( x_str=palm.energy_range, y_str=prep_data['1'][pulse, :], x_ref=palm.energy_range, y_ref=prep_data['0'][pulse, :], ) xcorr_source.data.update(lags=lags, xcorr1=corr_res_uncut[pulse, :], xcorr2=corr_results[pulse, :]) xcorr_center_span.location = delays[pulse] pulse_delay_plot_span.location = pulse pulse_length_plot_span.location = pulse # this placeholder function should be reassigned in 'saved_runs_dropdown_callback' h5_update_fun = lambda pulse: None def saved_runs_dropdown_callback(_attr, _old, new): if new != "Saved Runs": nonlocal h5_update_fun, current_results saved_runs_dropdown.label = new filepath = os.path.join(path_textinput.value, new) tags, delays, lengths, debug_data = palm.process_hdf5_file( filepath, debug=True) current_results = (new, tags, delays, lengths) if autosave_checkbox.active: save_button_callback() pulse_delay_source.data.update(pulse=np.arange(len(delays)), delay=delays) pulse_length_source.data.update(x=np.arange(len(lengths)), y=lengths) h5_update_fun = partial(h5_update, delays=delays, debug_data=debug_data) pulse_slider.end = len(delays) - 1 pulse_slider.value = 0 h5_update_fun(0) saved_runs_dropdown = Dropdown(label="Saved Runs", button_type='primary', menu=[]) saved_runs_dropdown.on_change('value', saved_runs_dropdown_callback) # ---- saved run periodic update def path_periodic_update(): new_menu = [] if os.path.isdir(path_textinput.value): for entry in os.scandir(path_textinput.value): if entry.is_file() and entry.name.endswith(('.hdf5', '.h5')): new_menu.append((entry.name, entry.name)) saved_runs_dropdown.menu = sorted(new_menu, reverse=True) doc.add_periodic_callback(path_periodic_update, 5000) # Pulse number slider def pulse_slider_callback(_attr, _old, new): h5_update_fun(pulse=new) pulse_slider = Slider( start=0, end=99999, value=0, step=1, title="Pulse ID", callback_policy='throttle', callback_throttle=500, ) pulse_slider.on_change('value', pulse_slider_callback) # Energy maximal range value text input def energy_max_textinput_callback(_attr, old, new): nonlocal energy_max try: new_value = float(new) if new_value > energy_min: energy_max = new_value palm.energy_range = np.linspace(energy_min, energy_max, energy_npoints) saved_runs_dropdown_callback('', '', saved_runs_dropdown.label) else: energy_max_textinput.value = old except ValueError: energy_max_textinput.value = old energy_max_textinput = TextInput(title='Maximal Energy, eV:', value=str(energy_max)) energy_max_textinput.on_change('value', energy_max_textinput_callback) # Energy minimal range value text input def energy_min_textinput_callback(_attr, old, new): nonlocal energy_min try: new_value = float(new) if new_value < energy_max: energy_min = new_value palm.energy_range = np.linspace(energy_min, energy_max, energy_npoints) saved_runs_dropdown_callback('', '', saved_runs_dropdown.label) else: energy_min_textinput.value = old except ValueError: energy_min_textinput.value = old energy_min_textinput = TextInput(title='Minimal Energy, eV:', value=str(energy_min)) energy_min_textinput.on_change('value', energy_min_textinput_callback) # Energy number of interpolation points text input def energy_npoints_textinput_callback(_attr, old, new): nonlocal energy_npoints try: new_value = int(new) if new_value > 1: energy_npoints = new_value palm.energy_range = np.linspace(energy_min, energy_max, energy_npoints) saved_runs_dropdown_callback('', '', saved_runs_dropdown.label) else: energy_npoints_textinput.value = old except ValueError: energy_npoints_textinput.value = old energy_npoints_textinput = TextInput( title='Number of interpolation points:', value=str(energy_npoints)) energy_npoints_textinput.on_change('value', energy_npoints_textinput_callback) # Save location save_textinput = TextInput(title="Save Folder Path:", value=os.path.join(os.path.expanduser('~'))) # Autosave checkbox autosave_checkbox = CheckboxButtonGroup(labels=["Auto Save"], active=[], width=250) # Save button def save_button_callback(): if current_results[0]: filename, tags, delays, lengths = current_results save_filename = os.path.splitext(filename)[0] + '.csv' df = pd.DataFrame({ 'pulse_id': tags, 'pulse_delay': delays, 'pulse_length': lengths }) df.to_csv(os.path.join(save_textinput.value, save_filename), index=False) save_button = Button(label="Save Results", button_type='default', width=250) save_button.on_click(save_button_callback) # assemble tab_layout = column( row( column(waveform_plot, xcorr_plot), Spacer(width=30), column( path_textinput, saved_runs_dropdown, pulse_slider, Spacer(height=30), energy_min_textinput, energy_max_textinput, energy_npoints_textinput, Spacer(height=30), save_textinput, autosave_checkbox, save_button, ), ), row(pulse_delay_plot, Spacer(width=10), pulse_length_plot), ) return Panel(child=tab_layout, title="HDF5 File")
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"
# 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))
geo_source.geojson = states_view.to_json() def save_to_shapefile(): states_view.to_file('fout.shp') def on_slider_change(attr, old, new): simplify_tolerance = new simplify_features(simplify_tolerance) # let's read some shapefile metadata crs = states.crs simplify_slider = Slider(title='Simplify Tolerance', value=0, start=0, end=1, step=.01) simplify_slider.on_change('value', on_slider_change) save_button = Button(label='Save') save_button.on_click(save_to_shapefile) p = Figure(plot_height=600, plot_width=900, x_range=(bounds[0], bounds[2]), y_range=(bounds[1], bounds[3])) polys = p.patches(xs='xs', ys='ys', alpha=0.9, source=geo_source) controls = HBox(width=p.plot_width, children=[simplify_slider, save_button]) layout = VBox(width=p.plot_width, children=[controls, p]) curdoc().add_root(layout)
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)