def modify_doc(doc): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1], val=["a", "b"])) 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')) plot.add_tools( CustomAction(callback=CustomJS(args=dict(s=source), code=RECORD("data", "s.data")))) spinner = Spinner(low=-1, high=10, step=0.1, value=4, css_classes=["foo"], format="0[.]0") def cb(attr, old, new): source.data['val'] = [old, new] spinner.on_change('value', cb) doc.add_root(column(spinner, plot)) return doc
def create_plot_height_input(self) -> TextInput: plot_height = self.figure.plot_height plot_height_input = Spinner(title="Height", value=plot_height, step=5, width=100) plot_height_input.on_change("value", self.handle_plot_height_change) return plot_height_input
def create_plot_width_input(self) -> TextInput: plot_width = self.figure.plot_width plot_width_input = Spinner(title="Width", value=plot_width, step=5, width=100) plot_width_input.on_change("value", self.handle_plot_width_change) return plot_width_input
def create_radius_input(self) -> TextInput: radius = self.plot.glyph.radius radius_input = Spinner(value=radius, title="Radius", step=0.01, width=100) radius_input.on_change("value", self.handle_radius_change) return radius_input
def create_range_end_input(self, dimension: str) -> Spinner: axes_range = self.get_axes_range(dimension) disabled = isinstance(axes_range, FactorRange) spinner = Spinner(title="End", value=axes_range.end, step=0.05, width=100, disabled=disabled) spinner.on_change("value", partial(self.handle_range_end_change, dimension)) return spinner
def modify_doc(doc): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1], val=["a", "b"])) 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')) plot.add_tools(CustomAction(callback=CustomJS(args=dict(s=source), code=RECORD("data", "s.data")))) spinner = Spinner(low=-1, high=10, step=0.1, value=4, css_classes=["foo"]) def cb(attr, old, new): source.data['val'] = [old, new] spinner.on_change('value', cb) doc.add_root(column(spinner, plot)) return doc
def test_input_smallest_step(self, bokeh_model_page) -> None: spinner = Spinner(value=0, low=0, high=1, step=1e-16, css_classes=["foo"]) spinner.js_on_change('value', CustomJS(code=RECORD("value", "cb_obj.value"))) page = bokeh_model_page(spinner) el = page.driver.find_element_by_css_selector('.foo input') enter_value_in_spinner(page.driver, el, 1e-16) results = page.results assert float(results['value']) == 1e-16 enter_value_in_spinner(page.driver, el, 0.43654644333534) results = page.results assert float(results['value']) == 0.43654644333534 assert page.has_no_console_errors()
def test_spinner_smallest_step(self, bokeh_model_page) -> None: spinner = Spinner(value=0, low=0, high=1, step=1e-16, css_classes=["foo"]) spinner.js_on_change('value', CustomJS(code=RECORD("value", "cb_obj.value"))) page = bokeh_model_page(spinner) input_el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, input_el, "0.43654644333534") results = page.results assert results['value'] == 0.43654644333534 enter_text_in_element(page.driver, input_el, "1e-16", click=2) results = page.results assert results['value'] == 1e-16 assert page.has_no_console_errors()
def test_display_number_input(self, bokeh_model_page): spinner = Spinner(css_classes=["foo"]) page = bokeh_model_page(spinner) el = page.driver.find_element_by_css_selector('.foo input') assert el.get_attribute('type') == "number" assert page.has_no_console_errors()
def test_spinner_value_format(self, bokeh_model_page) -> None: spinner = Spinner(value=1, low=0, high=10, step=1, css_classes=["foo"], format="0.00") page = bokeh_model_page(spinner) input_el = page.driver.find_element_by_css_selector('.foo input') assert input_el.get_attribute('value') == '1.00' assert page.has_no_console_errors()
def page(): # create plot with circle glyphs p = figure(x_range=(1, 9), plot_width=500, plot_height=250) points = p.circle(x=x, y=y, size=15, fill_color="#21a7df") # set up textarea (div) div = Div( text=""" <p>Select the circle's size using this control element:</p> """, width=200, height=30, ) # set up spinner spinner = Spinner( title="Circle size", low=0, high=60, step=5, value=points.glyph.size, width=200, ) spinner.js_link("value", points.glyph, "size") # set up RangeSlider range_slider = RangeSlider( title="Adjust x-axis range", start=0, end=10, step=1, value=(p.x_range.start, p.x_range.end), ) range_slider.js_link("value", p.x_range, "start", attr_selector=0) range_slider.js_link("value", p.x_range, "end", attr_selector=1) # create layout return layout([ [div, spinner], [range_slider], [p], ])
def test_spinner_value_format(self, bokeh_model_page: BokehModelPage) -> None: spinner = Spinner(value=1, low=0, high=10, step=1, format="0.00") page = bokeh_model_page(spinner) input_el = find_element_for(page.driver, spinner, "input") assert input_el.get_attribute('value') == '1.00' assert page.has_no_console_errors()
def test_spinner_display_title(self, bokeh_model_page) -> None: spinner = Spinner(title="title", css_classes=["foo"]) page = bokeh_model_page(spinner) label_el = page.driver.find_element_by_css_selector('.foo label') assert label_el.text == "title" input_el = page.driver.find_element_by_css_selector('.foo input') assert input_el.get_attribute('type') == "text" assert page.has_no_console_errors()
def test_displays_title(self, bokeh_model_page): text_input = Spinner(title="title", css_classes=["foo"]) page = bokeh_model_page(text_input) el = page.driver.find_element_by_css_selector('.foo label') assert el.text == "title" el = page.driver.find_element_by_css_selector('.foo input') assert el.get_attribute('type') == "number" assert page.has_no_console_errors()
def test_callback_property_executes(self, single_plot_page): 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)) spinner = Spinner(css_classes=['foo']) spinner.callback = CustomJS(code=RECORD("value", "cb_obj.value")) page = single_plot_page(column(spinner, plot)) el = page.driver.find_element_by_css_selector('.foo input') enter_value_in_spinner(page.driver, el, 4) results = page.results assert results['value'] == 4 enter_value_in_spinner(page.driver, el, -5.1) results = page.results assert results['value'] == -5.1 assert page.has_no_console_errors()
def test_callback_property_executes(self, single_plot_page): 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)) spinner = Spinner(css_classes=['foo'], step=1, value=0) spinner.callback = CustomJS(code=RECORD("value", "cb_obj.value")) page = single_plot_page(column(spinner, plot)) el = page.driver.find_element_by_css_selector('.foo input') enter_value_in_spinner(page.driver, el, 4) results = page.results assert results['value'] == 4 enter_value_in_spinner(page.driver, el, -5.1) results = page.results assert results['value'] == -5 assert page.has_no_console_errors()
def test_spinner_display_title(self, bokeh_model_page: BokehModelPage) -> None: spinner = Spinner(title="title") page = bokeh_model_page(spinner) label_el = find_element_for(page.driver, spinner, "label") assert label_el.text == "title" input_el = find_element_for(page.driver, spinner, "input") assert input_el.get_attribute('type') == "text" assert page.has_no_console_errors()
def test_spinner_display(self, bokeh_model_page) -> None: spinner = Spinner(css_classes=["foo"]) page = bokeh_model_page(spinner) input_el = page.driver.find_element_by_css_selector('.foo input') btn_up_el = page.driver.find_element_by_css_selector('.foo .bk-spin-btn-up') btn_down_el = page.driver.find_element_by_css_selector('.foo .bk-spin-btn-down') assert input_el.get_attribute('type') == "text" assert btn_up_el.tag_name == "button" assert btn_down_el.tag_name == "button" assert page.has_no_console_errors()
def test_input_value_min_max_step(self, bokeh_model_page): spinner = Spinner(value=1, low=0, high=10, step=1, css_classes=["foo"]) page = bokeh_model_page(spinner) el = page.driver.find_element_by_css_selector('.foo input') assert el.get_attribute('value') == '1' assert el.get_attribute('step') == '1' assert el.get_attribute('max') == '10' assert el.get_attribute('min') == '0' assert page.has_no_console_errors()
def test_spinner_display(self, bokeh_model_page: BokehModelPage) -> None: spinner = Spinner() page = bokeh_model_page(spinner) input_el = find_element_for(page.driver, spinner, "input") btn_up_el = find_element_for(page.driver, spinner, ".bk-spin-btn-up") btn_down_el = find_element_for(page.driver, spinner, ".bk-spin-btn-down") assert input_el.get_attribute('type') == "text" assert btn_up_el.tag_name == "button" assert btn_down_el.tag_name == "button" assert page.has_no_console_errors()
def __init__(self): """Initialize an image processor. """ self.aggregated_image = np.zeros((1, 1), dtype=np.float32) # Threshold widgets self.threshold_toggle = CheckboxGroup(labels=["Apply Thresholding"], default_size=145) self.threshold_min_spinner = Spinner(title="Min Intensity:", value=0, step=0.1, default_size=145) self.threshold_max_spinner = Spinner(title="Max Intensity:", value=1000, step=0.1, default_size=145) # Aggregate widgets self.aggregate_toggle = CheckboxGroup(labels=["Apply Aggregation"], default_size=145) self.aggregate_limit_spinner = Spinner(title="Limit:", value=0, low=0, step=1, default_size=145) self.aggregate_counter_textinput = TextInput(title="Counter:", value=str(1), disabled=True, default_size=145) self.average_toggle = CheckboxGroup(labels=["Show Average"], default_size=145)
def test_server_on_change_round_trip(self, bokeh_server_page: BokehServerPage) -> None: spinner = Spinner(low=-1, high=10, step=0.1, value=4, format="0[.]0") page = bokeh_server_page(mk_modify_doc(spinner)) input_el = find_element_for(page.driver, spinner, "input") # same value enter_text_in_element(page.driver, input_el, "4", click=2) page.eval_custom_action() results = page.results assert results['data']['val'] == ["a", "b"] # new valid value enter_text_in_element(page.driver, input_el, "5", click=2) page.eval_custom_action() results = page.results assert results['data']['val'] == [4, 5] # new overflow value enter_text_in_element(page.driver, input_el, "11", click=2) page.eval_custom_action() results = page.results assert results['data']['val'] == [5, 10] # new underflow value enter_text_in_element(page.driver, input_el, "-2", click=2) page.eval_custom_action() results = page.results assert results['data']['val'] == [10, -1] # new decimal value input_el.clear() #negative previous values needs a triple click to be selected enter_text_in_element(page.driver, input_el, "5.1") page.eval_custom_action() results = page.results assert results['data']['val'] == [None, 5.1] # new decimal value test rounding enter_text_in_element(page.driver, input_el, "5.19", click=2) page.eval_custom_action() results = page.results assert results['data']['val'] == [5.1, 5.19] assert input_el.get_attribute('value') == '5.2'
source = ColumnDataSource(df) y_list = source.data['favorite_count'].tolist() plot_figure = figure(plot_height=450, plot_width=600, tools="save,reset", toolbar_location="below") points = plot_figure.scatter('retweet_count', 'favorite_count', source=source, size=10) spinner = Spinner(title="Glyph size", low=1, high=40, step=0.5, value=4, width=80) spinner.js_link('value', points.glyph, 'size') button = Button(label="Click to set plot title", button_type="success") # visualization of retweeting tweets and favorite tweets from the home timeline at a time t def button_click(): plot_figure.title.text = 'Button Clicked' button.on_click(button_click) layout = row(row(column(spinner, width=100), plot_figure))
# define the location of the target P = 1*np.array([0, 6], dtype='float') # define the initital guess Po = 1*np.array([0.333, 3], dtype='float') N, num_dim = S.shape # estimating +/- 10 error range_err = 0.01 # estimating +/- 0.1us error time_err = 0.0000001 ### --------------------------------------------------------------------------- p_err_spin = Spinner(title="Position Error (km)", low=0.0, high=10.0, step=0.001, value=range_err, width=spin_width) t_err_spin = Spinner(title="Time Error (s)", low=0.0, high=1.0, step=0.00000001, value=time_err, width=spin_width) results_div = Div(width=250) aou_text = TextInput(title="AOU (km^2)", value="", width=245, background=[255,255,255], disabled=True) ### --------------------------------------------------------------------------- # calculate the arrival times def calc_arrival_times(S, T, P, N, v): for idx in range(0, N): T[idx] = math.sqrt(np.sum((S[idx] - P)*(S[idx] - P)))/v return T ### ---------------------------------------------------------------------------
import numpy as np from bokeh.io import show from bokeh.plotting import Figure from bokeh.models import ColumnDataSource, CustomJS, Spinner from bokeh.layouts import row, widgetbox data = np.random.rand(10, 2) cds = ColumnDataSource(data=dict(x=data[:, 0], y=data[:, 1])) p = Figure(x_range=(0, 1), y_range=(0, 1)) points = p.scatter(x='x', y='y', source=cds) w = Spinner(title="Glyph size", low=1, high=20, step=0.1, value=4, width=100) cb = CustomJS(args={'points': points}, code=""" points.glyph.size = cb_obj.value """) points.glyph.size = w.value w.js_on_change('value', cb) show(row([widgetbox(w, width=100), p]))
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_value, new_value): save_textinput.value = new_value 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_value, new_value): if new_value != "Saved Runs": nonlocal h5_update_fun, current_results saved_runs_dropdown.label = new_value filepath = os.path.join(path_textinput.value, new_value) tags, delays, lengths, debug_data = palm.process_hdf5_file( filepath, debug=True) current_results = (new_value, 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_value, new_value): h5_update_fun(pulse=new_value) 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_spinner_callback(_attr, old_value, new_value): nonlocal energy_max 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_spinner.value = old_value energy_max_spinner = Spinner(title="Maximal Energy, eV:", value=energy_max, step=0.1) energy_max_spinner.on_change("value", energy_max_spinner_callback) # Energy minimal range value text input def energy_min_spinner_callback(_attr, old_value, new_value): nonlocal energy_min 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_spinner.value = old_value energy_min_spinner = Spinner(title="Minimal Energy, eV:", value=energy_min, step=0.1) energy_min_spinner.on_change("value", energy_min_spinner_callback) # Energy number of interpolation points text input def energy_npoints_spinner_callback(_attr, old_value, new_value): nonlocal energy_npoints 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_spinner.value = old_value energy_npoints_spinner = Spinner(title="Number of interpolation points:", value=energy_npoints) energy_npoints_spinner.on_change("value", energy_npoints_spinner_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_spinner, energy_max_spinner, energy_npoints_spinner, 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 create_size_spinner(self) -> Spinner: value = int(self.text_font_size[:-2]) spinner = Spinner(title="Size", value=value, low=0, step=1, width=100) spinner.on_change("value", self.handle_size_change) return spinner
def create_standoff_spinner(self) -> Spinner: spinner = Spinner(title="Standoff", value=self.standoff, width=210) spinner.on_change("value", self.handle_standoff_change) return spinner
def create_hbar(area, plot_data, y_variables=data.model_vars, y_definition=data.label_def_ordered, y_extra_info=data.label_extra_ordered, div_name="myplot"): values = plot_data.to_numpy() values = values[0] all_data = ColumnDataSource(data=dict({ 'variables': y_variables, 'values': values, 'definition': y_definition, 'variables_extra': y_extra_info })) tooltips = """ <div style="width:200px;"> <div> <span style="font-size: 15px; color:blue">Variable:</span> <span style="font-size: 12px;">@variables_extra</span> </div> <div> <span style="font-size: 15px; color:blue">Percentage:</span> <span style="font-size: 12px;">@values{1.1} %</span> </div> <div> <span style="font-size: 15px; color:blue">Explanation:</span> <span style="font-size: 12px;">@definition</span> </div> </div> """ TOOLS = "hover,save,pan,box_zoom,reset,wheel_zoom" plot = figure( plot_height=600, plot_width=800, x_axis_label='Percentage', #y_axis_label = , x_range=(0, 100), y_range=y_variables, tools=TOOLS, tooltips=tooltips) plot.circle_cross(x='values', y='variables', size=30, color='lightseagreen', line_color="teal", alpha=0.75, hover_fill_alpha=1.0, hover_fill_color='navy', source=all_data) plot.title.text = "Relevant statistics about " + area part_rent_slider = Spinner(low=0, high=100, value=plot_data.loc[:, 'WPARTHUUR_P'].iloc[0], step=1, title="Private rental", width=80) corp_rent_slider = Spinner(low=0, high=100, value=plot_data.loc[:, 'WCORHUUR_P'].iloc[0], step=1, title="Housing corporation rental", width=80) high_rent_slider = Spinner(low=0, high=100, value=plot_data.loc[:, 'WHUURHOOG_P'].iloc[0], step=1, title="High rent (> 971 euro)", width=80) middle_rent_slider = Spinner(low=0, high=100, value=plot_data.loc[:, 'WHUURMIDDEN_P'].iloc[0], step=1, title="Middle high rent (711 - 971 euro)", width=80) low_rent_slider = Spinner(low=0, high=100, value=plot_data.loc[:, 'WHUURTSLG_P'].iloc[0], step=1, title="Low rent (< 711 euro)", width=80) living_space_040 = Spinner(low=0, high=100, value=plot_data.loc[:, 'WOPP0040_P'].iloc[0], step=1, title="Living space of 0-40 m2", width=80) living_space_4060 = Spinner(low=0, high=100, value=plot_data.loc[:, 'WOPP4060_P'].iloc[0], step=1, title="Living space of 40-60 m2", width=80) living_space_6080 = Spinner(low=0, high=100, value=plot_data.loc[:, 'WOPP6080_P'].iloc[0], step=1, title="Living space of 60-80 m2", width=80) living_space_80100 = Spinner(low=0, high=100, value=plot_data.loc[:, 'WOPP80100_P'].iloc[0], step=1, title="Living space of 80-100 m2", width=80) living_space_100 = Spinner(low=0, high=100, value=plot_data.loc[:, 'WOPP100PLUS_P'].iloc[0], step=1, title="Living space of > 100 m2", width=80) all_sliders = [ part_rent_slider, corp_rent_slider, high_rent_slider, middle_rent_slider, low_rent_slider, living_space_100, living_space_80100, living_space_6080, living_space_4060, living_space_040 ] callback = CustomJS(args=dict(source=all_data), code=""" var data = source.data; var values = data["values"]; var value = cb_obj.value; var var_text = cb_obj.title; var variable; var value_idx; updatePlot(value, var_text); socket.on('plot_update', function(msg) { value = msg.new_value; variable = msg.variable; value_idx = msg.index; values[value_idx] = value; data.values = values; source.data = data; source.change.emit(); window.onmouseup = function() { updateModel(value, variable); } }); """) for slider in all_sliders: slider.js_on_change('value', callback) layout = row(plot, column(*all_sliders), width=800) plot_json = json_item(layout, div_name) return plot_json
view = CDSView(source=source_visible, filters=[ time_filter, speed_filter, routes_filter, gos_num_filter, in_jam_filter ]) # plotting the graph points = graph.scatter("x", "y", source=source_visible, fill_color="color", size="size", fill_alpha=0.5, line_color=None, view=view) spinner = Spinner(title="Размер точек", low=1, high=40, step=1, value=7, width=80) spinner.js_link('value', points.glyph, 'size') # displaying the model layout = row( column(graph, time_slider, speed_slider, row(spinner, in_jam_checkboxes)), column(routes_checkboxes, width=60), column(gos_num_checkboxes, width=60), column(text_banner, data_table)) show(layout)
peak_flagged_source = ColumnDataSource(data=dict()) distribution_source = ColumnDataSource(data=dict()) qq_source = ColumnDataSource(data=dict()) datatable_source = ColumnDataSource(data=dict()) hist_source = ColumnDataSource(data=dict()) station_name_input = AutocompleteInput( completions=autocomplete_station_names, title='Enter Water Survey of Canada STATION NAME (USE ALL CAPS)', value=IDS_TO_NAMES['08MH016'], min_characters=3) simulation_number_input = Spinner( high=5000, low=100, step=1, value=500, title="Number of Simulations", ) sample_size_input = Spinner(high=200, low=2, step=1, value=10, title="Sample Size for Simulations") msmt_error_input = RangeSlider( start=0, end=100., value=(10, 35), step=2,
Legend(click_policy='mute', location='top_left', border_line_alpha=0, items=legend_items)) # copy list to make it later possible to delete/ add items for the list without using original list (NOT YET USED) show_figures = figures splom = gridplot(show_figures, ncols=3, toolbar_location='right') p4 = gridplot([[splom, dum_fig]], toolbar_location=None) # [END] tab 4 - splom plot -------------------------------------------------------------------------------------------- # // TOOL GUI =========================================================================================================================================================== # Spinner GUI spinner = Spinner(title="Size", low=0, high=4, step=0.1, value=1, width=300) # spinner.js_link('value', points.glyph, 'radius') # Dropdown menu GUI menu = [("Item 1", "item_1"), ("Item 2", "item_2"), None, ("Item 3", "item_3")] dropdown = Dropdown(label="Dropdown button", button_type="warning", menu=menu) dropdown.js_on_event( "menu_item_click", CustomJS(code="console.log('dropdown: ' + this.item, this.toString())")) # Toggle button GUI toggle = Toggle(label="Button", button_type="success") toggle.js_on_click( CustomJS(code=""" console.log('toggle: active=' + this.active, this.toString()) """))
def create_alpha_spinner(self) -> Spinner: spinner = Spinner( title="Alpha", value=self.text_alpha, low=0, high=1, step=0.05, width=100 ) spinner.on_change("value", self.handle_alpha_change) return spinner