def patch_plot(self, title, tile_url, tile_attribution='MapTiler'): plot = base_map(tile_url, tile_attribution) div = Div(width=plot.plot_width // 2, height=plot.plot_height, height_policy="fixed") patches(plot, div, self.nations) callback = CustomJS(name="callback-load-hash-coordinates", args=dict(x=plot.x_range, y=plot.y_range), code=""" console.log([x.start, x.end, y.start, y.end].join(',')) let data = window.location.hash.slice(1) .split(',').map(x => +x); if (data.length == 4 && data.every(x => !isNaN(x))) { [x.start, x.end, y.start, y.end] = data; } """) button = Button(label="Reset Zoom", button_type="success") button.js_on_event(events.ButtonClick, callback) patches_layout = row(plot, div) button_layout = column(button, patches_layout) return Panel(child=button_layout, title=title)
def select_button(data_source=None): """Return a button.""" code = """ var data = data_source.data; var indices = []; var i = 0; while ( ! isNaN(data.y[i]) ) { indices.push(i) i++ } data_source.selected.indices = indices; button.button_type = 'success'; //console.log('select_button DONE'); """ button = Button(label="Select all indices", width=30, button_type="default") callback = CustomJS(args={ 'data_source': data_source, 'button': button }, code=code) button_type_callback = change_button_type_callback(button=button, btype='success') button.js_on_event(ButtonClick, callback, button_type_callback) return button
def create_buttons(): global button, download_button # Play button button = Button(label='► Play', button_type="success", width=60) button.on_click(animate) play_widget = widgetbox(button, width=80, height=50, sizing_mode='fixed') spacer = Spacer(width=300, height=50) # Download button download_button1 = Button(label="Download Minimal HTML", button_type="success", width=150) download_button2 = Button(label="Download With Structures", button_type="success", width=150) download_button1.js_on_event(ButtonClick, download_simple()) download_button2.js_on_event(ButtonClick, download_extended()) download_widget1 = widgetbox(download_button1, width=200, height=50, sizing_mode='fixed') download_widget2 = widgetbox(download_button2, width=200, height=50, sizing_mode='fixed') dpanel = Row(Spacer(width=170), download_widget1, Spacer(width=10), download_widget2, width=600, sizing_mode='fixed') return play_widget, dpanel
def comnt_visit_change_button(datasets=None, position_source=None, key_mapper=None, comnt_obj=None): """Return a button.""" def callback_py(attr, old, new, comnt_obj=None): selected_indices = position_source.selected.indices if len(selected_indices) > 1: print('multi serie selection, no good! len(selected_position) = {}' ''.format(len(selected_indices))) return selected_key = position_source.data['KEY'][selected_indices[0]] ds_key = key_mapper.get(selected_key) cv_boolean = datasets[ds_key]['metadata'].str.startswith( '//METADATA;COMNT_VISIT;') datasets[ds_key]['metadata'][ cv_boolean] = '//METADATA;COMNT_VISIT;' + comnt_obj.value js_code = """ console.log('comnt_visit_change_button') // Get data from ColumnDataSource var comnt_column = 'COMNT_VISIT'; var position_data = position_source.data; // Set variables attributes var new_comnt = comnt_obj.value; var selected_indices = position_source.selected.indices; if (selected_indices.length == 1) { position_data[comnt_column][selected_indices[0]] = new_comnt; // Save changes to ColumnDataSource position_source.change.emit(); // Trigger python callback inorder to save changes to the actual datasets dummy_trigger.glyph.size = {'value': Math.random(), 'units': 'screen'}; dummy_trigger.glyph.change.emit(); } else { console.log('To many selected stations!! We can only work with one at a time', selected_indices.length) } """ # noqa: E501 dummy_figure = figure() dummy_trigger = dummy_figure.circle(x=[1], y=[2], alpha=0) dummy_trigger.glyph.on_change('size', partial(callback_py, comnt_obj=comnt_obj)) callback = CustomJS(args={ 'position_source': position_source, 'comnt_obj': comnt_obj, 'dummy_trigger': dummy_trigger }, code=js_code) button = Button(label="Commit visit comnt", width=30, button_type="success") button.js_on_event(ButtonClick, callback) return button
def get_flag_widget(position_source, data_source, flag_key=None, color_key=None, size_key=None): """Return a bokeh row layout. Flag selector. """ code = """ console.log('get_flag_widget'); var flag_color_mapping = {'A-flag': {'c':'navy', 'flag': '', 'size': 6}, 'B-flag': {'c':'red', 'flag': 'B', 'size': 12}, 'E-flag': {'c':'green', 'flag': 'E', 'size': 12}, 'S-flag': {'c':'orange', 'flag': 'S', 'size': 12}}; // Get data from ColumnDataSource var position_data = position_source.data; var data = data_source.data; // Set variables attributes var color_column = color_key; var size_column = size_key; var selected_flag = flag_selection.value; var selected_position = position_source.selected.indices; var selected_key = position_data['KEY'][selected_position[0]]; var flag_column = selected_key+'_'+flag_key; // Get indices array of all selected items var selected_indices = data_source.selected.indices; for (var i = 0; i < selected_indices.length; i++) { data[color_column][selected_indices[i]] = flag_color_mapping[selected_flag]['c']; data[size_column][selected_indices[i]] = flag_color_mapping[selected_flag]['size']; data[flag_column][selected_indices[i]] = flag_color_mapping[selected_flag]['flag']; // console.log('data[flag_column][selected_indices[i]]', data[flag_column][selected_indices[i]]) } // Save changes to ColumnDataSource data_source.change.emit(); """ # noqa: E501 callback = CustomJS(args={ 'position_source': position_source, 'data_source': data_source }, code=code) flag_selector = Select(value='A-flag', options=['A-flag', 'B-flag', 'E-flag', 'S-flag'], width=100, height=50) callback.args["flag_selection"] = flag_selector callback.args["color_key"] = color_key callback.args["size_key"] = size_key callback.args["flag_key"] = flag_key button = Button(label="Flag Data", width=50) button.js_on_event(ButtonClick, callback) return row([flag_selector, button], sizing_mode="stretch_width")
class ButtonWrapper: def __init__(self, label: str, callback: Callback) -> None: self.obj = Button(label=label) self.obj.js_on_event('button_click', callback) def click(self, driver: WebDriver) -> None: button = find_element_for(driver, self.obj, ".bk-btn") button.click()
class ButtonWrapper(object): def __init__(self, label, callback): self.id = "button-" + make_id() self.obj = Button(label=label, css_classes=[self.id]) self.obj.js_on_event('button_click', callback) def click(self, driver): button = driver.find_element_by_class_name(self.id) button.click()
class ButtonWrapper(object): def __init__(self, label, callback): self.ref = "button-" + make_id() self.obj = Button(label=label, css_classes=[self.ref]) self.obj.js_on_event('button_click', callback) def click(self, driver): button = driver.find_element_by_css_selector(".%s .bk-btn" % self.ref) button.click()
def multiline2(): xData={ "a":[2,5,6,8,9,4,1,10,7,3] } x=[2,5,6,8,9,4,1,10,7,3] ya=[5,2,4,8,3,4,8,3,4,6] yb=[4,1,3,7,2,3,7,2,3,5] data=ColumnDataSource(data={'x':x,'ya':ya,'yb':yb}) p=figure(title = "multiline", sizing_mode="fixed", plot_width=600, plot_height=400,tools='pan,wheel_zoom,box_zoom,save,reset') p.toolbar.logo=None from bokeh.models import LinearColorMapper from bokeh.models.glyphs import Line,Circle from bokeh.palettes import inferno,YlOrRd,Magma,PuBu,Greys from bokeh.transform import transform #p.vline_stack(['y1','y2'],x='x',source=data) l1=Line(x='x',y='yb',line_color='red',line_width=2) l2=Circle(x='x',y='ya',fill_color='blue',fill_alpha=0.4,size=7) r1=p.add_glyph(data,l1,name='predict') r2=p.add_glyph(data,l2,name='real') p.add_tools( HoverTool(tooltips = [('X,Y_real', '@x,@ya')],names=['real']) ) p.add_tools( HoverTool(tooltips = [('X,Y_predict', '@x,@yb')],names=['predict']) ) from bokeh.models import Button from bokeh import events callback = CustomJS(args=dict(source=data), code=""" var data = source.data; let newList = []; for(var i=0;i<data['x'].length;i++){ newList.push({ value1: data['x'][i], value2: data['ya'][i], value3: data['yb'][i] }) } console.log(newList) newList.sort(function(a,b) { return ((a.value1 - b.value1)) }) console.log(newList) for(var i=0;i<newList.length;i++){ data['x'][i]=newList[i].value1 data['ya'][i]=newList[i].value2 data['yb'][i]=newList[i].value3 } console.log(data) source.change.emit(); """) dp = Button(label="sort") dp.js_on_event(events.ButtonClick, callback) layout = column(dp, p) return json.dumps(json_item(layout))
def deselect_button(data_source=None): """Return a button.""" code = """ data_source.selected.indices = []; """ callback = CustomJS(args={'data_source': data_source}, code=code) button = Button(label="Deselect all indices", width=30, button_type="default") button.js_on_event(ButtonClick, callback) return button
def test_js_on_event_executes(self, bokeh_model_page): button = Button(css_classes=['foo']) button.js_on_event('button_click', CustomJS(code=RECORD("clicked", "true"))) page = bokeh_model_page(button) button = page.driver.find_element_by_css_selector('.foo .bk-btn') button.click() results = page.results assert results == {'clicked': True} assert page.has_no_console_errors()
def test_js_on_event_executes(self, bokeh_model_page: BokehModelPage) -> None: button = Button() button.js_on_event('button_click', CustomJS(code=RECORD("clicked", "true"))) page = bokeh_model_page(button) button_el = find_element_for(page.driver, button, ".bk-btn") button_el.click() results = page.results assert results == {'clicked': True} assert page.has_no_console_errors()
def button_example(use_bokeh_server=False): if not use_bokeh_server: output_file('button.html') button = Button(label='Press Me') if use_bokeh_server: # To use real Python callbacks, a Bokeh server application may be used. def button_python_callback(window=None): print('Button is cicked.') button.on_click(button_python_callback) else: # Only JavaScript callbacks may be used with standalone output. button_javascript_callback = CustomJS(code=""" console.log('Click event occured at x-position: ') """) button.js_on_event(events.ButtonClick, button_javascript_callback) layout = column(button) if use_bokeh_server: curdoc().add_root(layout) else: show(layout)
y, radius=radii, fill_color=colors, fill_alpha=0.6, line_color=None) # Add a div to display events and a button to trigger button click events div = Div(width=1000) button = Button(label="Button", button_type="success") layout = column(button, row(p, div)) ## Register event callbacks # Button event button.js_on_event(events.ButtonClick, display_event(div)) # LOD events p.js_on_event(events.LODStart, display_event(div)) p.js_on_event(events.LODEnd, display_event(div)) # Point events point_attributes = ['x', 'y', 'sx', 'sy'] p.js_on_event(events.Tap, display_event(div, attributes=point_attributes)) p.js_on_event(events.DoubleTap, display_event(div, attributes=point_attributes)) p.js_on_event(events.Press, display_event(div, attributes=point_attributes)) # Mouse wheel event p.js_on_event(events.MouseWheel, display_event(div, attributes=point_attributes + ['delta']))
data: {"index": active_button}, dataType: 'json', success: function (json_from_server) { var test = json_from_server[active_button] fig.y_range.start = test[0]; fig.y_range.end = test[1]; fig.x_range.start = date_ints[active_button] fig.x_range.end = date_ints[6] }, error: function() { alert("Oh no, something went wrong. Search for an error " + "message in Flask log and browser developer tools."); } }); """ % (date_ints, stock_ticker)) p.js_on_event('tap', tap_callback) button2.js_on_event(ButtonClick, button_callback) radio_button_group.callback = radio_button_callback lay_out = column(row(text_input, button2), radio_button_group, output, row(p,div)) curdoc().add_root(lay_out) js,div=components(lay_out, INLINE) cdn_js=INLINE.render_js() cdn_css=INLINE.render_css()
from bokeh.io import show from bokeh.models import Button, CustomJS button = Button(label="Foo", button_type="success") button.js_on_event( "button_click", CustomJS(code="console.log('button: click!', this.toString())")) show(button)
.. bokeh-example-metadata:: :apis: bokeh.models.widgets.buttons.Button, bokeh.models.widgets.buttons.Dropdown, bokeh.models.widgets.buttons.Toggle, bokeh.models.widgets.groups.CheckBoxButtonGroup, bokeh.models.widgets.groups.CheckboxGroup, bokeh.models.widgets.groups.RadioButtonGroup, bokeh.models.widgets.groups.RadioGroup # noqa: E501 :refs: :ref:`userguide_layout` > :ref:`userguide_layout_gridplot`, :ref:`userguide_tools` > :ref:`userguide_tools_hover_tool` :keywords: buttons, radio button, checkboxes, toggle button, dropdown ''' from bokeh.document import Document from bokeh.embed import file_html from bokeh.models import (Button, CheckboxButtonGroup, CheckboxGroup, Column, CustomJS, Dropdown, RadioButtonGroup, RadioGroup, Toggle) from bokeh.resources import INLINE from bokeh.util.browser import view button = Button(label="Button (enabled) - has click event", button_type="primary") button.js_on_event("button_click", CustomJS(code="console.log('button: click ', this.toString())")) button.js_on_event("button_click", CustomJS(code="console.log('button: click ', this.toString())")) button_disabled = Button(label="Button (disabled) - no click event", button_type="primary", disabled=True) button_disabled.js_on_event("button_click", CustomJS(code="console.log('button(disabled): click ', this.toString())")) toggle_inactive = Toggle(label="Toggle button (initially inactive)", button_type="success") toggle_inactive.js_on_event('button_click', CustomJS(code="console.log('toggle(inactive): active=' + this.origin.active, this.toString())")) toggle_active = Toggle(label="Toggle button (initially active)", button_type="success", active=True) toggle_active.js_on_event('button_click', CustomJS(code="console.log('toggle(active): active=' + this.origin.active, this.toString())")) menu = [("Item 1", "item_1_value"), ("Item 2", "item_2_value"), None, ("Item 3", "item_3_value")] dropdown = Dropdown(label="Dropdown button", button_type="warning", menu=menu) dropdown.js_on_event("button_click", CustomJS(code="console.log('dropdown: click ' + this.toString())"))
title="my sine wave", tools="crosshair,pan,reset,save,wheel_zoom", x_range=[0, 4 * np.pi], y_range=[-2.5, 2.5]) plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6) # Set up widgets text = TextInput(title="title", value='my sine wave') offset = Slider(title="offset", value=0.0, start=-5.0, end=5.0, step=0.1) amplitude = Slider(title="amplitude", value=1.0, start=-5.0, end=5.0, step=0.1) phase = Slider(title="phase", value=0.0, start=0.0, end=2 * np.pi) freq = Slider(title="frequency", value=1.0, start=0.1, end=5.1, step=0.1) logout = Button(label="logout") logout.js_on_event( "button_click", CustomJS(code="window.location.href='%s'" % curdoc().session_context.logout_url)) # Set up callbacks def update_title(attrname, old, new): plot.title.text = text.value text.on_change('value', update_title) def update_data(attrname, old, new): # Get the current slider values a = amplitude.value
var data = {}; columns = Object.keys(source.data); columns.forEach(function(key) { data[key] = []; }); for (var i = 0; i < source.get_length(); i++){ if (show.includes(source.data['time'][i])){ columns.forEach(function(key) { data[key].push(source.data[key][i]) }); } } displayed_src.data = data; displayed_src.change.emit(); """) button.js_on_event(events.ButtonClick, button_callback) # Update the prediction-map on button click button_callback2 = CustomJS(args=dict(text_input=text_input2, source=geosource2, displayed_src=displayed_src2), code=""" var time = text_input.value; var show = [time, 'No data']; var data = {}; columns = Object.keys(source.data); columns.forEach(function(key) { data[key] = []; }); for (var i = 0; i < source.get_length(); i++){
class side_plot: '''Interactive probability dense plot that changes with the attached slider value''' def __init__(self, infoDict, slider): self.iD = infoDict self.slider = slider x = list(range(self.iD['e_min'], self.iD['e_max'] + 1)) p_d = list(stats.gaussian_kde(self.iD['max_exprs'])(x)) v0, v1 = self.iD['value'] x_i = x[v0:v1 + 1] y_i = p_d[v0:v1 + 1] #source1, for yellow highlighted area; source2, for grey colored area source1 = ColumnDataSource( data=dict(x_=x_i, y_l=[0] * len(x_i), y_u=y_i)) source2 = ColumnDataSource( data=dict(x_=x[:1] + x + x[-1:], y_=[0] + p_d + [0])) self.p = figure(title="Probability density", tools="", background_fill_color="#ffffff", plot_height=210, plot_width=350, logo=None) self.p.x_range.range_padding = 0.01 self.p.y_range.range_padding = 0 ## Draw grey colored area self.p.patch('x_', 'y_', source=source2, color="#000000", alpha=0.2, line_width=0) ## Add Green dashlines self.leftSpan = Span(location=self.slider.value[0], dimension='height', line_color='green', line_dash='dashed', line_width=3) self.rightSpan = Span(location=self.slider.value[1], dimension='height', line_color='green', line_dash='dashed', line_width=3) callback = CustomJS(args=dict(source1=source1, source2=source2, ran=(self.iD['e_min'], self.iD['e_max']), x=x, p_d=p_d, leftSpan=self.leftSpan, rightSpan=self.rightSpan), code=""" var f0 = Math.ceil(cb_obj.value[0]) var f1 = Math.ceil(cb_obj.value[1]) var pad_i = 10 var pad_l = Math.min(f0-ran[0], pad_i) var pad_r = Math.min(ran[1]-f1, pad_i) //console.log(pad_l) //console.log(pad_r) var x_s = x.slice(f0,f1+1) var y_s = p_d.slice(f0,f1+1) leftSpan.location = f0 rightSpan.location = f1 source1.data['x_'] = x_s source1.data['y_u'] = y_s source1.data['y_l'] = [] for (var i = 0; i < x_s.length; i++){source1.data['y_l'].push(0)} source2.data['x_'] = x.slice(f0-pad_l,f1+1+pad_r) source2.data['x_'].unshift(source2.data['x_'][0]) source2.data['x_'].push(source2.data['x_'][source2.data['x_'].length-1]) source2.data['y_'] = p_d.slice(f0-pad_l,f1+1+pad_r) source2.data['y_'].unshift(0) source2.data['y_'].push(0) source2.change.emit() source1.change.emit() """) self.slider.js_on_change('value', callback) ## Value reset button for RangeSlider self.btn = Button(label="Reset", width=3, height=6) self.btn.js_on_event( ButtonClick, CustomJS(args=dict(value=self.iD['value'], slider=self.slider, source2=source2, x_=x[:1] + x + x[-1:], y_=[0] + p_d + [0]), code='''slider.value=value source2.data['x_']=x_ source2.data['y_']=y_ source2.change.emit() ''')) ## Yellow highlight area self.band = Band(base='x_', lower='y_l', upper='y_u', source=source1, level='glyph', fill_alpha=1.0, line_width=1, line_color='black') def show(self): #print(self.iD) self.p.add_layout(self.band) self.p.add_layout(self.leftSpan) self.p.add_layout(self.rightSpan) tool = row(self.slider, self.btn) self.layout = column(tool, self.p) #show(self.layout) return self.layout
def plot(tables, output_filename): ''' This is the plot function that uses Bokeh functions and widgets to make an interactive hexagon plot. This function recieves: - tables: dictionary with tables used to create arrays of repeated x, y coordinates (depending on the counts) for the hexagon plot. - output_filename: filename of .html output in the plots folder The coordinate arrays are used to create a pandas dataframe with Bokeh functions. This dataframe contains the q, r coordinates and counts used to plot the hexagons. To this dataframe, extra information is added (e.g. most common chemicals), which is displayed in the hover tooltip. Gaussian blur is added to copies of this dataframe and given as input to the Bokeh slider widget. Other widgets are added as well, for saturation, normalisation etc. Bokeh allows to customize these widges with javascript code. The hexagon plot is saved as a .html file and also shown in the browser. ''' file_name = 'plots/' + str(output_filename) + '.html' output_file(file_name) # Blur and saturation values BLUR_MAX = 3 BLUR_STEP_SIZE = 1 SATURATION_MAX = 5 SATURATION_STEP_SIZE = 0.25 # First, create array for plot properties ( ratio, size of hexagons etc.) default_term = list(tables.keys())[0] x, y, ids = create_array(tables[default_term]['table'], normalisation=False) # Hexagon plot properties length = len(x) orientation = 'flattop' ratio = ((max(y) - min(y)) / (max(x) - min(x))) size = 10 / ratio h = sqrt(3) * size h = h * ratio title = 'Hexbin plot for ' + str( length) + ' annotated chemicals with query ' + str(default_term) # make figure p = figure(title=title, x_range=[min(x) - 0.5, max(x) + 0.5], y_range=[0 - (h / 2), max(y) + 100], tools="wheel_zoom,reset,save", background_fill_color='#440154') p.grid.visible = False p.xaxis.axis_label = "log(P)" p.yaxis.axis_label = "mass in Da" p.xaxis.axis_label_text_font_style = 'normal' p.yaxis.axis_label_text_font_style = 'normal' # source for plot term_to_source, term_to_metadata, options = make_plot_sources( tables, size, ratio, orientation, BLUR_MAX, BLUR_STEP_SIZE) # start source for plot, this is the source that is first displayed in the hexagon figure x, y, ids = create_array(tables[default_term]['table'], normalisation=False) df = hexbin(x, y, ids, size, aspect_scale=ratio, orientation=orientation) df = add_counts(df, tables[default_term]['table']) source = ColumnDataSource(df) metadata = term_to_metadata[default_term] metadata = return_html(metadata) # color mapper mapper = linear_cmap('scaling', 'Viridis256', 0, max(source.data['scaling'])) # plot hex = p.hex_tile(q="q", r="r", size=size, line_color=None, source=source, aspect_scale=ratio, orientation=orientation, fill_color=mapper) # HOVER TOOLTIPS = return_tooltip() code_callback_hover = return_code('hover') callback_hover = CustomJS(code=code_callback_hover) hover = HoverTool(tooltips=TOOLTIPS, callback=callback_hover, show_arrow=False) p.add_tools(hover) # WIDGETS slider1 = Slider(start=1, end=SATURATION_MAX, value=1, step=SATURATION_STEP_SIZE, title="Saturation", width=100) slider2 = Slider(start=0, end=BLUR_MAX, value=0, step=BLUR_STEP_SIZE, title="Blur", width=100) checkbox = CheckboxGroup(labels=["TFIDF"], active=[]) radio_button_group = RadioGroup(labels=["Viridis256", "Greys256"], active=0) button = Button(label="Metadata", button_type="default", width=100) multi_select = MultiSelect(title=output_filename, value=[default_term], options=options, width=100, height=300) # WIDGETS CODE FOR CALLBACK code_callback_slider1 = return_code('slider1') code_callback_slider2 = return_code('slider2') code_callback_checkbox = return_code('checkbox') code_callback_rbg = return_code('rbg') code_callback_button = return_code('button') code_callback_ms = return_code('multi_select') # WIDGETS CALLBACK callback_slider1 = CustomJS(args={ 'source': source, 'mapper': mapper }, code=code_callback_slider1) callback_slider2 = CustomJS(args={ 'source': source, 'mapper': mapper, 'slider1': slider1, 'multi_select': multi_select, 'checkbox': checkbox, 'term_to_source': term_to_source, 'step_size': BLUR_STEP_SIZE }, code=code_callback_slider2) callback_checkbox = CustomJS(args={ 'source': source, 'term_to_source': term_to_source, 'multi_select': multi_select, 'step_size': BLUR_STEP_SIZE, 'slider1': slider1, 'slider2': slider2, 'mapper': mapper }, code=code_callback_checkbox) callback_radio_button_group = CustomJS(args={ 'p': p, 'mapper': mapper, 'Viridis256': Viridis256, 'Greys256': Greys256 }, code=code_callback_rbg) callback_button = CustomJS(args={ 'term_to_metadata': term_to_metadata, 'multi_select': multi_select }, code=code_callback_button) callback_ms = CustomJS(args={ 'source': source, 'term_to_source': term_to_source, 'checkbox': checkbox, 'metadata': metadata, 'step_size': BLUR_STEP_SIZE, 'slider2': slider2, 'slider1': slider1, 'p': p, 'mapper': mapper }, code=code_callback_ms) # # WIDGETS INTERACTION slider1.js_on_change('value', callback_slider1) slider2.js_on_change('value', callback_slider2) checkbox.js_on_change('active', callback_checkbox) radio_button_group.js_on_change('active', callback_radio_button_group) button.js_on_event(events.ButtonClick, callback_button) multi_select.js_on_change("value", callback_ms) # LAYOUT layout = row( multi_select, p, column(slider1, slider2, checkbox, radio_button_group, button)) show(layout)
s.close() server_info = ColumnDataSource(dict(server_ip=[host_ip])) js_callback = CustomJS(args=dict(server_ip=server_info), code=open(join(dirname(__file__), "readFile.js")).read()) # add a button widget and configure with the call back button = Button(label="Load File", id="uploadButton", width=300, button_type="warning") button2 = Button(label="Plot Data", width=300, button_type="warning") button2.on_click(plot_data) button.js_on_event(events.ButtonClick, js_callback) # Create html input in Div widget fileInput = Div(text=""" <h1>Select File</h1> <input type="file" id="upload"> """, width=350) filePreview = Div( text= '<h1 id="fileContentsTitle"> File Preview </h1> <div id="fileContents">x,y</div>', id="filePreview", width=600) fileReadError = Div(text='', width=600)
def getTimeSeries_works2(df_tws): def display_event(div, attributes=[], style='float:left;clear:left;font_size=13px'): "Build a suitable CustomJS to display the current event in the div model." return CustomJS(args=dict(div=div), code=""" var attrs = %s; var args = []; for (var i = 0; i<attrs.length; i++) { args.push(attrs[i] + '=' + Number(cb_obj[attrs[i]]).toFixed(2)); } var line = "<span style=%r><b>" + cb_obj.event_name + "</b>(" + args.join(", ") + ")</span>\\n"; var text = div.text.concat(line); var lines = text.split("\\n") if (lines.length > 35) lines.shift(); div.text = lines.join("\\n"); """ % (attributes, style)) x = np.random.random(size=4000) * 100 y = np.random.random(size=4000) * 100 radii = np.random.random(size=4000) * 1.5 colors = [ "#%02x%02x%02x" % (int(r), int(g), 150) for r, g in zip(50 + 2 * x, 30 + 2 * y) ] p = figure(tools="pan,wheel_zoom,zoom_in,zoom_out,reset") p.scatter(x, y, radius=np.random.random(size=4000) * 1.5, fill_color=colors, fill_alpha=0.6, line_color=None) div = Div(width=400, height=p.plot_height, height_policy="fixed") button = Button(label="Button", button_type="success") layout = column(button, row(p, div)) ## Events with no attributes button.js_on_event(events.ButtonClick, display_event(div)) # Button click p.js_on_event(events.LODStart, display_event(div)) # Start of LOD display p.js_on_event(events.LODEnd, display_event(div)) # End of LOD display ## Events with attributes point_attributes = ['x', 'y', 'sx', 'sy'] # Point events wheel_attributes = point_attributes + ['delta'] # Mouse wheel event pan_attributes = point_attributes + ['delta_x', 'delta_y'] # Pan event pinch_attributes = point_attributes + ['scale'] # Pinch event point_events = [ events.Tap, events.DoubleTap, events.Press, events.PressUp, events.MouseMove, events.MouseEnter, events.MouseLeave, events.PanStart, events.PanEnd, events.PinchStart, events.PinchEnd, ] for event in point_events: p.js_on_event(event, display_event(div, attributes=point_attributes)) p.js_on_event(events.MouseWheel, display_event(div, attributes=wheel_attributes)) p.js_on_event(events.Pan, display_event(div, attributes=pan_attributes)) p.js_on_event(events.Pinch, display_event(div, attributes=pinch_attributes)) output_file("js_events.html", title="JS Events Example") return layout
def main(filename, src, dst, outputFileName): df = pd.read_csv(filename) df = df.replace(nan, 'unknown') valuetype = 'Flows' ########################################################################################### ##################################### CREATE DF ####################################### Csrcval = src Cdstval = dst dfcountry = df[(df['src_country'] == Csrcval) & (df['dst_country'] == Cdstval)] c_ind = list(dfcountry['src_org'].unique()) c_col = list(dfcountry['dst_org'].unique()) c_dfFlows = pd.DataFrame(index=c_ind, columns=c_col, data=0) c_dfPkts = pd.DataFrame(index=c_ind, columns=c_col, data=0) c_dfOcts = pd.DataFrame(index=c_ind, columns=c_col, data=0) dftest = dfcountry.groupby(['src_org', 'dst_org']).size() for x in dftest.index.values.tolist(): c_dftemp = dfcountry[(dfcountry['src_org'] == x[0]) & (dfcountry['dst_org'] == x[1])] print(f'Pkts from {x[0]} to {x[1]}') c_dfPkts.at[[x[0]], [x[1]]] = c_dftemp['dPkts'].sum() print(c_dftemp['dPkts'].sum()) print(f'Bytes from {x[0]} to {x[1]}') c_dfOcts.at[[x[0]], [x[1]]] = c_dftemp['dOctets'].sum() print(c_dftemp['dOctets'].sum()) print(f'Flows from {x[0]} to {x[1]}') c_dfFlows.at[[x[0]], [x[1]]] = len(c_dftemp) print(len(c_dftemp)) # rename column c_dfPkts.columns.name = Cdstval c_dfOcts.columns.name = Cdstval c_dfFlows.columns.name = Cdstval # create df to be visualized dfViz = pd.DataFrame(c_dfFlows.stack(), columns=['value']).reset_index() dfViz.columns = ['src_org', 'dst_org', 'value'] dfViz2 = pd.DataFrame(c_dfPkts.stack(), columns=['value']).reset_index() dfViz2.columns = ['src_org', 'dst_org', 'value'] dfViz3 = pd.DataFrame(c_dfOcts.stack(), columns=['value']).reset_index() dfViz3.columns = ['src_org', 'dst_org', 'value'] ########################################################################################### ##################################### COLOR MAP ######################################## colors = RdBu(500) c_mapper = LinearColorMapper(palette=colors, low=dfViz.value.min(), high=dfViz.value.max()) c_mapper2 = LinearColorMapper(palette=colors, low=dfViz2.value.min(), high=dfViz2.value.max()) c_mapper3 = LinearColorMapper(palette=colors, low=dfViz3.value.min(), high=dfViz3.value.max()) ########################################################################################### ##################################### LIST CHECK ####################################### srclist = list(dfViz.src_org.unique()) dstlist = list(dfViz.dst_org.unique()) if len(srclist) == 1 and len(dstlist) == 1: return 1 else: ########################################################################################### ####################################### PLOT 1 ######################################## TOOLS = "hover,save,pan,box_zoom,reset,wheel_zoom,tap" c_p = figure(title="Interactive Visualization", x_range=c_ind, y_range=c_col, x_axis_location="above", plot_width=900, plot_height=800, tools=TOOLS, toolbar_location='below', tooltips=[('Source', '@src_org'), ('Destination', '@dst_org'), (valuetype, '@value')]) c_p.title.align = 'center' c_p.grid.grid_line_color = None c_p.axis.axis_line_color = 'white' c_p.axis.major_tick_line_color = None c_p.axis.major_label_text_font_size = "10pt" c_p.axis.major_label_standoff = 0 c_p.xaxis.axis_label = 'Source' c_p.yaxis.axis_label = 'Destination' c_p.xaxis.major_label_orientation = pi / 3 c_heatmap = c_p.rect(x='src_org', y='dst_org', width=1, height=1, source=dfViz, fill_color={ 'field': 'value', 'transform': c_mapper }, line_color='white') c_color_bar = ColorBar(color_mapper=c_mapper, major_label_text_font_size="10pt", ticker=BasicTicker(desired_num_ticks=10), label_standoff=12, border_line_color=None, location=(0, 0)) c_color_bar.formatter.use_scientific = False c_p.add_layout(c_color_bar, 'right') ########################################################################################### ####################################### PLOT 2 ######################################## valuetype = 'dPkts' c_p2 = figure(title="Interactive Visualization", x_range=c_ind, y_range=c_col, x_axis_location="above", plot_width=900, plot_height=800, tools=TOOLS, toolbar_location='below', tooltips=[('Source', '@src_org'), ('Destination', '@dst_org'), (valuetype, '@value')]) c_p2.title.align = 'center' c_p2.grid.grid_line_color = None c_p2.axis.axis_line_color = 'white' c_p2.axis.major_tick_line_color = None c_p2.axis.major_label_text_font_size = "10pt" c_p2.axis.major_label_standoff = 0 c_p2.xaxis.axis_label = 'Source' c_p2.yaxis.axis_label = 'Destination' c_p2.xaxis.major_label_orientation = pi / 3 c_heatmap2 = c_p2.rect(x='src_org', y='dst_org', width=1, height=1, source=dfViz2, fill_color={ 'field': 'value', 'transform': c_mapper2 }, line_color='white') c_color_bar2 = ColorBar(color_mapper=c_mapper2, major_label_text_font_size="10pt", ticker=BasicTicker(desired_num_ticks=10), label_standoff=12, border_line_color=None, location=(0, 0)) c_color_bar2.formatter.use_scientific = False c_p2.add_layout(c_color_bar2, 'right') ########################################################################################### ####################################### PLOT 3 ######################################## valuetype = 'dOctets' c_p3 = figure(title="Interactive Visualization", x_range=c_ind, y_range=c_col, x_axis_location="above", plot_width=900, plot_height=800, tools=TOOLS, toolbar_location='below', tooltips=[('Source', '@src_org'), ('Destination', '@dst_org'), (valuetype, '@value')]) c_p3.title.align = 'center' c_p3.grid.grid_line_color = None c_p3.axis.axis_line_color = 'white' c_p3.axis.major_tick_line_color = None c_p3.axis.major_label_text_font_size = "10pt" c_p3.axis.major_label_standoff = 0 c_p3.xaxis.axis_label = 'Source' c_p3.yaxis.axis_label = 'Destination' c_p3.xaxis.major_label_orientation = pi / 3 c_heatmap3 = c_p3.rect(x='src_org', y='dst_org', width=1, height=1, source=dfViz3, fill_color={ 'field': 'value', 'transform': c_mapper3 }, line_color='white') c_color_bar3 = ColorBar(color_mapper=c_mapper2, major_label_text_font_size="10pt", ticker=BasicTicker(desired_num_ticks=10), label_standoff=12, border_line_color=None, location=(0, 0)) c_color_bar3.formatter.use_scientific = False c_p3.add_layout(c_color_bar3, 'right') ########################################################################################### ###################################### BUTTONS ######################################## homeButton = Button(label="Back to Homepage") col = column(c_p, c_p2, c_p3) radioBtn = RadioButtonGroup( labels=["All", "Flows", "Packets", "Bytes"], active=0, width=300) radioCallback = CustomJS(args=dict(plots=[c_p, c_p2, c_p3], col=col, radioBtn=radioBtn), code=""" const children = [] if (radioBtn.active == 0) { children.push(plots[0]) children.push(plots[1]) children.push(plots[2]) } if (radioBtn.active == 1) { children.push(plots[0]) } if (radioBtn.active == 2) { children.push(plots[1]) } if (radioBtn.active == 3) { children.push(plots[2]) } col.children = children """) radioBtn.js_on_change('active', radioCallback) homeButtonCallback = CustomJS(code=""" window.location.href = "http://engineering.utep.edu:62432"; """) homeButton.js_on_event(events.ButtonClick, homeButtonCallback) jsonString = dfViz.to_json(orient='table', index=False) callback = CustomJS(args=dict(plots=[c_p, c_p2, c_p3], src=srclist, dst=dstlist, file=filename, dataframe=jsonString), code=""" // the event that triggered the callback is cb_obj: // The event type determines the relevant attributes // console.log('Tap event occurred at x-position: ' + cb_obj.x) // console.log('Tap event occurred at y-position: ' + cb_obj.y) // console.log('Tap event occurred at y-position: ' + parseInt(cb_obj.y)) console.log('Tap event occurred at x-position: ' + src[parseInt(cb_obj.x)]); console.log('Tap event occurred at y-position: ' + dst[parseInt(cb_obj.y)]); console.log('Tap event occurred at value:'); df = JSON.parse(dataframe); console.log(df); // console.log(df.data[4]); function findObjectByKey(array, key1, value1, key2, value2) { for (var i = 0; i < array.length; i++) { // console.log(i); // console.log(array[i][key1]+' : '+value1+' VS '+array[i][key2]+' : '+ value2); if (array[i][key1] === value1 && array[i][key2] === value2) { return array[i]; } } return null; } var obj = findObjectByKey(df.data, 'src_org', src[parseInt(cb_obj.x)], 'dst_org', dst[parseInt(cb_obj.y)]); console.log(obj.value); if (obj.value == 0) { alert('Selected pair has no communication'); plots[0].reset.emit(); plots[1].reset.emit(); plots[2].reset.emit(); } else { var form = document.createElement('form'); form.setAttribute('method', 'post'); form.setAttribute('action', '/asHist'); form.style.display = 'none'; var fileName = document.createElement("textarea"); fileName.type = "textarea"; fileName.name = "FileName"; fileName.id = "FileName"; fileName.value = file; form.appendChild(fileName); var sourceVal = document.createElement("textarea"); sourceVal.type = "textarea"; sourceVal.name = "SrcVal"; sourceVal.id = "SrcVal"; sourceVal.value = src[parseInt(cb_obj.x)]; form.appendChild(sourceVal); var destVal = document.createElement("textarea"); destVal.type = "textarea"; destVal.name = "DestVal"; destVal.id = "DestVal"; destVal.value = dst[parseInt(cb_obj.y)]; form.appendChild(destVal); document.body.appendChild(form); console.log(fileName.value); console.log(sourceVal.value); console.log(destVal.value); form.submit(); plots[0].reset.emit(); plots[1].reset.emit(); plots[2].reset.emit(); } """) c_p.js_on_event('tap', callback) c_p2.js_on_event('tap', callback) c_p3.js_on_event('tap', callback) ########################################################################################### ###################################### OUTPUT ######################################### output_file("continent_test.ejs") layout = column(row(homeButton, radioBtn), col) save(layout, filename=outputFileName, title='Organization Level') return 0
def plot(tables, output_filename, xmin, xmax, ymin, ymax, superterm): ''' This is the plot function that uses Bokeh functions and widgets to make an interactive hexagon plot. This function recieves: - tables: dictionary with tables used to create arrays of repeated x, y coordinates (depending on the counts) for the hexagon plot. - output_filename: filename of .html output in the plots folder The coordinate arrays are used to create a pandas dataframe with Bokeh functions. This dataframe contains the q, r coordinates and counts used to plot the hexagons. To this dataframe, extra information is added (e.g. most common chemicals), which is displayed in the hover tooltip. Gaussian blur is added to copies of this dataframe and given as input to the Bokeh slider widget. Other widgets are added as well, for saturation, normalization etc. Bokeh allows to customize these widges with javascript code. The hexagon plot is saved as a .html file and also shown in the browser. ''' file_name = 'plots/' + str(output_filename) + '.html' output_file(file_name) # Blur and saturation values BLUR_MAX = 4 BLUR_STEP_SIZE = 0.25 SATURATION_MAX = 5 SATURATION_STEP_SIZE = 0.25 # Hexagon plot properties SIZE_HEXAGONS = 10 orientation = 'flattop' #bokeh alows 2 different hexagon orientations which also influences hexagon size calculations, but we currently have only calculated blur distances for this orientation ratio = ((ymax - ymin) / (xmax - xmin)) size = SIZE_HEXAGONS / ratio hexagon_height = sqrt(3) * size hexagon_height = hexagon_height * ratio # make figure p = figure(x_range=[xmin, xmax], y_range=[ymin - (hexagon_height / 2), ymax], tools="wheel_zoom,reset,save", background_fill_color='#440154') p.grid.visible = False p.xaxis.axis_label = "log(P)" p.yaxis.axis_label = "mass in Da" p.xaxis.axis_label_text_font_style = 'normal' p.yaxis.axis_label_text_font_style = 'normal' # term_to_source, term_to_metadata, options = make_plot_sources(tables, size, ratio, orientation, BLUR_MAX, BLUR_STEP_SIZE) # source for widgets term_to_source = dict() term_to_class = dict() term_to_metadata = dict() options = [] for term in tables.keys(): options.append((term, term)) table = tables[term]['table'] if superterm: source = create_class_source(table, term, size, ratio, orientation, superterm) term_to_class[term] = {} term_to_class[term]['show_class'] = True term_to_class[term]['source'] = source else: term_to_class[term] = {'show_class': False} source, title = create_data_source(table, term, size, ratio, orientation, BLUR_MAX, BLUR_STEP_SIZE) metadata = return_html(tables[term]['metadata']) term_to_source[term] = {'source': source, 'title': title} term_to_metadata[term] = metadata # hex = p.hex_tile(q='q', r="r", size=size, line_color=None, source=source, aspect_scale=ratio,orientation=orientation, # fill_color='pink' ) # show(p) # make default souce for plot, this is the first source shown in the plot, and also works like a container. Old data is thrown out and new data is thrown in. default_term = list(tables.keys())[0] # pick the first one metadata = tables[default_term]['metadata'] metadata = return_html(metadata) table = tables[default_term]['table'] source, title = create_data_source(table, default_term, size, ratio, orientation, BLUR_MAX, BLUR_STEP_SIZE) p.title.text = title # color mapper mapper = linear_cmap('scaling', 'Viridis256', 0, max(source.data['scaling'])) # plot hex = p.hex_tile(q="q", r="r", size=size, line_color=None, source=source, aspect_scale=ratio, orientation=orientation, fill_color=mapper) if superterm: source_class = term_to_class[default_term]['source'] class_hex = p.hex_tile(q='q', r="r", size=size, line_color=None, source=source_class, aspect_scale=ratio, orientation=orientation, fill_color='pink', fill_alpha=0.7) class_hex.visible = False # HOVER TOOLTIPS = return_JS_code('tooltips') TOOLTIPS_tfidf = return_JS_code('tooltips_tfidf') code_callback_hover = return_JS_code('hover') callback_hover = CustomJS(code=code_callback_hover) hover = HoverTool(tooltips=TOOLTIPS, callback=callback_hover, show_arrow=False) p.add_tools(hover) # WIDGETS slider1 = Slider(start=1, end=SATURATION_MAX, value=1, step=SATURATION_STEP_SIZE, title="Saturation", width=100) slider2 = Slider(start=0, end=BLUR_MAX, value=0, step=BLUR_STEP_SIZE, title="Blur", width=100) checkbox = CheckboxGroup(labels=["TFIDF"], active=[]) radio_button_group = RadioGroup(labels=["Viridis256", "Greys256"], active=0) button = Button(label="Metadata", button_type="default", width=100) multi_select = MultiSelect(title=output_filename, value=[default_term], options=options, width=100, height=300) if superterm: label = "Show " + str(superterm) checkbox_class = CheckboxGroup(labels=[label], active=[]) # WIDGETS CODE FOR CALLBACK code_callback_slider1 = return_JS_code('slider1') code_callback_slider2 = return_JS_code('slider2') code_callback_checkbox = return_JS_code('checkbox') code_callback_rbg = return_JS_code('rbg') code_callback_button = return_JS_code('button') code_callback_ms = return_JS_code('multi_select') if superterm: code_callback_class = return_JS_code('class') # WIDGETS CALLBACK callback_slider1 = CustomJS(args={ 'source': source, 'mapper': mapper, 'slider2': slider2, 'checkbox': checkbox }, code=code_callback_slider1) callback_slider2 = CustomJS(args={ 'source': source, 'mapper': mapper, 'slider1': slider1, 'checkbox': checkbox }, code=code_callback_slider2) callback_checkbox = CustomJS(args={ 'source': source, 'slider1': slider1, 'slider2': slider2, 'mapper': mapper, 'hover': hover, 'tooltips': TOOLTIPS, 'tooltips_tfidf': TOOLTIPS_tfidf }, code=code_callback_checkbox) callback_radio_button_group = CustomJS(args={ 'p': p, 'multi_select': multi_select, 'mapper': mapper, 'term_to_class': term_to_class, 'Viridis256': Viridis256, 'Greys256': Greys256 }, code=code_callback_rbg) callback_button = CustomJS(args={ 'term_to_metadata': term_to_metadata, 'multi_select': multi_select }, code=code_callback_button) callback_ms = CustomJS(args={ 'source': source, 'term_to_source': term_to_source, 'term_to_class': term_to_class, 'checkbox': checkbox, 'slider2': slider2, 'slider1': slider1, 'p': p, 'mapper': mapper }, code=code_callback_ms) if superterm: callback_radio_button_group = CustomJS(args={ 'p': p, 'multi_select': multi_select, 'class_hex': class_hex, 'term_to_class': term_to_class, 'mapper': mapper, 'Viridis256': Viridis256, 'Greys256': Greys256 }, code=code_callback_rbg) callback_class = CustomJS(args={ 'multi_select': multi_select, 'term_to_class': term_to_class, 'class_hex': class_hex }, code=code_callback_class) callback_ms = CustomJS(args={ 'source': source, 'term_to_source': term_to_source, 'checkbox': checkbox, 'slider2': slider2, 'slider1': slider1, 'p': p, 'mapper': mapper, 'checkbox_class': checkbox_class, 'class_hex': class_hex, 'term_to_class': term_to_class }, code=code_callback_ms) # WIDGETS INTERACTION slider1.js_on_change('value', callback_slider1) slider2.js_on_change('value', callback_slider2) checkbox.js_on_change('active', callback_checkbox) radio_button_group.js_on_change('active', callback_radio_button_group) button.js_on_event(events.ButtonClick, callback_button) multi_select.js_on_change("value", callback_ms) if superterm: checkbox_class.js_on_change('active', callback_class) # LAYOUT if superterm: layout = row( multi_select, p, column(slider1, slider2, checkbox, checkbox_class, radio_button_group, button)) else: layout = row( multi_select, p, column(slider1, slider2, checkbox, radio_button_group, button)) show(layout)
# Add a div to display events and a button to trigger button click events div = Div(width=1000) button = Button(label="Button", button_type="success") layout = column(button, row(p, div)) point_attributes = ['x','y','sx','sy'] pan_attributes = point_attributes + ['delta_x', 'delta_y'] pinch_attributes = point_attributes + ['scale'] wheel_attributes = point_attributes+['delta'] ## Register Javascript event callbacks # Button event button.js_on_event(events.ButtonClick, display_event(div)) # LOD events p.js_on_event(events.LODStart, display_event(div)) p.js_on_event(events.LODEnd, display_event(div)) # Point events p.js_on_event(events.Tap, display_event(div, attributes=point_attributes)) p.js_on_event(events.DoubleTap, display_event(div, attributes=point_attributes)) p.js_on_event(events.Press, display_event(div, attributes=point_attributes)) # Mouse wheel event p.js_on_event(events.MouseWheel, display_event(div,attributes=wheel_attributes)) # Mouse move, enter and leave
from bokeh.layouts import column, row from bokeh.models import Button, CustomJS, PasswordInput, PreText, TextInput from bokeh.plotting import output_file, show output_file("using_password_input.html", title="Password Field") USER = "******" PASSWD = "Bok3h" text = PreText(text="LOGIN TO KNOW THE SECRET:") user = TextInput(placeholder="username", title=f"(UserName: {USER})") password = PasswordInput(placeholder="password", title=f"(Password: {PASSWD})") button = Button(label="GO!", width=150) secret = PreText() # Secret information displayed if correct password entered # Verify if the password typed is bokeh using a JS script verify = CustomJS(args=dict(user=user, password=password, secret=secret), code=""" secret.text = 'Wrong Password.'; if (user.value == %r && password.value == %r) { secret.text = 'Correct Password. The Secret is 42.'; } """ % (USER, PASSWD)) password.js_on_change('value', verify) button.js_on_event('button_click', verify) layout = row(column(text, user, password, button), secret) show(layout)
update_plot_points(type_filter) update_emotions_points(type_filter) update_frequency_points(type_filter) update_wordcloud_points(type_filter) # print("callback_filter_4", timeit.timeit('output = 10*5')) general_dict['filter_4'] = MultiSelect( value=general_dict['full_segment_filter_list'], options=general_dict['full_segment_filter_list'], height=130) button_3 = Button(label="Select All") button_4 = Button(label="Select None") button_3.js_on_event( 'button_click', CustomJS(args=dict(s=general_dict['filter_4']), code="s.value=s.options")) button_4.js_on_event( 'button_click', CustomJS(args=dict(s=general_dict['filter_4']), code="s.value=[]")) general_dict['filter_4'].on_change('value', callback_filter_4) # def callback_filter_2(attr, old, new): # update_filters() # filter_dfs() # for type_filter in general_dict['type_list']: # update_plot_points(type_filter) # update_emotions_points(type_filter) # update_frequency_points(type_filter) # update_wordcloud_points(type_filter)
def get(self, request): s1 = ColumnDataSource(data=test_data) TOOLTIPS = [ ("index", "$index"), ("(x,y)", "($x, $y)"), ("patient id", "@patient_id"), ] # DEFAULT_TOOLS = "pan,wheel_zoom,box_zoom,save,reset,help" p = figure( tools= "reset, pan, wheel_zoom, box_zoom, box_select, lasso_select, save, help", tooltips=TOOLTIPS, title="Mouse over the dots") # p.scatter(x, y, radius=1, fill_alpha=0.6, line_color=None) p.circle('x', 'y', size=20, source=s1, alpha=0.6) s1.selected.js_on_change( 'indices', CustomJS(args=dict(s1=s1), code=""" var inds = cb_obj.indices; var d1 = s1.data; for (var i = 0; i < inds.length; i++) { console.log(d1['x'][inds[i]] +'|'+d1['y'][inds[i]] +'|'+ d1['patient_id'][inds[i]]); } """)) button = Button(label="Button") div = Div(id="mydiv", name="div_selected_data", width=400) # Events with no attributes button.js_on_event( events.ButtonClick, CustomJS(args=dict(div=div), code=""" div.text = "Button is clicked!"; """)) columns = [ TableColumn(field="patient_id", title="Patient ID"), TableColumn(field="x", title="X"), TableColumn(field="y", title="Y"), ] source = ColumnDataSource(test_data) data_table = DataTable(source=source, columns=columns, width=400, height=280) # , widgetbox(data_table) # layout = column(button, row(p, div), data_table) layout = column(button, row(p, div), data_table) script, div = components(layout) # script, div = components(layout) return render(request, 'report_radiomic_brain.html', { 'script': script, 'div': div })
from bokeh.events import ButtonClick from bokeh.layouts import column from bokeh.models import Button, CustomJS from bokeh.plotting import show from fontawesome_icon import FontAwesomeIcon btn = Button(icon=FontAwesomeIcon(icon_name="thumbs-o-up", size=2), label="It works!") btn.js_on_event(ButtonClick, CustomJS(code="alert('It works!')")) show(column(btn))
def render_basic( itmdt: Intermediate, yscale: str, plot_width: int, plot_height: int, ) -> Box: """ Render plots and dataset stats from plot(df) """ # pylint: disable=too-many-locals figs = list() for col, dtype, data in itmdt["data"]: if is_dtype(dtype, Nominal()): df, total_grps, miss_pct = data fig = bar_viz( df[:-1], total_grps, miss_pct, col, yscale, plot_width, plot_height, False, ) figs.append(fig) elif is_dtype(dtype, Continuous()): df, miss_pct = data fig = hist_viz(df, miss_pct, col, yscale, plot_width, plot_height, False) figs.append(fig) elif is_dtype(dtype, DateTime()): df, timeunit, miss_pct = data fig = dt_line_viz(df, col, timeunit, yscale, plot_width, plot_height, False, miss_pct) figs.append(fig) stats_section = stats_viz(itmdt["statsdata"], plot_width=plot_width, plot_height=plot_height) plot_section = gridplot( children=figs, sizing_mode=None, toolbar_location=None, ncols=3, ) button = Button(label="Show Stats Info", width=plot_width * 3, button_type="primary") button.js_on_event( ButtonClick, CustomJS( args={ "button": button, "div": stats_section }, code=""" let buttonLabel = button.label let isDivVisible = div.visible div.visible = isDivVisible ? false : true button.label = (buttonLabel === 'Hide Stats Info') ? 'Show Stats Info' : 'Hide Stats Info' """, ), ) return column(button, stats_section, plot_section)