def make_audio_panel(): PLAY_TEST_AUDIO = """ var path = 'Groove-Explorer-2/static/Test Audio/List Interface/' var index = selector.active; var labels = ['A', 'B', 'C', 'D', 'E']; var filename = path + labels[index] + '.mp3'; audio_player.stop_audio(); audio_player.play_audio(filename); """ STOPCODE = """ audio_player.stop_audio(); """ labels = ['A', 'B', 'C', 'D', 'E'] audio_selector = RadioGroup(labels=labels, height_policy="auto", sizing_mode='scale_width', active=0) play_button = Button(label='Play') play_button.js_on_click( CustomJS(args=dict(selector=audio_selector), code=PLAY_TEST_AUDIO)) stop_button = Button(label='Stop') stop_button.js_on_click(CustomJS(code=STOPCODE)) audio_panel = column(audio_selector, play_button, stop_button) return audio_panel
def modify_doc(doc): plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_tools(CustomAction(callback=CustomJS(args=dict(s=source), code=RECORD("data", "s.data")))) button = Button(css_classes=["foo"]) button.js_on_click(CustomJS(args=dict(s=source), code="s.patch({'x': [[1, 100]]})")) doc.add_root(column(button, plot))
def make_download_history_buttons(grid_name, track_name): download_h5 = CustomJS(args=dict(grid_name=grid_name, track_name=track_name), code=""" download_source(grid_name, track_name, 'hdf5') """) button_h5 = Button(label="Download HDF5", button_type="success", sizing_mode="stretch_width") button_h5.js_on_click(download_h5) download_csv = CustomJS(args=dict(grid_name=grid_name, track_name=track_name), code=""" download_source(grid_name, track_name, 'csv') """) button_csv = Button(label="Download CSV", button_type="success", sizing_mode="stretch_width") button_csv.js_on_click(download_csv) return button_h5, button_csv
def __init__( self, top_n_words: int, min_date: date, max_date: date, date_range_widget: DateRangeWidget, dataset_widget: DatasetWidget, word_freqs_widget: WordFreqsWidget, num_docs_figure: NumDocsFigure, add_next_tick_callback: Callable[[Callable[[], None]], None], ): self._top_n_words = top_n_words self._min_date = min_date self._max_date = max_date self._date_range_widget = date_range_widget self._dataset_widget = dataset_widget self._word_freqs_widget = word_freqs_widget self._num_docs_figure = num_docs_figure self._add_next_tick_callback = add_next_tick_callback self._source = ColumnDataSource(self._new_source_data()) self._stats = Div( text="", style={ "padding": "6px 0", "width": "100%" }, sizing_mode="stretch_width", ) freqs_table = DataTable( source=self._source, columns=[ TableColumn(field="words", title="Word"), TableColumn(field="freqs", title="Frequency"), ], sizing_mode="stretch_both", ) export_csv = Button( label="Export CSV", button_type="primary", sizing_mode="fixed", width=100, height=30, ) export_csv.js_on_click( CustomJS( args={"source": self._source}, code=(Path(__file__).parent / "export_csv.js").read_text(encoding="UTF-8"), )) self.figure = column( row(self._stats, export_csv, sizing_mode="stretch_width"), freqs_table, ) self._last_selection: Optional[Hashable] = None self._word_freqs_per_day: Optional[Mapping[str, Sequence[int]]] = None self._num_docs_per_day: Optional[Sequence[int]] = None self._took_msecs: Optional[int] = None
def get_checkboxes_with_filter(labels: List[str], column_label: str, source, select_all_btn=True, clear_all_btn=True): """ :param labels: names for checkbox labels as list (dataframe must contain it as value to filter) :param column_label: name of column in dataframe :param source: dataframe :return: checkboxes and filter for graph """ # routes checkboxes checkboxes = CheckboxGroup(labels=labels, active=list(range(len(labels)))) filter = CustomJSFilter(code=''' var selected = checkboxes.active.map(i=>checkboxes.labels[i]); var indices = []; var column = source.data[column_label]; // iterate through rows of data source and see if each satisfies some constraint for (var i = 0; i < column.length; i++){ if(selected.includes(column[i])){ indices.push(true); } else { indices.push(false); } } console.log("filter completed"); return indices; ''', args=dict(checkboxes=checkboxes, column_label=column_label)) checkboxes.js_on_change( "active", CustomJS(code="source.change.emit();", args=dict(source=source))) widgets = [checkboxes] if select_all_btn: select_all = Button(label="выбрать все", width=65, height=30) select_all.js_on_click( CustomJS(args=dict(checkboxes=checkboxes, all_active=list(range(len(labels)))), code=""" checkboxes.active = all_active """)) widgets.append(select_all) if clear_all_btn: clear_all = Button(label="отчистить все", width=65, height=30) clear_all.js_on_click( CustomJS(args=dict(checkboxes=checkboxes), code=""" checkboxes.active = [] """)) widgets.append(clear_all) return Column(*widgets), filter
def _generate_device_plot(self, device_events): data_source = self._convert_events_to_datasource( device_events['events']) n_rows = device_events['n_rows'] if n_rows == 0: n_rows = 1 elif n_rows == 1: n_rows = 2 name = device_events['name'] plot = figure( title="{}".format(name), plot_height=20 * n_rows + 60, plot_width=1200, tools=self._tools, sizing_mode='stretch_both', # sizing_mode='scale_width', active_scroll='xwheel_zoom') plot.hbar(left='start', right='end', y='height', color='color', height=0.85, source=data_source, hover_fill_alpha=0.5, line_join='round', line_cap='round', hover_line_color='red') plot.x_range = Range1d(0, self._iteration_time, bounds="auto") plot.y_range = Range1d(0, n_rows) plot.yaxis.visible = False plot.ygrid.ticker = SingleIntervalTicker(interval=1) plot.ygrid.grid_line_color = None plot.ygrid.band_fill_alpha = 0.1 plot.ygrid.band_fill_color = "gray" button = Button(label=" Sync", width=20, button_type='primary', disabled=True) button.css_classes = ['xl-hidden'] button.js_on_click( CustomJS(args={ 'me': plot, }, code=self._js_update_ranges)) plot.x_range.js_on_change( 'start', CustomJS(args={ 'button': button, }, code=self._js_on_change_callback)) return plot, WidgetBox(button)
def make_comparison_controls(source, track_sources, p1, p2, pars_dict, select_options): calbackcode = """ var data = source.data; var parname = cb_obj.value; data[axisname+'1'] = data[parname+'_1']; data[axisname+'2'] = data[parname+'_2']; axis1.axis_label = parname; axis2.axis_label = parname; source.change.emit(); """ x1 = Select(title='X-Axis', value=pars_dict['x1'], options=select_options) x1.js_on_change( 'value', CustomJS(args=dict(source=source, axisname='x', axis1=p1.xaxis[0], axis2=p2.xaxis[0], suffix='_1'), code=calbackcode)) y1 = Select(title='Y-Axis', value=pars_dict['y1'], options=select_options) y1.js_on_change( 'value', CustomJS(args=dict(source=source, axisname='y', axis1=p1.yaxis[0], axis2=p2.yaxis[0], suffix='_1'), code=calbackcode)) update_source = CustomJS(args=dict( summary_source=source, track_sources=track_sources, ), code=""" update_source(summary_source, track_sources[0], grid1, '_1') update_source(summary_source, track_sources[1], grid2, '_2') """) button = Button(label="Plot selected tracks", button_type="success", sizing_mode="stretch_width") button.js_on_click(update_source) controls = row([x1, y1, button]) control_dict = { "x1": x1, "y1": y1, } return controls, control_dict
def test_js_on_click_executes(self, bokeh_model_page) -> None: button = Button(css_classes=['foo']) button.js_on_click(CustomJS(code=RECORD("clicked", "true"))) page = bokeh_model_page(button) button = page.driver.find_element_by_css_selector('.foo .bk-btn') button.click() results = page.results assert results == {'clicked': True} assert page.has_no_console_errors()
def test_js_on_click_executes(self, bokeh_model_page): button = Button(css_classes=['foo']) button.js_on_click(CustomJS(code=RECORD("clicked", "true"))) page = bokeh_model_page(button) button = page.driver.find_element_by_css_selector('.foo .bk-btn') button.click() results = page.results assert results == {'clicked': True} assert page.has_no_console_errors()
def test_js_on_click_executes(self, bokeh_model_page: BokehModelPage) -> None: button = Button() button.js_on_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 modify_doc(doc): p1 = figure(x_axis_type="datetime", title="t-SNE embedding of the digits - original") p1.xaxis.axis_label = 'x1' p1.yaxis.axis_label = 'x2' p1.legend.location = "top_left" p2 = figure(x_axis_type="datetime", title="t-SNE embedding of the digits - siamese") p2.xaxis.axis_label = 'x1' p2.yaxis.axis_label = 'x2' p2.legend.location = "top_left" def callback(attr, old, sample_size): x_test = x_val[:sample_size, :] y_test = y_val[:sample_size] x_affinity = siamese_net.predict(x_test, batch_sizes) # ---------------------------------------------------------------------- # t-SNE embedding of the digits dataset print("Computing t-SNE embeddings for sample size %s" % sample_size) tsne = manifold.TSNE(n_components=2, init='pca', random_state=0) X_tsne = tsne.fit_transform(x_test) plot_embedding_bokeh(X_tsne, y_test, p1) X_affinity_tsne = tsne.fit_transform(x_affinity) plot_embedding_bokeh(X_affinity_tsne, y_test, p2) print("Finished Plotting for sample size %s" % sample_size) b = Button(label="Reset", button_type="success", width=300) b.js_on_click( CustomJS(args=dict(p1=p1, p2=p2), code=""" console.log("start CustomJS"); p1.reset.emit(); p2.reset.emit(); console.log("finish CustomJS"); """)) default_sample_size = 100 slider = Slider(start=100, end=1000, value=default_sample_size, step=100, title="Sample Size") slider.on_change('value', callback) callback(None, None, default_sample_size) grid = gridplot([[p1, p2]], plot_width=400, plot_height=400) doc.add_root(column(slider, grid, b)) doc.theme = Theme(filename="theme.yaml")
def bar_plot(results): quantity = ['low','medium','high','none'] colors = ['lightsteelblue', 'gold', 'saddlebrown', 'black'] source = ColumnDataSource(data=dict(quantity=quantity, results=results, color=colors)) p = figure(x_range=quantity, y_range=(0,1), title="Absolute frequency of quantity and its thresholds",toolbar_location=None,plot_width=650, plot_height=650) p.vbar(x='quantity', top='results', width=0.6, source=source, legend_field="quantity", line_color='color', fill_color='color') p.xgrid.grid_line_color = None p.legend.orientation = "horizontal" p.legend.location = "top_center" hline1 = Span(location=threshold[0], line_color='lightsteelblue', line_width=3) hline2 = Span(location=threshold[1], line_color='gold', line_width=3) hline3 = Span(location=threshold[2], line_color='saddlebrown', line_width=3) hline4 = Span(location=threshold[3], line_color='black', line_width=3) p.renderers.extend([hline1]) p.renderers.extend([hline2]) p.renderers.extend([hline3]) p.renderers.extend([hline4]) p.legend.orientation = "vertical" p.legend.location = "top_left" p.xaxis.major_label_orientation = 1.2 p.xgrid.visible = False p.ygrid.visible = False p.outline_line_width = 3 p.outline_line_alpha = 0.3 p.outline_line_color = "black" p.xaxis.axis_label = "Quantity" p.yaxis.axis_label = "Absolute frequency" p.yaxis.ticker = [threshold[0], threshold[1], threshold[2], threshold[3]] b = Button(label='Update bin') b.js_on_click(CustomJS(args=dict(urls=['http://127.0.0.1:5000/update_bin']),code="""urls.forEach(url => window.open(url))""")) output_file('templates/bar_plot.html') layer = column(b , p) return layer
def test_updates_when_visibility_is_toggled( self, single_plot_page: SinglePlotPage) -> None: source = ColumnDataSource(dict(x=[1, 2], y1=[0, 1], y2=[10, 11])) plot = Plot(height=400, width=400, x_range=DataRange1d(), y_range=DataRange1d(only_visible=True), min_border=0) plot.add_glyph(source, Circle(x='x', y='y1')) glyph = plot.add_glyph(source, Circle(x='x', y='y2')) code = RECORD("yrstart", "p.y_range.start", final=False) + RECORD( "yrend", "p.y_range.end") plot.tags.append( CustomJS(name="custom-action", args=dict(p=plot), code=code)) plot.toolbar_sticky = False button = Button() button.js_on_click( CustomJS(args=dict(glyph=glyph), code="glyph.visible=false")) page = single_plot_page(column(plot, button)) page.eval_custom_action() results = page.results assert results['yrstart'] <= 0 assert results['yrend'] >= 11 button = find_element_for(page.driver, button, ".bk-btn") button.click() page.eval_custom_action() results = page.results assert results['yrstart'] <= 0 assert results['yrend'] < 5 assert page.has_no_console_errors()
def test_updates_when_visibility_is_toggled(self, single_plot_page) -> None: source = ColumnDataSource(dict(x=[1, 2], y1=[0, 1], y2=[10, 11])) plot = Plot(plot_height=400, plot_width=400, x_range=DataRange1d(), y_range=DataRange1d(only_visible=True), min_border=0) plot.add_glyph(source, Circle(x='x', y='y1')) glyph = plot.add_glyph(source, Circle(x='x', y='y2')) code = RECORD("yrstart", "p.y_range.start", final=False) + RECORD( "yrend", "p.y_range.end") plot.add_tools( CustomAction(callback=CustomJS(args=dict(p=plot), code=code))) plot.toolbar_sticky = False button = Button(css_classes=['foo']) button.js_on_click( CustomJS(args=dict(glyph=glyph), code="glyph.visible=false")) page = single_plot_page(column(plot, button)) page.click_custom_action() results = page.results assert results['yrstart'] <= 0 assert results['yrend'] >= 11 button = page.driver.find_element_by_css_selector('.foo .bk-btn') button.click() page.click_custom_action() results = page.results assert results['yrstart'] <= 0 assert results['yrend'] < 5 assert page.has_no_console_errors()
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_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
class BuildingTaskDashboard: start_location = [36.483, 36.475] folium_zoom = 14 def __init__(self, task: TaskHandler, results_dir=BUILDING_RESULTS_DIR): self.task = task self.main_panel = column() self.folium_name = task.__str__() # unpack building experiment results self.kfold = 0 self.model_idx = 0 # self.full_results = load_experiment_results(results_dir)['model_results'] self.full_results = load_separate_model_results(results_dir)['model_results'] self.model_results = self.full_results[self.model_idx] self.geos_train, self.X_train_df, self.y_train, self.train_probas, \ self.geos_test, self.X_test_df, self.y_test, self.test_probas, \ self.models, self.model_names, self.auc_scores = self._extract_model_results(self.full_results, self.model_idx, self.kfold) self.num_kfold = len(self.full_results[0]['train_idx']) self.features_df = pd.concat([self.X_train_df, self.X_test_df]) self.features_kmeans = shap.kmeans(self.features_df, 10) self.all_probas = np.concatenate([self.train_probas[self.model_idx], self.test_probas[self.model_idx]]) self.all_probas_df = pd.Series(data=self.all_probas, index=self.features_df.index) self.mean_auc = self.mean_auc_panel(self.model_names, self.auc_scores) plot = self.bokeh_plot() self.main_panel.children.append(plot) @staticmethod def mean_auc_panel(model_names, auc_scores): text = "<h3>Mean AUC results </h3>" for i, model_name in enumerate(model_names): model_mean = np.mean(auc_scores[i]) text += f"<br> <b>{model_name}:</b> \t {round(model_mean, 3)}" return Div(text=text) def bokeh_plot(self): # create precision recall curve test_probas_df = pd.DataFrame( {model_name: test_proba for model_name, test_proba in zip(self.model_names, self.test_probas)}) pr_curve = bokeh_multiple_pr_curves(test_probas_df, self.y_test.values) # create feature histogram self.feature_select = Select(title="Choose Feature: ", value=self.X_train_df.columns[0], options=list(self.X_train_df.columns), width=200) self.feature_select.on_change('value', self.choose_feature_callback) # self.feature_select.js_on_change('value', log_current_map_position_js(self.folium_name)) hist = bokeh_score_histogram(self.X_train_df.iloc[:, 0], self.y_train > 0.5) # create model select self.model_select = Select(title="Choose Model: ", value=self.model_names[0], options=list(self.model_names), width=300) self.kfold_select = Select(title="Choose Kfold: ", value='0', options=list(map(str, range(self.num_kfold))), width=150) self.run_button = Button(label="RUN", button_type="success", width=100) self.run_button.js_on_click(log_current_map_position_js(self.folium_name)) self.run_button.on_click(self.run_callback) # build input for map click coords lon_text = TextInput(value="0", title='lon:', width=100) lat_text = TextInput(value="0", title='lat:', width=100) self.lonlat_text_inputs = [lon_text, lat_text] feature_importance_button = Button(label='Calculate Feature Values') # feature_importance_button.js_on_click(log_current_map_position_js(self.folium_name)) # feature_importance_button.on_click(self.sample_feature_importance_update) # importance_fig, _ = self.build_importance_figure(Point(0, 0)) # create folium figure folium_fig = bokeh_scored_polygons_folium([self.all_probas_df], [True], train_geos=self.geos_train, test_geos=self.geos_test, start_zoom=self.folium_zoom, start_location=self.start_location, file_name=self.folium_name, width=700, lonlat_text_inputs=self.lonlat_text_inputs) # put it all together self.left_column = column(pr_curve, self.feature_select, hist) self.folium_column = column(row(self.model_select, self.kfold_select, self.run_button), folium_fig, self.mean_auc) self.importance_and_val_column = column(row(lon_text, lat_text), feature_importance_button)#, importance_fig) return row(self.left_column, self.folium_column, self.importance_and_val_column) def sample_feature_importance_update(self): lat, lon = self.get_click_lonlat() point = Point([lon, lat]) importance_figure, closest_geo = self.build_importance_figure(point) self.lonlat_text_inputs[0].value = str(round(closest_geo.centroid.x, 5)) self.lonlat_text_inputs[1].value = str(round(closest_geo.centroid.y, 5)) self.importance_and_val_column.children[-1] = importance_figure def choose_feature_callback(self, attr, old, new): print(f"Chose feature: {new}") new_hist = bokeh_score_histogram(self.X_train_df[new], self.y_train > 0.5) self.left_column.children[-1] = new_hist def build_importance_figure(self, point: Point): if point.x == 0 and point.y == 0: closest_geo = point closest_geo_df = pd.DataFrame([self.features_df.mean().values], columns=self.features_df.columns, index=['aggregated']) else: closest_geo = get_closest_geo(point, self.features_df.index) closest_geo_df = self.features_df[self.features_df.index == closest_geo] model = self.models[self.model_names.index(self.model_select.value)] explainer = shap.KernelExplainer(model.predict, self.features_kmeans) shap_values_model = explainer.shap_values(closest_geo_df, silent=True)[0] # TODO: very slow # importance_fig = shap.force_plot(explainer.expected_value, shap_values_model, closest_geo_df) sort_indices = np.argsort(np.abs(shap_values_model)) importance_fig = feature_importance(list(self.X_train_df.columns[sort_indices]), shap_values_model[sort_indices]) # shap.save_html('importance_fig.html', importance_fig) # importance_fig = Div(text="""<iframe> # src="importance_fig.html" # </iframe>""") return importance_fig, closest_geo def run_callback(self): self.model_idx = self.model_names.index(self.model_select.value) self.kfold = int(self.kfold_select.value) # set all the parameters of the new kfold self.geos_train, self.X_train_df, self.y_train, self.train_probas, \ self.geos_test, self.X_test_df, self.y_test, self.test_probas, \ self.models, self.model_names, self.auc_scores = self._extract_model_results(self.full_results, self.model_idx, self.kfold) self.num_kfold = len(self.full_results[0]['train_idx']) self.features_df = pd.concat([self.X_train_df, self.X_test_df]) self.features_kmeans = shap.kmeans(self.features_df, 10) self.all_probas = np.concatenate([self.train_probas[self.model_idx], self.test_probas[self.model_idx]]) self.all_probas_df = pd.Series(data=self.all_probas, index=self.features_df.index) # create new precision recall curve test_probas_df = pd.DataFrame( {model_name: test_proba for model_name, test_proba in zip(self.model_names, self.test_probas)}) pr_curve = bokeh_multiple_pr_curves(test_probas_df, self.y_test.values) self.left_column.children[0] = pr_curve # create new folium map print(f"Choose model: {self.model_select.value}\t kfold: {self.kfold}") new_folium = bokeh_scored_polygons_folium([self.all_probas_df], [True], train_geos=self.geos_train, test_geos=self.geos_test, start_zoom=self.folium_zoom, start_location=self.start_location, file_name=self.folium_name, width=700, lonlat_text_inputs=self.lonlat_text_inputs) self.folium_column.children[-2] = new_folium self.sample_feature_importance_update() def get_click_lonlat(self): lon = self.lonlat_text_inputs[0].value lat = self.lonlat_text_inputs[1].value lon = float(lon) if lon != "" else 0 lat = float(lat) if lat != "" else 0 return lat, lon def _extract_model_results(self, full_results, model_idx, kfold): model_results = full_results[model_idx] train_idx, test_idx = model_results['train_idx'][kfold], model_results['test_idx'][kfold] # X and y X_train_df, X_test_df = model_results['X_df'].iloc[train_idx], model_results['X_df'].iloc[test_idx] y_train, y_test = model_results['y'][train_idx], model_results['y'][test_idx] # geos geos_train_idx, geos_test_idx = model_results['geos_kfold_split'][kfold] geos_train, geos_test = model_results['geos'][geos_train_idx], model_results['geos'][geos_test_idx] # probas train_probas = [results['probas'][kfold][train_idx] for results in full_results] test_probas = [results['probas'][kfold][test_idx] for results in full_results] # models model_names = [results['model_name'] for results in full_results] models = [results['models'][kfold] for results in full_results] scores = [results['auc_scores'] for results in full_results] return geos_train, X_train_df, y_train, train_probas, \ geos_test, X_test_df, y_test, test_probas, \ models, model_names, scores
colsource.data['timestamp_str'][selected_indices[-1]], }, index=[0])) annotations.data.update(bp.ColumnDataSource(pdf_results).data) if not btn_3m_walk.label.endswith('(done)'): btn_3m_walk.label = btn_3m_walk.label + ' (done)' ### Callback registrations btn_chairstand.on_click(mark_chairstand) btn_3m_walk.on_click(mark_3m_walk) btn_clear_selection.on_click(clear_selection) btn_export.js_on_click( CustomJS(args=dict(source=annotations), code=open( os.path.join(os.path.dirname(__file__), 'js', "download.js")).read())) file_picker.on_change('value', update_plot) colsource.selected.js_on_change( "indices", CustomJS( args=dict(s1=colsource, s2=selected_data, table=table), code=""" var inds = cb_obj.indices; var d1 = s1.data; var d2 = s2.data; d2['timestamp'] = [] d2['x'] = [] d2['y'] = [] d2['z'] = []
class WaveformPlot(): '''A waveform plot.''' def __init__(self, wav, fs, offset=0.0, dtype=np.float32, title='Waveform'): self.dtype = dtype self.wav = wav.astype(dtype) self.fs = fs self.offset = dtype(offset) self.title = title self.source = ColumnDataSource( data={ 'time': ((np.arange(len(wav)) / fs) + self.offset).astype(dtype), 'amplitude': self.wav }) self.playbutton = Button(label='Play window') self.zoomrange = np.array([0, len(self.wav) / self.fs]) self.boxzoomtool = BoxZoomTool(dimensions='width') self.plot = figure(title=self.title, tools=[self.boxzoomtool, 'reset']) self.plot.toolbar.logo = None self.plot.line('time', 'amplitude', source=self.source) self.winstart_ti = TextInput(name="winstart_ti", visible=False, value=str(self.zoomrange[0])) self.winend_ti = TextInput(name="winend_ti", visible=False, value=str(self.zoomrange[1])) self.fs_ti = TextInput(name="fs_ti", visible=False, value=str(self.fs)) self.plot.x_range.on_change('start', self.range_cb) self.plot.x_range.on_change('end', self.range_cb) self.js_playwin_cb = CustomJS(args=dict(sig=self.wav), code=''' let winstart_ti = document.getElementsByName("winstart_ti")[0]; let winend_ti = document.getElementsByName("winend_ti")[0]; let fs_ti = document.getElementsByName("fs_ti")[0]; if (typeof(winstart_ti) !== 'undefined' && typeof(winend_ti) !== 'undefined' && typeof(fs_ti) !== 'undefined' ) { let fs = Number(fs_ti.value); let start_idx = Math.round(Number(winstart_ti.value) * fs); let end_idx = Math.round(Number(winend_ti.value) * fs); if (start_idx < 0) { start_idx = 0; } if (end_idx > sig.length) { end_idx = sig.length; } let mysig = sig.slice(start_idx, end_idx); // // For more on AudioBuffer usage see // https://developer.mozilla.org/en-US/docs/Web/API/AudioBuffer // let audioCtx = new (window.AudioContext || window.webkitAudioContext)(); // Create an empty mono buffer at the signal sample rate. let myArrayBuffer = audioCtx.createBuffer(1, mysig.length, fs); // Fill the buffer with mysig. // This would be cleaner if mysig were of type Float32Array // so we could use copyToChannel(). //myArrayBuffer.copyToChannel(mysig, 0); for (var chan = 0; chan < myArrayBuffer.numberOfChannels; chan++) { // This gives us the actual array that contains the data let nowBuffering = myArrayBuffer.getChannelData(chan); for (let i = 0; i < myArrayBuffer.length; i++) { nowBuffering[i] = mysig[i]; } } // Get an AudioBufferSourceNode. // This is the AudioNode to use when we want to play an // AudioBuffer let source = audioCtx.createBufferSource(); source.buffer = myArrayBuffer; source.connect(audioCtx.destination); // Start the source playing. source.start(); } ''') self.playbutton.js_on_click(self.js_playwin_cb) self.js_winrange_cb = CustomJS(code=""" // cbo = cb_obj; console.log(cb_obj); let winstart_ti = document.getElementsByName("winstart_ti")[0]; if (typeof(winstart_ti) !== 'undefined') { winstart_ti.value = String(cb_obj["start"]); console.log(winstart_ti.value); } let winend_ti = document.getElementsByName("winend_ti")[0]; if (typeof(winend_ti) !== 'undefined') { winend_ti.value = String(cb_obj["end"]); console.log(winend_ti.value); } """) self.plot.x_range.js_on_change('start', self.js_winrange_cb) self.plot.x_range.js_on_change('end', self.js_winrange_cb) @property def wav_window(self): '''Return the data in the currently displayed plot window.''' winrange = np.round(self.zoomrange * self.fs).astype(int) if winrange[0] < 0: winrange[0] = 0 if winrange[1] > len(self.wav) - 1: winrange[1] = len(self.wav) - 1 return self.wav[winrange[0]:winrange[1]] @property def zoomrange_idx(self): '''Return the sample indexes of current zoomrange.''' idxs = np.round(self.zoomrange * self.fs).astype(int) if idxs[0] < 0: idxs[0] = 0 if idxs[1] > len(self.wav): idxs[1] = len(self.wav) return idxs def range_cb(self, attr, old, new): if old is not None: if attr == 'start': self.zoomrange[0] = new elif attr == 'end': self.zoomrange[1] = new
var f = anim[0]; cb_obj.origin.disabled = true function app(f) { for (var i = 0; i < x.length; i++) { y[i] = Math.pow(x[i], f) } source.change.emit(); if (f >= anim[1]) { cb_obj.origin.disabled = false; return; } setTimeout(function() { app(f+anim[2]); }, anim[3]) } app(f); """ ) bt.js_on_click(callback) layout = column(p, bt) #show the results item_text = json.dumps(json_item(layout, "myplot")) print(item_text) sys.stdout.flush()
from bokeh.models import Button, DataTable, Dropdown, PreText, RadioButtonGroup from bokeh.layouts import layout from bokeh.plotting import curdoc from file_input import ImportData imp_data = ImportData() button = Button(label="Upload", button_type="success") button.js_on_click(imp_data.cb) imp_data.x_label = PreText(text="x axis variable") imp_data.y_label = PreText(text="y axis variable") imp_data.g_label = PreText(text="group variable") imp_data.x_drop = Dropdown(label="x-axis Variable") imp_data.y_drop = Dropdown(label="y-axis Variable") imp_data.g_drop = Dropdown(label="Group Variable") imp_data.dt = DataTable() imp_data.plot_type = RadioButtonGroup(labels=["Line", "Bar", "Scatter", "Histogram"]) imp_data.plot_label = PreText(text="Plot type") imp_data.submit = Button(label="Submit", button_type="success") app_layout = layout([button]) doc = curdoc() imp_data.layout = app_layout imp_data.doc = doc doc.add_root(app_layout)
def _graph_iterations_plot(G: nx.Graph, nodes: List[List[int]] = None, edges: List[List[List[int]]] = None, costs: List[float] = None, tables: List[pd.DataFrame] = None, swaps: List[List[int]] = None, show_all_edges: bool = True, show_labels: bool = True, **kw) -> GridBox: """Return a plot of multiple iterations of a graph. Args: G (nx.Graph): Networkx graph. nodes (List[List[int]]): Highlighted nodes at every iteration. edges (List[List[List[int]]]): Highlighted edges at every iteration. costs (List[float]): Cost at every iteration. tables (List[pd.DataFrame]): Table to be shown at every iteration. swaps (List[List[int]]): Edge swap to highlight at every iteration. show_all_edges (bool, optional): True iff all edges should be shown. show_labels (bool, optional): True iff labels should be shown. Returns: GridBox: Plot of multiple iterations of a graph. """ G = G.copy() plot = _blank_plot(G, **kw) _set_edge_positions(G) _set_graph_colors(G) args_dict = {} # keep track of objects to pass to JS callback # nodes and edges nodes_src, nodes_glyph = _add_nodes(G, plot) args_dict['nodes_src'] = nodes_src if nodes is not None: for i in nodes[0]: nodes_src.data['line_color'][i] = PRIMARY_DARK_COLOR nodes_src.data['fill_color'][i] = PRIMARY_DARK_COLOR if show_all_edges: edges_src, edges_glyph = _add_edges(G, plot, show_labels=show_labels) # current iteration n = Div(text='0', width=plot.plot_width, align='center') args_dict['n'] = n # total number of iterations features = [edges, nodes, costs, tables, swaps] k = max([0 if feature is None else len(feature) for feature in features]) k = Div(text=str(k), width=plot.plot_width, align='center') args_dict['k'] = k # indicate if on final iteration done = Div(text='', width=int(plot.plot_width / 2), align='center') args_dict['done'] = done source_data = {} if edges is not None: tmp = list(zip(*[_edge_positions(G, edge) for edge in edges])) edge_xs, edge_ys = tmp source_data['edge_xs'] = edge_xs source_data['edge_ys'] = edge_ys edge_subset_src = ColumnDataSource(data={ 'xs': edge_xs[0], 'ys': edge_ys[0] }) plot.multi_line('xs', 'ys', line_color=TERTIARY_DARK_COLOR, line_width=LINE_WIDTH, level=EDGE_LEVEL, line_cap='round', source=edge_subset_src) args_dict['edge_subset_src'] = edge_subset_src if nodes is not None: source_data['nodes'] = nodes if costs is not None: source_data['costs'] = costs cost = Div(text=str(costs[0]), width=int(plot.plot_width / 2), align='center') args_dict['cost'] = cost if tables is not None: tables = [table.to_dict(orient='list') for table in tables] source_data['tables'] = tables table_src = ColumnDataSource(data=tables[0]) columns = [TableColumn(field='index', title='')] for i in range(len(tables[0]) - 1): columns.append(TableColumn(field=str(i), title=str(i))) table = DataTable(source=table_src, columns=columns, height=80, width_policy='fit', max_width=plot.plot_width, width=plot.plot_width, background='white', index_position=None, editable=False, reorderable=False, sortable=False, selectable=False) args_dict['table_src'] = table_src if swaps is not None: tmp = list(zip(*[_swap_positions(G, swap) for swap in swaps])) swaps_before_x, swaps_before_y, swaps_after_x, swaps_after_y = tmp source_data['swaps_before_x'] = swaps_before_x source_data['swaps_before_y'] = swaps_before_y source_data['swaps_after_x'] = swaps_after_x source_data['swaps_after_y'] = swaps_after_y swaps_src = ColumnDataSource( data={ 'swaps_before_x': swaps_before_x[0], 'swaps_before_y': swaps_before_y[0], 'swaps_after_x': swaps_after_x[0], 'swaps_after_y': swaps_after_y[0] }) plot.multi_line(xs='swaps_before_x', ys='swaps_before_y', line_color=SECONDARY_COLOR, line_width=LINE_WIDTH, line_cap='round', level=EDGE_LEVEL, source=swaps_src) plot.multi_line(xs='swaps_after_x', ys='swaps_after_y', line_color=SECONDARY_COLOR, line_width=LINE_WIDTH, line_cap='round', level=EDGE_LEVEL, line_dash=[10, 12], source=swaps_src) args_dict['swaps_src'] = swaps_src source = ColumnDataSource(data=source_data) args_dict['source'] = source code = ('done_update()\n' + 'cost_update()\n' * (costs is not None) + 'edge_subset_update()\n' * (edges is not None) + 'table_update()\n' * (tables is not None) + 'nodes_update()\n' * (nodes is not None) + 'swaps_update()\n' * (swaps is not None)) next_btn_code = PLOT_GRAPH_ITERATIONS_JS + 'increment_iteration()\n' + code prev_btn_code = PLOT_GRAPH_ITERATIONS_JS + 'decrement_iteration()\n' + code # buttons next_button = Button(label="Next", button_type="primary", max_width=int(plot.plot_width / 2), width_policy='fit', sizing_mode='stretch_width') next_button.js_on_click(CustomJS(args=args_dict, code=next_btn_code)) prev_button = Button(label="Previous", button_type="primary", max_width=int(plot.plot_width / 2), width_policy='fit', sizing_mode='stretch_width') prev_button.js_on_click(CustomJS(args=args_dict, code=prev_btn_code)) plot.add_tools( HoverTool(tooltips=[("Index", "$index"), ("Name", "@name")], renderers=[nodes_glyph])) # create layout layout = [[plot], [ row(prev_button, next_button, max_width=plot.plot_width, sizing_mode='stretch_both') ], [row(cost, done) if costs else row(done)]] if tables is not None: layout.insert(1, [table]) grid = gridplot(layout, plot_width=plot.plot_width, plot_height=plot.plot_height, toolbar_location=None, toolbar_options={'logo': None}) return grid
label_data = ColumnDataSource( data=dict(x=[1, 2, 3], y=[0, 0, 0], t=['Original', 'Normal', 'Uniform'])) label_set = LabelSet(x='x', y='y', text='t', y_offset=-4, source=label_data, render_mode='css', text_baseline="top", text_align='center') p.add_layout(label_set) callback = CustomJS(args=dict(source=source, normal=normal, uniform=uniform), code=""" const data = source.data; for (var i = 0; i < data.y.length; i++) { data.xn[i] = normal.compute(data.x[i] + 1); } for (var i = 0; i < data.y.length; i++) { data.xu[i] = uniform.compute(data.x[i] + 2); } source.change.emit(); """) button = Button(label='Press to apply Jitter!', width=300) button.js_on_click(callback) output_file("transform_jitter.html", title="Example Jitter Transform") show(Column(button, p))
def cluster_gui(doc): global s2, s1, old_indices old_indices = [] output_file("tile.html") tile_provider = get_provider(CARTODBPOSITRON) x = [] y = [] name = [] global fig03 fig03 = figure( plot_width=400, plot_height=400, tools=["box_zoom", "wheel_zoom", "reset", "save"], title="Waveforms from current selection", ) for i, st in enumerate(stations): xm, ym = merc(st.lat, st.lon) x.append(xm) y.append(ym) name.append(st.nsl_string()) # create first subplot plot_width = 400 plot_height = 400 d = num.ones_like(x) s1 = ColumnDataSource(data=dict(x=x, y=y, ind=d, name=name)) # range bounds supplied in web mercator coordinates fig01 = figure( x_axis_type="mercator", y_axis_type="mercator", plot_width=plot_width, plot_height=plot_height, tools=[ "lasso_select", "box_select", "reset", "save", "box_zoom", "wheel_zoom" ], title="Select", ) fig01.add_tile(tile_provider) fig01.scatter("x", "y", source=s1, alpha=0.6, size=8) # create second subplot s2 = ColumnDataSource(data=dict(x=[], y=[], ind=[], name=[])) color_mapper = LinearColorMapper(palette='Magma256', low=1, high=100) fig02 = figure( x_axis_type="mercator", y_axis_type="mercator", plot_width=plot_width, plot_height=plot_height, x_range=(num.min(x), num.max(x)), y_range=(num.min(y), num.max(y)), tools=["box_zoom", "wheel_zoom", "reset", "save"], title="Stations selected for Array", ) fig02.add_tile(tile_provider) fig02.scatter("x", "y", source=s2, alpha=1, color={ 'field': 'ind', 'transform': color_mapper }, size=8) x_event, y_event = merc(event.lat, event.lon) fig01.scatter(x_event, y_event, size=8, color="red") fig02.scatter(x_event, y_event, size=8, color="red") columns = [ TableColumn(field="x", title="X axis"), TableColumn(field="y", title="Y axis"), TableColumn(field="ind", title="indices"), TableColumn(field="name", title="name"), ] table = DataTable( source=s2, columns=columns, width=400, height=600, sortable=True, selectable=True, editable=True, ) source_count = 0 callback_slider = CustomJS(code=""" source_count = slider.value; """) global slider slider = Slider(start=1, end=100, value=1, step=1, title="Array number") slider.js_on_change('value', callback_slider) s1.selected.js_on_change( "indices", CustomJS(args=dict(s1=s1, s2=s2, s3=slider, table=table), code=""" var inds = cb_obj.indices; var d1 = s1.data; var d2 = s2.data; const A = s3.value; for (var i = 0; i < inds.length; i++) { d2['x'].push(d1['x'][inds[i]]) d2['y'].push(d1['y'][inds[i]]) d2['name'].push(d1['name'][inds[i]]) d2['ind'].push(A) } s2.change.emit(); table.change.emit(); s2.data = s2.data; var inds = source_data.selected.indices; var data = source_data.data; var out = "name, x, y, ind\\n"; for (i = 0; i < inds.length; i++) { out += data['name'][inds[i]] + "," + data['x'][inds[i]] + "," + data['y'][inds[i]] + "," + data['ind'][inds[i]] + "\\n"; } var file = new Blob([out], {type: 'text/plain'}); """), ), savebutton = Button(label="Save", button_type="success") savebutton.callback = CustomJS( args=dict(source_data=s1), code=""" var inds = source_data.selected.indices; var data = source_data.data; var out = "name, x, y, ind\\n"; for (i = 0; i < inds.length; i++) { out += data['name'][inds[i]] + "," + data['x'][inds[i]] + "," + data['y'][inds[i]] + "," + data['ind'][inds[i]] + "\\n"; } var file = new Blob([out], {type: 'text/plain'}); var elem = window.document.createElement('a'); elem.href = window.URL.createObjectURL(file); elem.download = 'arrays.txt'; document.body.appendChild(elem); elem.click(); document.body.removeChild(elem); """, ) tooltips = [ ("X:", "@x"), ("Y:", "@y"), ("Array:", "@ind"), ("Station:", "@name"), ] fig01.add_tools(HoverTool(tooltips=tooltips)) fig02.add_tools(HoverTool(tooltips=tooltips)) fig03.add_tools(HoverTool(tooltips=tooltips)) endbutton = Button(label="End and proceed", button_type="success") endbutton.on_click(button_callback) clearbutton = Button(label="Clear all", button_type="success") clearbutton.on_click(clearbuttonlast_callback) clearbuttonlast = Button(label="Clear last selection", button_type="success") clearbuttonlast.on_click(clearbuttonlast_callback) clearbuttonone = Button(label="Remove one from list", button_type="success") clearbuttonone.on_click(clearbuttonone_callback) b = Button(label="Reset all plots") b.js_on_click( CustomJS(code="""\ document.querySelectorAll('.bk-tool-icon-reset[title="Reset"]').forEach(d => d.click()) """)) #layout = grid([fig01, fig02, table, fig03, slider, clearbuttonlast, clearbutton, savebutton, endbutton], ncols=3, nrows=4) global text_input text_input = TextInput(value="1", title="Array number:") buttons = column(clearbuttonlast, clearbuttonone, clearbutton, savebutton, endbutton) inputs = column(text_input, slider) layout_grid = layout([fig01, fig02, buttons], [fig03, inputs, table]) #curdoc().add_root(layout) cluster_result = [] doc.add_root(layout_grid) #global session #session = push_session(curdoc()) #curdoc().add_periodic_callback(update, 100) #session.show(layout) doc.add_periodic_callback(update, 900) curdoc().title = "Array selection"
genome_plot.xgrid.grid_line_alpha = 0 configurePlot(genome_plot) protein_names, protein_lengths = protein_annotation(FIRST) FIRST = False if ((min(protein_lengths) < (0.05 * sum(protein_lengths))) and len(max(protein_names, key=len)) >= 10): genome_plot.xaxis.major_label_orientation = pi / 4 genome_plot.xaxis.axis_label = "Protein" # Creates button that allows reset of plot to original state. reset_button = Button(label="Reset Plot") reset_button.js_on_click( CustomJS(args=dict(g=genome_plot), code=""" g.reset.emit() """)) # Creates text input button for user manual input of depth. ose = TextInput(title='Manually input depth:') # Creates checkboxes to show different types of mutations. syngroup = CheckboxGroup(labels=[ "Show synonymous mutations", "Show nonsynonymous mutations", "Show stopgains and stoplosses", "Show complex mutations", "Show mutations without longitudinal data" ], active=[0, 1, 2, 3, 4]) # Grabs the mutations that occur multiple times across samples.
for (var i = 0; i < x.length; i++) { y[i] = osds[f][x[i]]["total_ops"] } source.change.emit(); """) menu = get_osdlist(osds) select = Select(title="choose osd", value="osd.0", options=menu) select.js_on_change("value", callback) mid_ops = get_mid_ops(osds) # To do, use javascript to calculate the mid value instead of python callback_button = CustomJS(args=dict(source=source, mid_ops=mid_ops), code=""" var data = source.data; var y = data['y'] var x = data['x'] for (var i = 0; i < x.length; i++) { y[i] = mid_ops[i] } source.change.emit(); """) button = Button(label="mid", button_type="success") button.js_on_click(callback_button) layout = row(widgetbox(select, button), p) show(layout) # add a circle renderer with a size, color, and alpha
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_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_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_click( CustomJS( code= "console.log('toggle(inactive): active=' + this.active, this.toString())" )) toggle_active = Toggle(label="Toggle button (initially active)", button_type="success", active=True) toggle_active.js_on_click(
from bokeh.plotting import show from bokeh.layouts import column from bokeh.models import Button, CustomJS from fontawesome_icon import FontAwesomeIcon btn = Button(icon=FontAwesomeIcon(icon_name="thumbs-o-up", size=2), label="It works!") btn.js_on_click(CustomJS(code="alert('It works!')")) show(column(btn))
'salary': current.salary, 'years_experience': current.years_experience, } slider = RangeSlider(title="Max Salary", start=10000, end=110000, value=(10000, 50000), step=1000, format="0,0") slider.on_change('value', lambda attr, old, new: update()) button = Button(label="Download", button_type="success") button.js_on_click( CustomJS(args=dict(source=source), code=open(join(dirname(__file__), "download.js")).read())) columns = [ TableColumn(field="name", title="Employee Name"), TableColumn(field="salary", title="Income", formatter=NumberFormatter(format="$0,0.00")), TableColumn(field="years_experience", title="Experience (years)") ] data_table = DataTable(source=source, columns=columns, width=800) controls = column(slider, button) curdoc().add_root(row(controls, data_table))
yaxislabel = 'log10(y)' """) button_plot = Button(label = "Plot Data", button_type = "primary") #button_test= Button(label = "Test", button_type = "success") button_linear_x = Button(label = "Linear x Basis", button_type = "primary") button_log_x = Button(label = "Logarithmic x Basis", button_type = "primary") button_exp_x = Button(label = "Exponential x Basis", button_type = "primary") button_linear_y = Button(label = "Linear y Basis", button_type = "primary") button_log_y = Button(label = "Logarithmic y Basis", button_type = "primary") button_exp_y = Button(label = "Exponential y Basis", button_type = "primary") button_plot.js_on_click(callback_plot) button_linear_x.js_on_click(callback_linear_x) button_log_x.js_on_click(callback_log_x) button_exp_x.js_on_click(callback_exp_x) button_linear_y.js_on_click(callback_linear_y) button_log_y.js_on_click(callback_log_y) button_exp_y.js_on_click(callback_exp_y) button_linear_x.js_on_click(callback_plot) button_log_x.js_on_click(callback_plot) button_exp_x.js_on_click(callback_plot) button_linear_y.js_on_click(callback_plot) button_log_y.js_on_click(callback_plot)
def modify_doc(doc): # Download WIKI metadata from Quandl via API url_0 = 'https://www.quandl.com/api/v3/databases/WIKI/metadata?api_key='+Q_API_key response_0 = requests.get(url_0) # Unzip the bytes and extract the csv file into memory myzip = ZipFile(BytesIO(response_0.content)).extract('WIKI_metadata.csv') # Read the csv into pandas dataframe df_0 = pd.read_csv(myzip) # Clean up the name fields df_0['name'] = df_0['name'].apply(lambda s:s[:s.find(')')+1].rstrip()) # Drop extraneous fields and reorder df_0 = df_0.reindex(columns=['name','code']) # Make widgets stock_picker = Select(title="Select a Stock", value=df_0['name'][0], options=df_0['name'].tolist()) year_picker = Select(title="Select a Year", value="2018", options=[str(i) for i in range(2008,2019)], width=100) months = ["January","February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] month_picker = Select(title="Select a Month", value="January", options=months, width=150) widgets = row(stock_picker, year_picker, month_picker) # Get data def get_data(AV_API_key, ticker): from alpha_vantage.timeseries import TimeSeries ts = TimeSeries(key=AV_API_key) data, metadata = ts.get_daily(ticker,'full') data_dict = {} for sub in data.values(): for key, value in sub.items(): data_dict.setdefault(key[3:], []).append(float(value)) data_dict['date'] = list(data.keys()) df = pd.DataFrame.from_dict(data_dict) df['date'] = pd.to_datetime(df['date']) return df # Make figure df = get_data(AV_API_key, 'A') data_dict = df.to_dict('series') data_dict = {k:data_dict[k][::-1] for k in data_dict.keys()} source = ColumnDataSource(data=data_dict) # create a new plot with a datetime axis type p1 = figure(plot_width=800, plot_height=400, x_axis_type="datetime") p2 = figure(plot_width=800, plot_height=250, x_axis_type="datetime", x_range=p1.x_range) # create price glyphs and volume glyph p1O = p1.line(x='date', y='open', source=source, color=Spectral5[0], alpha=0.8, legend="OPEN") p1C = p1.line(x='date', y='close', source=source, color=Spectral5[1], alpha=0.8, legend="CLOSE") p1L = p1.line(x='date', y='low', source=source, color=Spectral5[4], alpha=0.8, legend="LOW") p1H = p1.line(x='date', y='high', source=source, color=Spectral5[3], alpha=0.8, legend="HIGH") p2V = p2.line(x='date', y='volume', source=source, color="black", alpha=0.8) # Add HoverTools to each line p1.add_tools(HoverTool(tooltips=[('Date','@date{%F}'),('Open','@open{($ 0.00)}'),('Close','@close{($ 0.00)}'), ('Low','@low{($ 0.00)}'),('High','@high{($ 0.00)}'),('Volume','@volume{(0.00 a)}')], formatters={'date': 'datetime'},mode='mouse')) p2.add_tools(HoverTool(tooltips=[('Date','@date{%F}'),('Open','@open{($ 0.00)}'),('Close','@close{($ 0.00)}'), ('Low','@low{($ 0.00)}'),('High','@high{($ 0.00)}'),('Volume','@volume{(0.00 a)}')], formatters={'date': 'datetime'},mode='mouse')) # Add legend p1.legend.orientation = 'horizontal' p1.legend.title = 'Daily Stock Price' p1.legend.click_policy="hide" p1.legend.location="top_left" # Add axis labels p1.xaxis.axis_label = 'Date' p2.xaxis.axis_label = 'Date' p1.yaxis.axis_label = 'Price ($USD/share)' p2.yaxis.axis_label = 'Volume (shares)' # Add tick formatting p1.yaxis[0].formatter = NumeralTickFormatter(format="$0.00") p2.yaxis[0].formatter = NumeralTickFormatter(format="0.0a") p1.outline_line_width = 1 p2.outline_line_width = 1 # Set up callbacks def update_source(attrname, old, new): # Get the current Select value ticker = df_0.loc[df_0['name'] == stock_picker.value, 'code'].iloc[0] print('ticker:', ticker) # Get the new data df = get_data(AV_API_key, ticker) dfi = df.set_index(['date']) data_dict = df.to_dict('series') data_dict = {k:data_dict[k][::-1] for k in data_dict.keys()} source.data = data_dict def update_axis(attrname, old, new): print('updating axes') # Get the current Select values year = year_picker.value month = f'{months.index(month_picker.value) + 1:02d}' start = datetime.strptime(f'{year}-{month}-01', "%Y-%m-%d") print('year: ', year) print('month: ', month) if month == '12': end = datetime.strptime(f'{str(int(year)+1)}-01-01', "%Y-%m-%d") else: end = datetime.strptime(f'{year}-{int(month)+1:02d}-01', "%Y-%m-%d") source.data = data_dict p1.x_range.start = start p1.x_range.end = end dfi = df.set_index(['date']) print(dfi.loc[end:start]) print(dfi.loc[end:start]['low'].min()*0.95) print(dfi.loc[end:start]['high'].max()*1.05) print(dfi.loc[end:start]['volume'].min()*0.95) print(dfi.loc[end:start]['volume'].max()*1.05) p1.y_range.start = dfi.loc[end:start]['low'].min()*0.95 p1.y_range.end = dfi.loc[end:start]['high'].max()*1.05 p2.y_range.start = dfi.loc[end:start]['volume'].min()*0.95 p2.y_range.end = dfi.loc[end:start]['volume'].max()*1.05 stock_picker.on_change('value', update_source) year_picker.on_change('value', update_axis) month_picker.on_change('value', update_axis) b = Button(label='Reset to Full History') b.js_on_click(CustomJS(args=dict(p1=p1, p2=p2), code=""" p1.reset.emit() p2.reset.emit() """)) c = column(Div(text="", height=8), b, width=200) # Set up layouts and add to document row1 = row(stock_picker, year_picker, month_picker, c, width=800) row2 = row(p1, width=800, height=400) row3 = row(p2, width=800, height=150) layout = column(row1, row2, row3, width=800) doc.add_root(layout) doc.title('Plot your Stock! Bokeh/Heroku App by J.R.Staunton ')
def get_NO2_plot(): merged_df = gdf.merge(data1, on='country', how='left') merged_df['week'].fillna(-1, inplace=True) merged_df['NO2'].fillna("No Data", inplace=True) merged_df['PM25'].fillna("No Data", inplace=True) # get the line plot climate_graph, CurrC = get_graph(data1, field="NO2", op="mean", title="NO2 conc. vs. weeks") def json_data(selectedWeek): week = selectedWeek merged = merged_df[(merged_df['week'] == week) | (merged_df['week'] == -1)] print(merged) merged_json = json.loads(merged.to_json()) json_data = json.dumps(merged_json) return json_data # Input GeoJSON source that contains features for plotting. geosource = GeoJSONDataSource(geojson=json_data(1)) Overall = ColumnDataSource(data1) Curr = ColumnDataSource(data1[data1['week'] == 1]) # Define a sequential multi-hue color palette. palette = brewer['Reds'][256] palette = palette[::-1] # Instantiate LinearColorMapper that linearly maps numbers in a range, into a sequence of colors. Input nan_color. color_mapper = LinearColorMapper(palette=palette, low=0, high=np.max(data1['NO2']) * 0.5, nan_color='#d9d9d9') # Create color bar. color_bar = ColorBar(color_mapper=color_mapper, label_standoff=5, width=15, height=200, border_line_color='black', location=(100, 10), orientation='vertical', major_label_text_align='left', major_label_text_color="white", background_fill_alpha=0, border_line_alpha=0) # Create figure object. p = figure(plot_height=530, plot_width=1100, toolbar_location=None, outline_line_color='white', outline_line_alpha=0, background='black', border_fill_color='black') p.add_layout(color_bar, 'left') p.background_fill_color = "black" p.xgrid.grid_line_color = None p.ygrid.grid_line_color = None p.axis.visible = False # Add patch renderer to figure. p.patches('xs', 'ys', source=geosource, fill_color={ 'field': 'NO2', 'transform': color_mapper }, line_color='black', line_width=0.25, fill_alpha=1, nonselection_fill_alpha=0.8, nonselection_fill_color="#1c1c1c", nonselection_line_color="#1c1c1c", nonselection_line_alpha=0.2) # Add hover tool hover = HoverTool(tooltips=[('Country/region', '@country'), ('NO2', '@NO2')], callback=get_callback('hover_cursor')) # Add Tap tool tap_cb = get_callback('tap_climate', args=[Overall, CurrC]) tap = TapTool(callback=tap_cb) tap_cb.args["graph"] = climate_graph tap_cb.args["field_name"] = "NO2" # add tools to figure p.tools = [hover, tap] # slider object slider = Slider(title='Week', bar_color='white', start=1, end=max(merged_df['week']), step=1, value=1, margin=(0, 0, 0, 250), orientation="horizontal", width=300) callback = get_callback('NO2_slider', [Overall, Curr]) slider.js_on_change('value', callback) callback.args["slider"] = slider callback.args["map"] = p # play button button = Button(label='► Play', width=300, margin=(12, 0, 0, 20)) animate = get_callback('climate_play_button') animate.args['button'] = button animate.args['slider'] = slider animate.args['max_week'] = max(data1['week']) button.js_on_click(animate) row2 = row(widgetbox(slider), widgetbox(button)) layout = column(p, row2) layout = row(layout, climate_graph) curdoc().add_root(layout) script, div = components(layout) return script, div