def test_js_on_change_executes(self, bokeh_model_page) -> None: button = Dropdown(label="Dropdown button", menu=items, css_classes=["foo"]) button.js_on_event('menu_item_click', CustomJS(code=RECORD("value", "this.item"))) page = bokeh_model_page(button) button = page.driver.find_element_by_css_selector('.foo button') button.click() item = page.driver.find_element_by_css_selector(".foo .bk-menu > *:nth-child(1)") item.click() results = page.results assert results == {'value': "item_1_value"} button = page.driver.find_element_by_css_selector('.foo button') button.click() item = page.driver.find_element_by_css_selector(".foo .bk-menu > *:nth-child(3)") item.click() results = page.results assert results == {'value': "item_3_value"} button = page.driver.find_element_by_css_selector('.foo button') button.click() item = page.driver.find_element_by_css_selector(".foo .bk-menu > *:nth-child(2)") item.click() results = page.results assert results == {'value': "item_2_value"} assert page.has_no_console_errors()
def test_js_on_change_executes(self, bokeh_model_page): button = Dropdown(label="Dropdown button", menu=items, css_classes=["foo"]) button.js_on_event('menu_item_click', CustomJS(code=RECORD("value", "this.item"))) page = bokeh_model_page(button) button = page.driver.find_element_by_css_selector('.foo button') button.click() item = page.driver.find_element_by_css_selector(".foo .bk-menu > *:nth-child(1)") item.click() results = page.results assert results == {'value': "item_1_value"} button = page.driver.find_element_by_css_selector('.foo button') button.click() item = page.driver.find_element_by_css_selector(".foo .bk-menu > *:nth-child(3)") item.click() results = page.results assert results == {'value': "item_3_value"} button = page.driver.find_element_by_css_selector('.foo button') button.click() item = page.driver.find_element_by_css_selector(".foo .bk-menu > *:nth-child(2)") item.click() results = page.results assert results == {'value': "item_2_value"} assert page.has_no_console_errors()
def make_dropdown(prop, menu): dropdown = Dropdown(label=prop, menu=menu) cb = CustomJS(args=dict(lines=lines, prop=prop), code=""" for (let i = 0; i < lines.length; i++) { const glyph = lines[i].glyph; glyph[prop] = cb_obj.item; } """) dropdown.js_on_event("menu_item_click", cb) return dropdown
def test_js_on_change_executes(self, bokeh_model_page: BokehModelPage) -> None: button = Dropdown(label="Dropdown button", menu=items) button.js_on_event('menu_item_click', CustomJS(code=RECORD("value", "this.item"))) page = bokeh_model_page(button) button_el = find_element_for(page.driver, button, "button") button_el.click() item = find_element_for(page.driver, button, ".bk-menu > *:nth-child(1)") item.click() results = page.results assert results == {'value': "item_1_value"} button_el = find_element_for(page.driver, button, "button") button_el.click() item = find_element_for(page.driver, button, ".bk-menu > *:nth-child(3)") item.click() results = page.results assert results == {'value': "item_3_value"} button_el = find_element_for(page.driver, button, "button") button_el.click() item = find_element_for(page.driver, button, ".bk-menu > *:nth-child(2)") item.click() results = page.results assert results == {'value': "item_2_value"} assert page.has_no_console_errors()
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()) """)) # choice menu GUI OPTIONS = [str(i) for i in range(20)] multi_choice = MultiChoice(value=["foo", "baz"], options=OPTIONS) multi_choice.js_on_change( "value", CustomJS(code="""
button_type="success", active=True) toggle_active.js_on_click( CustomJS( code= "console.log('toggle(active): active=' + this.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_click( CustomJS(code="console.log('dropdown: click ' + this.toString())")) dropdown.js_on_event( "menu_item_click", CustomJS(code="console.log('dropdown: ' + this.item, this.toString())")) dropdown_disabled = Dropdown(label="Dropdown button (disabled)", button_type="warning", disabled=True, menu=menu) dropdown_disabled.js_on_click( CustomJS( code="console.log('dropdown(disabled): click ' + this.toString())")) dropdown_disabled.js_on_event( "menu_item_click", CustomJS( code="console.log('dropdown(disabled): ' + this.item, this.toString())" ))
def plot_index_option_chain_bids(self): nse_obj = nse() index_option_chain = nse_obj.get_index_option_chain("NIFTY") ############################ Create dictionary of symbol ############### # Create a dictionary indexed by date bids_per_expiry = collections.defaultdict(list) for record in index_option_chain['records']['data']: # print(record) if 'CE' in record: expiry_record = {} expiry_record['strikePrice'] = record['strikePrice'] expiry_record['bidprice'] = record['CE']['bidprice'] expiry_record['openInterest'] = record['CE']['openInterest'] expiry_string = str(record['expiryDate']) bids_per_expiry[expiry_string].append(expiry_record) x = [] y = [] desc_rend = [] oi = [] for key in bids_per_expiry: strike_price_list = [] bid_price_list = [] open_interest_list = [] expiry_date_list = [] for record in bids_per_expiry[key]: strike_price_list.append(record['strikePrice']) bid_price_list.append(record['bidprice']) open_interest_list.append(record['openInterest']) expiry_date_list.append(key) x.append(strike_price_list) y.append(bid_price_list) desc_rend.append(expiry_date_list) oi.append(open_interest_list) ############################ Create dictionary of symbol ############### output_file("categorical2.html") # # https://bokeh.pydata.org/en/latest/docs/user_guide/tools.html#basic-tooltips TOOLTIPS = [("Expiry Date", "@desc"), ("Strike Price", "@xs"), ("Bid Price", "@ys")] ############################ Strike-price vs bidprice ############### # desc would be required for the hover tooltip p = figure(plot_width=500, plot_height=500, toolbar_location="below", tools=[ 'hover', 'pan', 'xzoom_in', 'xzoom_out', 'xwheel_zoom', "crosshair" ], tooltips=TOOLTIPS) #Store the line-plot and date to provide for drop-down menu_renderer = [] plots_renderer = [] # plot multiple lines for x_data, y_data, desc_data, color in zip(x, y, desc_rend, self.Category20_20_custom): print(desc_data) source = ColumnDataSource( data=dict(xs=x_data, ys=y_data, desc=desc_data)) # Append all plots plot = p.line('xs', 'ys', color=color, source=source) # Append the plot plots_renderer.append(plot) # Menu populated with the expiry dates menu_renderer.append(desc_data[0]) # Create a dropdown menu with expiry dates dropdown = Dropdown(label="Expiry Date", button_type="warning", menu=menu_renderer) # To debug this on chrome - right-click + Inspect callback = CustomJS(args=dict(plots=plots_renderer, menus=menu_renderer, dp=dropdown), code=""" for(var i=0; i<plots.length; i++){ console.log(this.item); if (menus[i] == this.item) plots[i].visible = true; else plots[i].visible = false; } dp.label = this.item; """) dropdown.js_on_event("menu_item_click", callback) ############################ Strike-price vs bidprice ############### layout = column(dropdown, p) #tab1 = Panel(child=layout, title="This is Tab 1") #tab2 = Panel(child=layout, title="This is Tab 2") #tabs = Tabs(tabs=[tab1, tab2]) show(layout)
def visualize_clusters(clustering, filter_list: Optional[list] = None, texts: Optional[list] = None, radius: float = 0.05, alpha: float = 0.5, plot_width: int = 1000, plot_height: int = 530, output_in_notebook: bool = True, output_file_path: Optional[str] = None, palette: Union[list, str] = 'Wellcome33'): """ This function creates a plot of the clusters Args: clustering: wellcomeml.ml.TextClustering instance filter_list: list texts: A list of texts to be displayed by the hover function radius: float, default: 0.05 alpha: float, default: 0.5 plot_width: int, default: 600 plot_height: int, default: 600 output_in_notebook: bool, default: True output_file_path: str, default: 'cluster_viz.html' palette: list, default: Wellcome33 Returns: None (Prints a bokeh figure) """ # Dataframe creation reduced_points = clustering.reduced_points data = pd.DataFrame(reduced_points) data = data.rename(columns={0: 'X', 1: 'Y'}) data['cluster_id'] = clustering.cluster_ids data['cluster_id'] = data['cluster_id'].astype(str) data['Keywords'] = clustering.cluster_kws data['category'] = (filter_list if filter_list else ['All']*len(data)) # Palette setting palette = (Wellcome33 if palette == 'Wellcome33' else palette) palette = [str(x) for x in palette] well_background = str(WellcomeBackground) clusters = list(data['cluster_id']) clusters = list(map(int, clusters)) clusters_uniq = np.unique(clusters) data['colors'] = [(palette[x % len(palette)] if x != -1 else str(WellcomeNoData)) for x in clusters] tools = ('hover, pan, wheel_zoom, zoom_in, zoom_out, reset, save, tap') tooltips = [("index", "$index"), ("(x,y)", "($x, $y)"), ("cluster", "@cluster_id"), ("keywords", "@Keywords")] if texts is not None: # Only gets the 60 characters of the text data['text'] = [text[:60] + '...' for text in texts] tooltips += [("text", "@text")] # DropDown Button dropdown_options = list(set([('All', 'All'), None] + [(cat, cat) for i, cat in enumerate(sorted( data['category'].unique()), 2)])) dropdown = Dropdown(label='Category', button_type='default', menu=dropdown_options, width=190, align="end") # Defines figure for plotting the clusters p = figure(title="Cluster visualization", toolbar_location="above", plot_width=plot_width, plot_height=plot_height, tools=tools, tooltips=tooltips, background_fill_color=well_background) R = [] sources = [] filtered_sources = [] for x in clusters_uniq: data_cluster_id_unfiltered = data[data['cluster_id'] == str(x)] sources.append(ColumnDataSource(data_cluster_id_unfiltered)) filtered_sources.append(ColumnDataSource(data_cluster_id_unfiltered)) # Plots the cluster r = p.circle(x="X", y="Y", radius=radius, fill_alpha=alpha, color="colors", source=filtered_sources[-1]) R += [r] # JavaScript callback for the Dropdown Button callback = CustomJS( args=dict(sources=sources, filtered_sources=filtered_sources), code=""" var data = [] var cat = cb_obj.item; function generateNewDataObject(oldDataObject){ var newDataObject = {} for (var key of Object.keys(oldDataObject)){ newDataObject[key] = []; } return newDataObject } function addRowToAccumulator(accumulator, dataObject, index) { for (var key of Object.keys(dataObject)){ accumulator[key][index] = dataObject[key][index]; } return accumulator; } if (cat === 'All') { for (var i = 0; i < sources.length; i++) { data.push(sources[i].data); } } else { for (var i = 0; i < sources.length; i++) { let new_data = generateNewDataObject(sources[i].data); for (var j = 0; j <= sources[i].data['category'].length; j++) { if (sources[i].data['category'][j] == cat) { new_data = addRowToAccumulator(new_data, sources[i].data, j); } } data[i] = new_data } } for (var i = 0; i < sources.length; i++) { filtered_sources[i].data = data[i] filtered_sources[i].change.emit() } """ ) dropdown.js_on_event(MenuItemClick, callback) # Plots the legend on two columns if len(clusters_uniq) > 36: median = len(R) // 2 legend1 = Legend(items=[(str(s), [r]) for s, r in zip(clusters_uniq[:median], R[:median])]) legend2 = Legend(items=[(str(s), [r]) for s, r in zip(clusters_uniq[median:], R[median:])]) p.add_layout(legend1, 'right') p.add_layout(legend2, 'right') else: legend = Legend(items=[(str(s), [r]) for s, r in zip(clusters_uniq, R)]) p.add_layout(legend, 'right') # Plots other extra annotations to the plot p.legend.title = "Cluster ID" p.legend.label_text_font_size = "11px" p.legend.background_fill_color = str(WellcomeBackground) p.legend.click_policy = "hide" p.min_border_left = 200 # Output in notebook and new page reset_output() if output_in_notebook: output_notebook() if output_file_path: output_file(output_file_path) show(column(dropdown, p))
def multilinePlot(dataset_id, columnName): log = DatasetManager.query.get_or_404(dataset_id) datasetName = log.datasetName datasetSqlName = log.datasetSqlName df = pd.read_sql_table(datasetSqlName, db.engine) # prepare some data x = df["index"] # create a new plot with a title and axis labels p = figure( title="Dataset Name: " + datasetName, x_axis_label="Index", y_axis_label="y", sizing_mode="fixed", plot_width=1100, plot_height=400, ) # Initialize source to x=[x] and y=[x] # Note: # Multi-line plots take an array as x's and y's # The x and y arrays must be the same length initialColumnName = columnName y = df[columnName] source = ColumnDataSource(data=dict(x=[x], y=[y])) df_source = ColumnDataSource(data=dict(df)) p.multi_line("x", "y", source=source) # Create menu and options with name of data columns with numerical data columns = df.columns.to_list() menu = [] options = [] for columnName in columns: # if df[columnName].dtype == np.float64 or df[columnName].dtype == np.int64: if is_numeric_dtype(df[columnName]): # Menu is a list of tuples of name/value pairs for dropdown widget menu.append((columnName, columnName)) # Option is a list of column names for multi-select widget options.append(columnName) # Create dropdown widget dropdown = Dropdown(label="Select Column", button_type="primary", menu=menu, width_policy="min") # Create multi-select widget multi_choice = MultiChoice(value=[initialColumnName], options=options, title="Select Columns") # Define JS callback to change column to plot callback_dropdown = CustomJS( args=dict(source=source, df_source=df_source), code=""" // Initialize x and y arrays var data = source.data; var x = data['x']; // console.log(' x=' + x); var y = data['y']; // console.log('y=' + y); // Get dataframe var df_data = df_source.data; // Set y array to selected value y[0] = df_data[this.item]; // Update plot with new x,y source data source.change.emit(); """, ) callback_multi_select = CustomJS( args=dict(source=source, df_source=df_source), code=""" // Initialize x and y arrays var data = source.data; var x = data['x']; var y = data['y']; x.length = 0; y.length = 0; // console.log(' x=' + x); // console.log('x.length=' + x.length); // console.log('y=' + y); // console.log('y.length=' + y.length); // Get dataframe var df_data = df_source.data; // Get value of multi-select widget // console.log('multi_select: ' + this.value, this.value.toString()); var array = this.value; // Iterate through multi-select values and update x,y arrays with selected values var array_iterator = array.values(); let next_value = array_iterator.next(); while (!next_value.done) { // console.log(next_value.value); x.push(df_data['index']); y.push(df_data[next_value.value]); next_value = array_iterator.next(); } // console.log('y=' + y); // console.log('y.length=' + y.length); // console.log('x.length=' + x.length); // Update plot with new x,y source data source.change.emit(); """, ) # Define javascript events to trigger callbacks dropdown.js_on_event( "menu_item_click", callback_dropdown, ) multi_choice.js_on_change( "value", callback_multi_select, ) layout = column(multi_choice, p) return layout
def categoricalPlot(dataset_id, columnName): log = DatasetManager.query.get_or_404(dataset_id) datasetName = log.datasetName datasetSqlName = log.datasetSqlName df = pd.read_sql_table(datasetSqlName, db.engine) vc = df[columnName].value_counts() categories = vc.index.to_list() # Categorical values can also be used as coordinates values = vc.to_list() print("categories and values:", categories, values) source = ColumnDataSource(data=dict(categories=categories, values=values)) print("source dir=", dir(source)) print("source.data=", source.data) print("source.data=", source.data["categories"]) # Set the x_range to the list of categories above p = figure( x_range=source.data["categories"], plot_height=250, plot_width=1100, title=datasetName + ": " + columnName + " Counts", ) p.vbar( x="categories", top="values", width=0.9, source=source, legend_field="categories", line_color="white", fill_color=factor_cmap("categories", palette=Spectral6, factors=source.data["categories"]), ) # Set some properties to make the plot look better p.xgrid.grid_line_color = None p.y_range.start = 0 # p.y_range.end = 9 p.legend.orientation = "horizontal" p.legend.location = "top_center" # Create menu and options with name of data columns with numerical data columns = df.columns.to_list() menu = [] columnNameList = [] category_counts = [] for columnName in columns: if not (is_numeric_dtype(df[columnName])): # Menu is a list of tuples of name/value pairs for dropdown widget menu.append((columnName, columnName)) # Option is a list of column names for multi-select widget columnNameList.append(columnName) # Get value counts vc = df[columnName].value_counts() category_counts.append([vc.index.to_list(), vc.to_list()]) # print("category_counts =", category_counts) # Create dropdown widget dropdown = Dropdown(label="Select Column", button_type="primary", menu=menu, width_policy="min") category_counts_source = ColumnDataSource( data=dict(x=columnNameList, y=category_counts)) # Define JS callback to change column to plot print("p.x_range=", p.x_range.properties_with_values()) print(dir(p.x_range)) callback_dropdown = CustomJS( args=dict(source=source, category_counts=category_counts_source, x_range=p.x_range), code=""" console.log('dropdown=' + this.item); // Initialize x and y arrays var data = source.data; var categories = data['categories']; // console.log(' x=' + x); var values = data['values']; // console.log('y=' + y); console.log('categories=' + categories + ' values=' + values); // Get dataframe var category_counts_data = category_counts.data; console.log('category_counts_data=' + category_counts_data); console.dir(category_counts_data); console.log('category_counts_data.x=' + category_counts_data.x); console.dir(category_counts_data.x); console.dir(category_counts_data.y); var index = category_counts_data.x.indexOf(this.item); console.log('index=' + index); console.log(category_counts_data.y[index]); // categories = category_counts_data.y[index][0]; // values = category_counts_data.y[index][1]; source.data['categories'] = category_counts_data.y[index][0]; source.data['values'] = category_counts_data.y[index][1]; x_range.factors = source.data['categories']; console.log('categories=' + categories + ' values=' + values); // Update plot with new x,y source data source.change.emit(); """, ) # Define javascript events to trigger callbacks dropdown.js_on_event( "menu_item_click", callback_dropdown, ) # return row(dropdown, p) return p