def bokeh_features_table(feature_names: List[str], feature_values: Iterable[float]) -> LayoutDOM: """ Create a 2-columns table that shows features' values Args: feature_names: The names of the features feature_values: The values of the features Returns: A Bokeh layout object of a table """ source = ColumnDataSource({ 'feature_values': feature_values, 'feature_names': feature_names }) columns = [ TableColumn(field='feature_names', title='Feature'), TableColumn(field='feature_values', title='Value', width=50) ] data_table = DataTable(source=source, columns=columns, header_row=True, width=250, height=600) return data_table
def modify_doc(doc): data = {'x': [1, 2, 3, 4], 'y': [10, 20, 30, 40]} source = ColumnDataSource(data) plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_tools( CustomAction(callback=CustomJS(args=dict(s=source), code=RECORD("data", "s.data")))) table = DataTable( columns=[TableColumn(field="x"), TableColumn(field="y")], source=source, editable=False) btn = Button(label="Click Me!", css_classes=["foo"]) @btn.on_click def btn_click(): source.patch({"x": [(0, 42)]}) doc.add_root(column(plot, table, btn))
def test_columns_sortable(self, bokeh_model_page): data = { 'x': [1, 2, 3, 4], 'y': [4, 3, 2, 1], 'd': ['foo', 'bar', 'baz', 'quux'] } source = ColumnDataSource(data) table = DataTable(columns=[ TableColumn(field="x", title="x"), TableColumn(field="y", title="y", sortable=False), TableColumn(field="d", title="d", sortable=True), ], source=source) page = bokeh_model_page(table) # index column h1 = get_table_header(page.driver, 1) assert "slick-header-sortable" in h1.get_attribute('class') h2 = get_table_header(page.driver, 2) assert "slick-header-sortable" in h2.get_attribute('class') h3 = get_table_header(page.driver, 3) assert "slick-header-sortable" not in h3.get_attribute('class') h4 = get_table_header(page.driver, 4) assert "slick-header-sortable" in h4.get_attribute('class') assert page.has_no_console_errors()
def make_table_tab(source): def get_formatter(data): if data.dtype.name == 'datetime64[ns]': return DateFormatter(format='%Y-%m-%d %H:%M:%S') if data.dtype.name in ['float64', 'int64']: return NumberFormatter(format='0.0[000]') if data.dtype.name == 'bool': return BooleanFormatter() return StringFormatter() table_columns = [ TableColumn(field='index', title='', formatter=get_formatter(df.index)) ] for col in df.columns: fmt = get_formatter(df[col]) title = col table_col = TableColumn(field=col, title=title, formatter=fmt) table_columns.append(table_col) data_table = DataTable(source=source, columns=table_columns, width=1600, height=800) panel = Panel(child=data_table, title="Table View") return panel
def get_history_module(self): self.history_dict = { k: list(self.history[k]) for k in self.config['controllables'] } self.history_dict['pred.'] = [''] * len(self.history) # self.history_dict['imple.'] = ['V'] * len(self.history) self.his_table_source = ColumnDataSource(self.history_dict) cols = [ TableColumn(field=k, title=k) for k in self.config['controllables'] ] # cols.extend([TableColumn(field='pred.', title='pred.'), TableColumn(field='imple.', title='imple.')]) cols.extend([TableColumn(field='pred.', title='pred.')]) his_table = DataTable(source=self.his_table_source, columns=cols, width=200, height=800, editable=True, reorderable=False) title = Div(text='History', sizing_mode="stretch_width", style={ 'font-size': '150%', 'color': self.txt_color }) self.his_panel.append(title) self.his_panel.append(his_table)
def mortality_source_table(self): anad_reasons = [ fish.mortality_reason for fish in self.schedule.dead_fish if fish.life_history is LifeHistory.ANADROMOUS ] res_reasons = [ fish.mortality_reason for fish in self.schedule.dead_fish if fish.life_history is LifeHistory.RESIDENT ] all_reasons = set( list(Counter(res_reasons).keys()) + list(Counter(anad_reasons).keys())) ac = Counter(anad_reasons) rc = Counter(res_reasons) anad_pct = list(100 * np.array([ac[reason] for reason in all_reasons]) / len(anad_reasons)) res_pct = list(100 * np.array([rc[reason] for reason in all_reasons]) / len(res_reasons)) source = ColumnDataSource({ 'reason': list(all_reasons), 'anad pct': anad_pct, 'res pct': res_pct }) columns = [ TableColumn(field="reason", title="Mortality reason", width=250), TableColumn(field="anad pct", title="% of anadromous", width=125), TableColumn(field="res pct", title="% of resident", width=125) ] return DataTable(source=source, columns=columns, row_headers=False, width=500, height=200)
def _addTable(self, src_pred): ''' Method adds table under the plot with position of the lines Parameters ---------- src_pred: ColumnDataSource line coords for pred lesion Output ------ Returns a table object to be added to the figure ''' columns = [ TableColumn(field='desc', title='description'), TableColumn(field='color', title='color'), TableColumn(field="x", title="X coordinates"), TableColumn(field="y", title="Y coordinates") ] table = DataTable(source=src_pred, columns=columns, editable=True, height=400) return table
def _build_plot_legend_table(self): template = """ <div style="background:<%=color%>; color:<%=color%>;"> <%= value %></div> """ formatter = HTMLTemplateFormatter(template=template) color_width = 70 pdb_width = 60 cid_width = 60 resno_width = 130 pos_width = 100 total_width = color_width + pdb_width + cid_width + resno_width + pos_width columns = [ TableColumn(field="color", title="Line Colour", width=color_width, formatter=formatter), TableColumn(field="pdb", title="PDB Code", width=pdb_width), TableColumn(field="cid", title="Chain ID", width=cid_width), TableColumn(field="resno", title="Starting Residue No", width=resno_width), TableColumn(field="seqno", title="Position Range", width=pos_width) ] data_table = DataTable(source=self.plot_legend_CDS, columns=columns, width=total_width, height=150, index_position=None, fit_columns=True) return data_table
def create_table(data): names = [] values = [] data = flatten(data) exec_mode = data.pop('execution_mode', '') exec_mode = exec_mode + '_' if exec_mode != '' else exec_mode data.pop('name', None) for key, value in data.items(): names.append(exec_mode + key) values.append(value) data = dict( names=names, values=values, ) source = ColumnDataSource(data) columns = [ TableColumn(field="names", title="Name"), TableColumn(field="values", title="Value"), ] return DataTable(source=source, columns=columns, width=800, height=280)
def fit_table(dist_names): """Tabela com os valores dos teste de aderencia para cada distribuição. Args: dist_names (list[str]): nomes das distribuição. """ source = ColumnDataSource( dict( dist_names=dist_names, chi=[0] * len(dist_names), ks=[0] * len(dist_names), wms=[0] * len(dist_names), )) formatter = NumberFormatter(format="0.000", text_align="center") return DataTable( source=source, columns=[ TableColumn(field="dist_names", title="Distribution"), TableColumn(field="chi", title="Chi", formatter=formatter), TableColumn(field="ks", title="KS", formatter=formatter), TableColumn(field="wms", title="WMS", formatter=formatter), ], width=300, index_position=None, fit_columns=True, )
def getSummary(df_tws): # ANOVA in Python: https://www.pythonfordatascience.org/anova-python/ results_data = pd.DataFrame(df_tws.describe()) df_results = results_data.reset_index() source = ColumnDataSource(df_results) template = """ <div style="background:<%= (function colorfromint(){ if(value == 1){ return("blue")} else{return("red")} }()) %>; color: white"> <%= value %></div> """ formater = HTMLTemplateFormatter(template=template) columns = [ TableColumn(field='index', title='Statistic'), TableColumn(field='retweets', title='Retweets'), TableColumn(field='favorites', title='Favourites'), TableColumn(field='sentiment', title='Sentiment', formatter=formater) ] data_table = DataTable(source=source, columns=columns, width=350, height=280, editable=False, index_position=None) return data_table
def _build_descr_match_table(self): columns = [TableColumn(field="resno", title="Res_No", width=40), TableColumn(field="match_vals", title="Score", width=40)] data_table = DataTable(source=self.descr_match_CDS, columns=columns, width=350, height=150, index_position=None, fit_columns=True) return data_table
def _build_all_descr_table(self): columns = [TableColumn(field="descr", title="Descriptor", width=40), TableColumn(field="score", title="Score", width=40)] data_table = DataTable(source=self.all_descr_CDS, columns=columns, width=350, height=150, index_position=None, fit_columns=True) return data_table
def _fill_datasets_table(self): # preprocess the time values max_date = min_date = None for ds in self.datasets: ds["_time_values"] = list( map(lambda t: np.datetime64(t).astype(datetime), ds["data"]["time"])) mx = max(ds["_time_values"]) mn = min(ds["_time_values"]) if max_date is None or mx > max_date: max_date = mx if min_date is None or mn < min_date: min_date = mn self.filtered_datasets = self.datasets self.datasets_min_date = min_date self.datasets_max_date = max_date self.datasets_source = ColumnDataSource( self._populate_datasets_table_data(self.filtered_datasets)) datasets_columns = [ TableColumn(field="names", title="Name", width=600), TableColumn(field="dates", title="Date", width=600) ] self.datasets_table = DataTable(source=self.datasets_source, columns=datasets_columns, width=600, height=350, selectable=True)
def _make_data_table(self): """ Builds the datatable portion of the final plot. """ columns = [ TableColumn(field="props", title="Property"), TableColumn(field="values", title="Value"), ] prop_source = ColumnDataSource(self._prop_df) model_id = self._node_source.data["index"][0] groupfilter = GroupFilter(column_name="id", group=model_id) data_table2_view = CDSView(source=prop_source, filters=[groupfilter]) data_table2 = DataTable( source=prop_source, view=data_table2_view, columns=columns, visible=False, index_position=None, fit_columns=True, editable=False, ) self._groupfilter = groupfilter self._prop_source = prop_source return data_table2
def __init__( self, model: DataModel, filter: typing.Optional[typing.Callable[[typing.Any], bool]] = None, ): # Note : typing.Any represent the type of the row tuple self.model = model # Note : views here should be "per-line" of data # Note : potentially a model is already a view (root of view tree... cf Ahman's Containers...) # For a "per-column" view -> model needs to be transformed (via a dataprocess) self.filter = filter # we always render ALL columns here. otherwise change your datamodel. self._table_columns = [ TableColumn(field=f, title=f, formatter=DateFormatter(format="%m/%d/%Y %H:%M:%S")) if pandas.api.types.is_datetime64_any_dtype(self.model.data.dtypes[i - 1]) else TableColumn(field=f, title=f) # CAREFUL with index for i, f in enumerate(self.model.columns) ] # TODO : some clever introspection of model to find most appropriate arguments... self._table_args = { "sortable": False, "reorderable": False, "index_position": None, } self._plot_args = dict()
def __create_transactions_table(self, source): """Creates Transactions DataTable with DataSource source passed as it's ColumnData Source. DataTable defines 4 fields that need to be passed in the source ColumnDataSource .data attribute: - .date - .product - .price - .shop Those attributes correspond to column names in .original_df and it's derivatives. Created DataTable will show details of those 4 columns for every transaction necessary. Additionally, .date field will be formatted to %d-%m-%Y format (31-01-2019) and .price field will be formatted into 0,0.00 format (1,897.34). DataTable has it's index (counter) column removed for clarity. Returns created DataTable. """ columns = [ TableColumn(field=self.date, title="Date", formatter=DateFormatter(format="%d-%m-%Y")), TableColumn(field=self.product, title="Product"), TableColumn(field=self.price, title="Price", formatter=NumberFormatter(format="0,0.00")), TableColumn(field=self.shop, title="Shop") ] dt = DataTable(source=source, columns=columns, header_row=True, index_position=None) return dt
def add_rank_table(self): columns = [ TableColumn(field="tool", title="Tool"), TableColumn(field="score", title="Weighted Score", formatter=NumberFormatter(format="0.00")), TableColumn(field="rank", title="Rank") ] self.data_table = DataTable(columns=columns, source=self.source, reorderable=True) buttons = zip( [self.ranking[k][0] for k in self.chosen_criteria], [self.ranking[k][1] for k in self.chosen_criteria], [self.weight_sliders[k] for k in self.weight_sliders.keys()]) self.app_layout.children.pop(1) b_layout = [[t[0], t[1], t[2]] for t in buttons] b_layout.append([self.rank_submit, self.b]) b_layout.append(widgetbox(self.data_table)) b_layout.append([self.clear_button]) b_layout.insert(0, [Spacer(width=300), self.swing_table]) self.app_layout.children.append(layout(b_layout))
def test_server_source_update_does_not_duplicate_data_update_event( self, bokeh_server_page: BokehServerPage) -> None: btn = Button(label="Click Me!") data = {'x': [1, 2, 3, 4], 'y': [10, 20, 30, 40]} source = ColumnDataSource(data) table = DataTable( columns=[TableColumn(field="x"), TableColumn(field="y")], source=source, editable=False) def modify_doc(doc): plot = Plot(height=400, width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.tags.append( CustomJS(name="custom-action", args=dict(s=source), code=RECORD("data", "s.data"))) @btn.on_click def btn_click(): source.data = {'x': [5, 6, 7, 8], 'y': [50, 60, 70, 80]} doc.add_root(column(plot, table, btn)) page = bokeh_server_page(modify_doc) page.eval_custom_action() results = page.results assert results == {'data': {'x': [1, 2, 3, 4], 'y': [10, 20, 30, 40]}} btn_el = find_element_for(page.driver, btn) btn_el.click() page.eval_custom_action() results = page.results assert results == {'data': {'x': [5, 6, 7, 8], 'y': [50, 60, 70, 80]}} # if the server receives something back like: # # Message 'PATCH-DOC' (revision 1) content: { # 'events': [{ # 'kind': 'ModelChanged', # 'model': {'id': '1001'}, # 'attr': 'data', 'new': {'x': [1, 2, 3, 4, 5], 'y': [10, 20, 30, 40, 50]} # }], # 'references': [] # } # # Then that means the client got our stream message and erroneously ping # ponged a full data update back to us assert not has_cds_data_patches(page.message_test_port.received)
def createTableWidgets(self): self.col_rocks = [ TableColumn(field=Ci, title=Ci) for Ci in self.column_names_rocks ] self.col_fluids = [ TableColumn(field=Ci, title=Ci) for Ci in self.column_names_fluids ] self.col_pres = [ TableColumn(field=Ci, title=Ci) for Ci in self.column_names_pres ] self.col_out = [ TableColumn(field=Ci, title=Ci) for Ci in self.column_names_output ] #Setup table widgets tablekwargs = {'width': self.pagewidth, 'editable': True} self.TW_rocks = DataTable(source=self.CDS_rocks, columns=self.col_rocks, **tablekwargs) self.TW_fluids = DataTable(source=self.CDS_fluids, columns=self.col_fluids, **tablekwargs) self.TW_pres = DataTable(source=self.CDS_pres, columns=self.col_pres, **tablekwargs) self.TW_out = DataTable(source=self.CDS_out, columns=self.col_out, **tablekwargs)
def test_copy_paste_to_textarea(self, bokeh_model_page): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1])) columns = [ TableColumn(field='x', title='x'), TableColumn(field='y', title='y') ] table = DataTable(source=source, columns=columns, editable=False, width=600) text_area = Div(text='<textarea id="T1"></textarea>') page = bokeh_model_page(column(table, text_area)) # Use reversed order to get the correct order copy_table_rows(page.driver, [2, 1]) # Copy is a little slow sleep(0.1) element = get_page_element(page.driver, '#T1') # Selenium doesn't paste until we write something to the element first # textarea works like a cell enter_text_in_cell_with_click_enter(page.driver, element, 'PASTED:') paste_values(page.driver, element) result = element.get_attribute('value') # The textarea now contains the content in the datatable assert result == '\nPASTED:\n0\t1\t1\n1\t2\t1\n' assert page.has_no_console_errors()
def _get_resource_widget(self): resources = [] num_annotated_texts = [] num_annotations = [] for resource in self.resources: resources.append(resource.resource_id) annotated_texts = resource.get_annotated_texts() num_annotated_texts.append(len(annotated_texts)) num_annotations.append( sum([len(at.annotations) for at in annotated_texts])) data = dict(resource=resources, sentences=num_annotated_texts, annotations=num_annotations) source = ColumnDataSource(data) columns = [ TableColumn(field="resource", title="Resource", width=500), TableColumn(field="sentences", title="Sentences", width=70), TableColumn(field="annotations", title="Annotations", width=880), ] data_table = DataTable(source=source, columns=columns, min_height=100, max_height=1000, height=(len(resources) + 1) * 28, width=1500, autosize_mode="none", sizing_mode="scale_both") return [Div(text='<h2>Resources</h2>'), data_table]
def save_df_as_image(df, path): source = ColumnDataSource(df) df_columns = [df.index.name] df_columns.extend(df.columns.values) columns_for_table=[] template=""" <div style="color:<%= (function colorfromint(){ if (Variation > 0) {return('green')} else if (Variation < 0) {return('red')} else {return('blue')} }())%>;"> <%=value%> </div> """ formatter = HTMLTemplateFormatter(template=template) for column in df_columns: if(column == 'Variation'): columns_for_table.append(TableColumn(field=column, title=column, formatter=formatter)) else: columns_for_table.append(TableColumn(field=column, title=column)) full_height=(26*len(df.index)) data_table = DataTable(source=source, columns=columns_for_table,fit_columns=True,height=full_height,width_policy="auto",index_position=None) export_png(data_table, filename = path)
def test_multi_row_copy(self, bokeh_model_page): data = {'x': [1,2,3,4], 'y': [0, 1, 2, 3], 'd': ['foo', 'bar', 'baz', 'quux']} source = ColumnDataSource(data) table = DataTable(columns=[ TableColumn(field="x", title="x"), TableColumn(field="y", title="y"), TableColumn(field="d", title="d"), ], source=source) text_input = TextAreaInput(css_classes=["foo"]) text_input.js_on_change('value', CustomJS(code=RECORD("value", "cb_obj.value"))) page = bokeh_model_page(column(table, text_input)) # select the third row row = get_table_row(page.driver, 1) row.click() row = get_table_row(page.driver, 3) shift_click(page.driver, row) enter_text_in_element(page.driver, row, Keys.INSERT, mod=Keys.CONTROL, click=0, enter=False) input_el = page.driver.find_element_by_css_selector('.foo') enter_text_in_element(page.driver, input_el, Keys.INSERT, mod=Keys.SHIFT, enter=False) #enter_text_in_element(page.driver, input_el, "") sleep(2.0) results = page.results assert results['value'] == '0\t1\t0\tfoo\n1\t2\t1\tbar\n2\t3\t2\tbaz\n' assert page.has_no_console_errors()
def modify_doc(doc): plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_tools( CustomAction(callback=CustomJS(args=dict(s=source), code=RECORD("data", "s.data")))) table = DataTable(columns=[ TableColumn(field="x", title="x", sortable=True), TableColumn(field="y", title="y", sortable=True) ], source=source, editable=False) button = Button(css_classes=["foo"]) def cb(): source.stream({'x': [100], 'y': [100]}) button.on_click(cb) doc.add_root(column(plot, table, button))
def test_multi_row_copy(self, bokeh_model_page) -> None: data = {'x': [1,2,3,4], 'y': [0,1,2,3], 'd': ['foo', 'bar', 'baz', 'quux']} source = ColumnDataSource(data) table = DataTable(columns=[ TableColumn(field="x", title="x"), TableColumn(field="y", title="y"), TableColumn(field="d", title="d"), ], source=source) text_input = TextInput(css_classes=["foo"]) text_input.js_on_change('value', CustomJS(code=RECORD("value", "cb_obj.value"))) page = bokeh_model_page(column(table, text_input)) row = get_table_row(page.driver, 1) row.click() row = get_table_row(page.driver, 3) shift_click(page.driver, row) enter_text_in_element(page.driver, row, Keys.INSERT, mod=Keys.CONTROL, click=0, enter=False) input_el = page.driver.find_element_by_css_selector('.foo') enter_text_in_element(page.driver, input_el, Keys.INSERT, mod=Keys.SHIFT, enter=False) enter_text_in_element(page.driver, input_el, "") results = page.results # XXX (bev) these should be newlines with a TextAreaInput but TextAreaInput # is not working in tests for some reason presently assert results['value'] == '0\t1\t0\tfoo 1\t2\t1\tbar 2\t3\t2\tbaz' assert page.has_no_console_errors()
def test_glyph_selection_updates_table(self, single_plot_page) -> None: plot = Plot(height=800, width=1000) data = {'x': [1, 2, 3, 4], 'y': [1, 1, 1, 1]} source = ColumnDataSource(data) table = DataTable(columns=[ TableColumn(field="x", title="x", sortable=True), TableColumn(field="y", title="y", sortable=True, editor=NumberEditor()) ], source=source, editable=True) plot.add_glyph(source, Rect(x='x', y='y', width=1.5, height=1)) plot.add_tools( TapTool(callback=CustomJS( code=RECORD("indices", "cb_data.source.selected.indices")))) page = single_plot_page(column(plot, table)) page.click_canvas_at_position(500, 400) assert set(page.results["indices"]) == {1, 2} assert get_table_selected_rows(page.driver) == {1, 2} assert page.has_no_console_errors() assert page.has_no_console_errors()
def test_single_row_copy_with_zero(self, bokeh_model_page) -> None: data = {'x': [1,2,3,4], 'y': [0,0,0,0], 'd': ['foo', 'bar', 'baz', 'quux']} source = ColumnDataSource(data) table = DataTable(columns=[ TableColumn(field="x", title="x"), TableColumn(field="y", title="y"), TableColumn(field="d", title="d"), ], source=source) text_input = TextInput(css_classes=["foo"]) text_input.js_on_change('value', CustomJS(code=RECORD("value", "cb_obj.value"))) page = bokeh_model_page(column(table, text_input)) row = get_table_row(page.driver, 2) row.click() enter_text_in_element(page.driver, row, Keys.INSERT, mod=Keys.CONTROL, click=0, enter=False) input_el = page.driver.find_element_by_css_selector('.foo') enter_text_in_element(page.driver, input_el, Keys.INSERT, mod=Keys.SHIFT, enter=False) enter_text_in_element(page.driver, input_el, "") sleep(0.5) results = page.results assert results['value'] == '1\t2\t0\tbar' assert page.has_no_console_errors()
def test_click_sortable(self, bokeh_model_page): data = { 'x': [1, 2, 3, 4], 'y': [4, 3, 2, 1], 'd': ['foo', 'bar', 'baz', 'quux'] } source = ColumnDataSource(data) table = DataTable(columns=[ TableColumn(field="x", title="x"), TableColumn(field="y", title="y", sortable=False), TableColumn(field="d", title="d", sortable=True), ], source=source) page = bokeh_model_page(table) for i, x in enumerate(['foo', 'bar', 'baz', 'quux'], 1): elt = get_table_cell(page.driver, i, 3) assert elt.text == x h4 = get_table_header(page.driver, 4) h4.click() for i, x in enumerate(['bar', 'baz', 'foo', 'quux'], 1): elt = get_table_cell(page.driver, i, 3) assert elt.text == x h4 = get_table_header(page.driver, 4) h4.click() for i, x in enumerate(['quux', 'foo', 'baz', 'bar'], 1): elt = get_table_cell(page.driver, i, 3) assert elt.text == x assert page.has_no_console_errors()
def data_table_selection(): global data_table_list data_table_list = [] for i in range(len(temp_list)): source_summary = ColumnDataSource(selected[i]) if len(temp_list) != 1: heading = "Summary - " + selected_filtered_data[i] else: heading = "Summary - " data_table_columns = [] for i in list(source_summary.data): if i == "level_0": data_table_columns.append(TableColumn( field=i, title='', ), ) else: data_table_columns.append(TableColumn( field=i, title=i, ), ) data_table = DataTable(source=source_summary, columns=data_table_columns, index_header='', index_position=None, width=600, height=280) data_table_heading = Div(text=heading, width=600, height=20) data_table_list.append(data_table_heading) data_table_list.append(data_table)