def test_HasProps_clone(): from bokeh.models import Plot p1 = Plot(plot_width=1000) c1 = p1.properties_with_values(include_defaults=False) p2 = p1._clone() c2 = p2.properties_with_values(include_defaults=False) assert c1 == c2
def test_atomic_plot_event_callbacks(): plot = Plot() for event_cls in [events.LODStart, events.LODEnd]: test_callback = EventCallback() plot.on_event(event_cls, test_callback) assert test_callback.event_name == None plot._trigger_event(event_cls(plot)) assert test_callback.event_name == event_cls.event_name
def test_pinch_callbacks(): plot = Plot() payload = dict(sx=3, sy=-2, x=10, y=100, scale=42) test_callback = EventCallback(['sx','sy','x','y', 'scale']) plot.on_event(events.Pinch, test_callback) assert test_callback.event_name == None plot._trigger_event(events.Pinch(plot, **payload)) assert test_callback.event_name == events.Pinch.event_name assert test_callback.payload == payload
def make_sizing_mode_plot(plot_width, plot_height, sizing_mode='scale_width'): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1])) plot = Plot( plot_height=plot_height, plot_width=plot_width, x_range=DataRange1d(), y_range=DataRange1d(), sizing_mode=sizing_mode ) plot.add_glyph(source, Rect(x='x', y='y', width=0.9, height=0.9)) return plot
def modify_doc(doc): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1], val=["a", "b"])) plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_glyph(source, Circle(x='x', y='y', size=20)) plot.add_tools(CustomAction(callback=CustomJS(args=dict(s=source), code=RECORD("data", "s.data")))) slider = Slider(start=0, end=10, value=1, title="bar", css_classes=["foo"], width=300) def cb(attr, old, new): source.data['val'] = [old, new] slider.on_change('value', cb) doc.add_root(column(slider, plot))
def make_plot(xname, yname, xax=False, yax=False): mbl = 40 if yax else 0 mbb = 40 if xax else 0 plot = Plot(x_range=xdr, y_range=ydr, background_fill_color="#efe8e2", border_fill_color='white', plot_width=200 + mbl, plot_height=200 + mbb, min_border_left=2 + mbl, min_border_right=2, min_border_top=2, min_border_bottom=2 + mbb) circle = Circle(x=xname, y=yname, fill_color="color", fill_alpha=0.2, size=4, line_color="color") r = plot.add_glyph(source, circle) xdr.renderers.append(r) ydr.renderers.append(r) xticker = BasicTicker() if xax: xaxis = LinearAxis() xaxis.axis_label = xname plot.add_layout(xaxis, 'below') xticker = xaxis.ticker plot.add_layout(Grid(dimension=0, ticker=xticker)) yticker = BasicTicker() if yax: yaxis = LinearAxis() yaxis.axis_label = yname yaxis.major_label_orientation = 'vertical' plot.add_layout(yaxis, 'left') yticker = yaxis.ticker plot.add_layout(Grid(dimension=1, ticker=yticker)) plot.add_tools(PanTool(), WheelZoomTool()) return plot
def test_setting_tools_on_plot_declaration_sets_them_on_toolbar(): pan = PanTool() plot = Plot(tools=[pan]) assert plot.toolbar.tools == [ pan ], "Remove this test when deprecation cycle is over"
def construct_map(source, fill_string='water_color', selected_color=ORANGE): assert isinstance(source, ColumnDataSource), "Require ColumnDataSource" # Plot and axes x_start, x_end = (-18, 55) y_start, y_end = (-35, 38) xdr = Range1d(x_start, x_end) ydr = Range1d(y_start, y_end) aspect_ratio = (x_end - x_start) / (y_end - y_start) plot_height = 600 plot_width = int(plot_height * aspect_ratio) plot = Plot( x_range=xdr, y_range=ydr, title="", plot_width=plot_width, plot_height=plot_height, min_border=0, **PLOT_FORMATS ) borders = Patches( xs='xs', ys='ys', fill_color=fill_string, fill_alpha=1, line_color="#FFFFFF", line_width=1, ) selected_borders = Patches( xs='xs', ys='ys', fill_color=fill_string, fill_alpha=1, line_color=selected_color, line_width=3, ) plot.add_glyph(source, borders, selection_glyph=selected_borders, nonselection_glyph=borders) # nopep8 return plot
def test_HasProps_clone(): from bokeh.models import Plot p1 = Plot(plot_width=1000) c1 = p1.changed_properties() p2 = p1.clone() c2 = p2.changed_properties() assert c1 == c2
def test_js_on_change_executes(self, single_plot_page): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1])) plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_glyph(source, Circle(x='x', y='y', size=20)) text_input = TextInput(css_classes=['foo']) text_input.js_on_change('value', CustomJS(code=RECORD("value", "cb_obj.value"))) page = single_plot_page(column(text_input, plot)) el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, el, "val1") results = page.results assert results['value'] == 'val1' # double click to highlight and overwrite old text enter_text_in_element(page.driver, el, "val2", click=2) results = page.results assert results['value'] == 'val2' # Check clicking outside input also triggers enter_text_in_element(page.driver, el, "val3", click=2, enter=False) page.click_canvas_at_position(10, 10) results = page.results assert results['value'] == 'val3' assert page.has_no_console_errors()
def plot(self, job, typename): u = utils.utils(job) colors = d3["Category20"][20] hc = {} for i, hostname in enumerate(u.hostnames): hc[hostname] = colors[i%20] plots = [] schema, _stats = u.get_type(typename) # Plot this type of data for index, event in enumerate(schema): try: plot = Plot(plot_width=400, plot_height=150, x_range = DataRange1d(), y_range = DataRange1d()) for hostname, stats in _stats.items(): rate = stats[:, index] if typename == "mem": source = ColumnDataSource({"x" : u.hours, "y" : rate}) plot.add_glyph(source, Step(x = "x", y = "y", mode = "after", line_color = hc[hostname])) else: rate = numpy.diff(rate)/numpy.diff(job.times) source = ColumnDataSource({"x" : u.hours, "y" : numpy.append(rate, rate[-1])}) plot.add_glyph(source, Step(x = "x", y = "y", mode = "after", line_color = hc[hostname])) plots += [self.add_axes(plot, event)] except: print(event + ' plot failed for jobid ' + job.id ) print(sys.exc_info()) return gridplot(*plots, ncols = len(plots)//4 + 1, toolbar_options = {"logo" : None})
def get_ws_plot( data, plot_height=300, plot_width=800, column_names=cs.column_names_weewx, column_time=cs.time_column_name_weewx, border_left=200, ): data_seconds = data data_seconds.iloc[:, 0] = data_seconds.iloc[:, 0] * 1000 plot = Plot( x_range=DataRange1d(), y_range=DataRange1d(), plot_width=plot_width, plot_height=plot_height, min_border_left=border_left, **kwargs ) add_glyphs_to_plot(column_names, column_time, data_seconds, plot) plot.add_layout(DatetimeAxis(), "below") plot.add_tools(PanTool(), WheelZoomTool(), ResizeTool(), CrosshairTool()) return plot
def test__check_compatible_scale_and_ranges_compat_numeric(): plot = Plot(x_scale=LinearScale(), x_range=Range1d()) check = plot._check_compatible_scale_and_ranges() assert check == [] plot = Plot(y_scale=LogScale(), y_range=DataRange1d()) check = plot._check_compatible_scale_and_ranges() assert check == []
def test_mousewheel_callbacks(): plot = Plot() payload = dict(sx=3, sy=-2, x=10, y=100, delta=5) test_callback = EventCallback(['sx','sy','x','y', 'delta']) plot.on_event(events.MouseWheel, test_callback) assert test_callback.event_name == None plot._trigger_event(events.MouseWheel(plot, **payload)) assert test_callback.event_name == events.MouseWheel.event_name assert test_callback.payload == payload
def make_responsive_plot(plot_width, plot_height, responsive_mode='width_ar'): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1])) plot = Plot( plot_height=plot_height, plot_width=plot_width, x_range=DataRange1d(), y_range=DataRange1d(), responsive=responsive_mode ) plot.add_glyph(source, Rect(x='x', y='y', width=0.9, height=0.9)) return plot
def test_pan_callbacks(): plot = Plot() payload = dict(sx=3, sy=-2, x=10, y=100, delta_x=2, delta_y=3.2) test_callback = EventCallback(['sx','sy','x','y', 'delta_x', 'delta_y']) plot.on_event(events.Pan, test_callback) assert test_callback.event_name == None plot._trigger_event(events.Pan(plot, **payload)) assert test_callback.event_name == events.Pan.event_name assert test_callback.payload == payload
def modify_doc(doc): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1], val=["a", "b"])) plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_glyph(source, Circle(x='x', y='y', size=20)) plot.add_tools(CustomAction(callback=CustomJS(args=dict(s=source), code=RECORD("data", "s.data")))) group = RadioButtonGroup(labels=LABELS, css_classes=["foo"]) def cb(active): source.data['val'] = [active, "b"] group.on_click(cb) doc.add_root(column(group, plot))
def modify_doc(doc): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1], val=["a", "b"])) plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_glyph(source, Circle(x='x', y='y', size=20)) plot.add_tools(CustomAction(callback=CustomJS(args=dict(s=source), code=RECORD("data", "s.data")))) text_input = TextInput(css_classes=["foo"]) def cb(attr, old, new): source.data['val'] = [old, new] text_input.on_change('value', cb) doc.add_root(column(text_input, plot))
def modify_doc(doc): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1])) plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_glyph(source, Circle(x='x', y='y', size=20)) plot.add_tools(CustomAction(callback=CustomJS(args=dict(s=source), code=RECORD("data", "s.data")))) button = Button(css_classes=['foo']) def cb(event): source.data=dict(x=[10, 20], y=[10, 10]) button.on_event('button_click', cb) doc.add_root(column(button, plot))
def test_pointevent_callbacks(): plot = Plot() payload = dict(sx=3, sy=-2, x=10, y=100) for event_cls in point_events: test_callback = EventCallback(['sx','sy','x','y']) plot.on_event(event_cls, test_callback) assert test_callback.event_name == None plot._trigger_event(event_cls(plot, **payload)) assert test_callback.event_name == event_cls.event_name assert test_callback.payload == payload
def test_color_bar_placement_and_render(output_file_url, selenium, screenshot): plot = Plot(height=HEIGHT, width=WIDTH, x_range=Range1d(0,10), y_range=Range1d(0,10), toolbar_location=None) bar_vertical_right_panel = create_vertical_color_bar_with_log_cmap() bar_vertical_right_panel.location = (0, 0) bar_vertical_in_frame = create_vertical_color_bar_with_log_cmap() bar_vertical_in_frame.location = "top_right" bar_vertical_in_frame.title = "Dummy Title" bar_vertical_in_frame.title_standoff = 7 bar_horizontal_below_panel = create_horizontal_color_bar_with_linear_cmap() bar_horizontal_below_panel.location = (0, 0) bar_horizontal_in_frame = create_horizontal_color_bar_with_linear_cmap() bar_horizontal_in_frame.location = "bottom_left" bar_horizontal_in_frame.title = "Dummy Title" plot.add_layout(bar_vertical_right_panel, 'right') plot.add_layout(bar_vertical_in_frame) plot.add_layout(bar_horizontal_below_panel, 'below') plot.add_layout(bar_horizontal_in_frame) # Save the plot and start the test save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Take screenshot screenshot.assert_is_valid()
def test_color_bar_placement_and_render(): plot = Plot(width=WIDTH, height=HEIGHT, x_range=Range1d(0,10), y_range=Range1d(0,10), toolbar_location=None) bar_vertical_right_panel = create_vertical_color_bar_with_log_cmap() bar_vertical_right_panel.location = (0, 0) bar_vertical_in_frame = create_vertical_color_bar_with_log_cmap() bar_vertical_in_frame.location = "top_right" bar_vertical_in_frame.title = "Dummy Title" bar_vertical_in_frame.title_standoff = 7 bar_horizontal_below_panel = create_horizontal_color_bar_with_linear_cmap() bar_horizontal_below_panel.location = (0, 0) bar_horizontal_in_frame = create_horizontal_color_bar_with_linear_cmap() bar_horizontal_in_frame.location = "bottom_left" bar_horizontal_in_frame.title = "Dummy Title" plot.add_layout(bar_vertical_right_panel, 'right') plot.add_layout(bar_vertical_in_frame) plot.add_layout(bar_horizontal_below_panel, 'below') plot.add_layout(bar_horizontal_in_frame) return plot
def test_patches_hover_still_works_when_a_seleciton_is_preselcted(output_file_url, selenium): # This tests an edge case interaction when Patches (specifically) is used # with a tool that requires hit testing e.g. HitTool AND a selection is # pre-made on the data source driving it. plot = Plot( x_range=Range1d(0, 100), y_range=Range1d(0, 100), min_border=0 ) source = ColumnDataSource(dict( xs=[[0, 50, 50, 0], [50, 100, 100, 50]], ys=[[0, 0, 100, 100], [0, 0, 100, 100]], color=['pink', 'blue'] )) source.selected = { '0d': {'glyph': None, 'indices': []}, '1d': {'indices': [1]}, '2d': {} } plot.add_glyph(source, Patches(xs='xs', ys='ys', fill_color='color')) plot.add_tools(HoverTool()) plot.add_layout(LinearAxis(), 'below') plot.add_layout(LinearAxis(), 'left') save(plot) selenium.get(output_file_url) assert has_no_console_errors(selenium) # Hover plot and test no error canvas = selenium.find_element_by_tag_name('canvas') actions = ActionChains(selenium) actions.move_to_element_with_offset(canvas, 100, 100) actions.perform() # If this assertion fails then there were likely errors on hover assert has_no_console_errors(selenium)
def make_figure(axes): xdr = Range1d(start=-1, end=1) ydr = Range1d(start=-1, end=1) plot = Plot(title=None, x_range=xdr, y_range=ydr, plot_width=200, plot_height=200, toolbar_location=None) plot.add_glyph(Circle(x=0, y=0, size=100)) for place in axes: plot.add_layout(LinearAxis(), aliases[place]) return plot
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("indices", "s.selected.indices")))) table = DataTable(columns=[ TableColumn(field="x"), TableColumn(field="y") ], source=source, editable=False) doc.add_root(column(plot, table))
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, editor=NumberEditor()) ], source=source, editable=True) doc.add_root(column(plot, table))
def sample_gear(): xdr = Range1d(start=-30, end=30) ydr = Range1d(start=-30, end=30) plot = Plot(title=None, x_range=xdr, y_range=ydr, plot_width=800, plot_height=800) plot.add_tools(PanTool(), WheelZoomTool(), ResetTool()) glyph = Gear(x=0, y=0, module=5, teeth=8, angle=0, shaft_size=0.2, fill_color=fill_color[2], line_color=line_color) plot.add_glyph(glyph) return plot
def test_color_bar_with_scale_alpha(): plot = Plot(width=WIDTH, height=HEIGHT, x_range=Range1d(0,10), y_range=Range1d(0,10), outline_line_alpha=0.0, toolbar_location=None) bar_vertical_in_frame = create_vertical_color_bar_with_log_cmap() bar_vertical_in_frame.scale_alpha = 0.5 plot.add_layout(bar_vertical_in_frame) return plot
def modify_doc(doc): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1], val=["a", "b"])) plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_glyph(source, Circle(x='x', y='y', size=20)) plot.add_tools(CustomAction(callback=CustomJS(args=dict(s=source), code=RECORD("data", "s.data")))) input_box = AutocompleteInput(css_classes=["foo"]) input_box.title = "title" input_box.value = "400" input_box.completions = ["100001", "12344556", "12344557", "3194567289", "209374209374"] def cb(attr, old, new): source.data['val'] = [old, new] input_box.on_change('value', cb) doc.add_root(column(input_box, plot))
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", editor=NumberEditor()) ], source=source, editable=True) doc.add_root(column(plot, table))
def modify_doc(doc): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1], val=["a", "b"])) plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_glyph(source, Circle(x='x', y='y')) plot.add_tools(CustomAction(callback=CustomJS(args=dict(s=source), code=RECORD("data", "s.data")))) spinner = Spinner(low=-1, high=10, step=0.1, value=4, css_classes=["foo"]) def cb(attr, old, new): source.data['val'] = [old, new] spinner.on_change('value', cb) doc.add_root(column(spinner, plot)) return doc
def test_plot_with_no_title_specified_creates_an_empty_title(): plot = Plot() assert plot.title.text == ""
def test_setting_logo_on_plot_declaration_sets_them_on_toolbar(): plot = Plot(logo='grey') assert plot.toolbar.logo == 'grey', "Remove this test when deprecation cycle is over"
def create(palm): fit_max = 1 fit_min = 0 doc = curdoc() # THz calibration plot scan_plot = Plot( title=Title(text="THz calibration"), x_range=DataRange1d(), y_range=DataRange1d(), plot_height=PLOT_CANVAS_HEIGHT, plot_width=PLOT_CANVAS_WIDTH, toolbar_location='right', ) # ---- tools scan_plot.toolbar.logo = None scan_plot.add_tools(PanTool(), BoxZoomTool(), WheelZoomTool(), ResetTool()) # ---- axes scan_plot.add_layout(LinearAxis(axis_label='Stage delay motor'), place='below') scan_plot.add_layout(LinearAxis(axis_label='Energy shift, eV', major_label_orientation='vertical'), place='left') # ---- grid lines scan_plot.add_layout(Grid(dimension=0, ticker=BasicTicker())) scan_plot.add_layout(Grid(dimension=1, ticker=BasicTicker())) # ---- circle cluster glyphs scan_circle_source = ColumnDataSource(dict(x=[], y=[])) scan_plot.add_glyph(scan_circle_source, Circle(x='x', y='y', line_alpha=0, fill_alpha=0.5)) # ---- circle glyphs scan_avg_circle_source = ColumnDataSource(dict(x=[], y=[])) scan_plot.add_glyph( scan_avg_circle_source, Circle(x='x', y='y', line_color='purple', fill_color='purple')) # ---- line glyphs fit_line_source = ColumnDataSource(dict(x=[], y=[])) scan_plot.add_glyph(fit_line_source, Line(x='x', y='y', line_color='purple')) # THz calibration folder path text input def path_textinput_callback(_attr, _old, _new): update_load_dropdown_menu() path_periodic_update() path_textinput = TextInput(title="THz calibration path:", value=os.path.join(os.path.expanduser('~')), width=510) path_textinput.on_change('value', path_textinput_callback) # THz calibration eco scans dropdown def scans_dropdown_callback(_attr, _old, new): scans_dropdown.label = new scans_dropdown = Dropdown(label="ECO scans", button_type='default', menu=[]) scans_dropdown.on_change('value', scans_dropdown_callback) # ---- eco scans periodic update def path_periodic_update(): new_menu = [] if os.path.isdir(path_textinput.value): for entry in os.scandir(path_textinput.value): if entry.is_file() and entry.name.endswith('.json'): new_menu.append((entry.name, entry.name)) scans_dropdown.menu = sorted(new_menu, reverse=True) doc.add_periodic_callback(path_periodic_update, 5000) # Calibrate button def calibrate_button_callback(): palm.calibrate_thz( path=os.path.join(path_textinput.value, scans_dropdown.value)) fit_max_textinput.value = str( np.ceil(palm.thz_calib_data.index.values.max())) fit_min_textinput.value = str( np.floor(palm.thz_calib_data.index.values.min())) update_calibration_plot() def update_calibration_plot(): scan_plot.xaxis.axis_label = '{}, {}'.format(palm.thz_motor_name, palm.thz_motor_unit) scan_circle_source.data.update( x=np.repeat(palm.thz_calib_data.index, palm.thz_calib_data['peak_shift'].apply(len)).tolist(), y=np.concatenate( palm.thz_calib_data['peak_shift'].values).tolist(), ) scan_avg_circle_source.data.update( x=palm.thz_calib_data.index.tolist(), y=palm.thz_calib_data['peak_shift_mean'].tolist()) x = np.linspace(fit_min, fit_max, 100) y = palm.thz_slope * x + palm.thz_intersect fit_line_source.data.update(x=np.round(x, decimals=5), y=np.round(y, decimals=5)) calib_const_div.text = """ thz_slope = {} """.format(palm.thz_slope) calibrate_button = Button(label="Calibrate THz", button_type='default', width=250) calibrate_button.on_click(calibrate_button_callback) # THz fit maximal value text input def fit_max_textinput_callback(_attr, old, new): nonlocal fit_max try: new_value = float(new) if new_value > fit_min: fit_max = new_value palm.calibrate_thz( path=os.path.join(path_textinput.value, scans_dropdown.value), fit_range=(fit_min, fit_max), ) update_calibration_plot() else: fit_max_textinput.value = old except ValueError: fit_max_textinput.value = old fit_max_textinput = TextInput(title='Maximal fit value:', value=str(fit_max)) fit_max_textinput.on_change('value', fit_max_textinput_callback) # THz fit maximal value text input def fit_min_textinput_callback(_attr, old, new): nonlocal fit_min try: new_value = float(new) if new_value < fit_max: fit_min = new_value palm.calibrate_thz( path=os.path.join(path_textinput.value, scans_dropdown.value), fit_range=(fit_min, fit_max), ) update_calibration_plot() else: fit_min_textinput.value = old except ValueError: fit_min_textinput.value = old fit_min_textinput = TextInput(title='Minimal fit value:', value=str(fit_min)) fit_min_textinput.on_change('value', fit_min_textinput_callback) # Save calibration button def save_button_callback(): palm.save_thz_calib(path=path_textinput.value) update_load_dropdown_menu() save_button = Button(label="Save", button_type='default', width=250) save_button.on_click(save_button_callback) # Load calibration button def load_dropdown_callback(_attr, _old, new): palm.load_thz_calib(os.path.join(path_textinput.value, new)) update_calibration_plot() def update_load_dropdown_menu(): new_menu = [] calib_file_ext = '.palm_thz' if os.path.isdir(path_textinput.value): for entry in os.scandir(path_textinput.value): if entry.is_file() and entry.name.endswith((calib_file_ext)): new_menu.append( (entry.name[:-len(calib_file_ext)], entry.name)) load_dropdown.button_type = 'default' load_dropdown.menu = sorted(new_menu, reverse=True) else: load_dropdown.button_type = 'danger' load_dropdown.menu = new_menu doc.add_next_tick_callback(update_load_dropdown_menu) doc.add_periodic_callback(update_load_dropdown_menu, 5000) load_dropdown = Dropdown(label="Load", menu=[], width=250) load_dropdown.on_change('value', load_dropdown_callback) # Calibration constants calib_const_div = Div(text=""" thz_slope = {} """.format(0)) # assemble tab_layout = column( row( scan_plot, Spacer(width=30), column( path_textinput, scans_dropdown, calibrate_button, fit_max_textinput, fit_min_textinput, row(save_button, load_dropdown), calib_const_div, ), )) return Panel(child=tab_layout, title="THz Calibration")
x1=np.linspace(0, 150, N), y1=np.linspace(0, 150, N), w1=np.linspace(10, 50, N), h1=np.linspace(10, 50, N), x2=np.linspace(-50, 150, N), y2=np.linspace(0, 200, N), )) xdr = Range1d(start=-100, end=200) ydr = Range1d(start=-100, end=200) plot = Plot(title=None, x_range=xdr, y_range=ydr, plot_width=300, plot_height=300, h_symmetry=False, v_symmetry=False, min_border=0, toolbar_location=None) image1 = ImageURL(url="url", x="x1", y="y1", w="w1", h="h1", anchor="center") plot.add_glyph(source, image1) image2 = ImageURL(url="url", x="x2", y="y2", w=20, h=20, anchor="top_left") plot.add_glyph(source, image2) image3 = ImageURL(url=dict(value=url), x=200, y=-100, anchor="bottom_right") plot.add_glyph(source, image3) xaxis = LinearAxis()
def test_ypan_ranges_update(self, single_plot_page) -> None: source = ColumnDataSource(dict(x=[1, 2], y=[1, 1])) plot = Plot(height=400, width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_glyph(source, Rect(x='x', y='y', width=0.9, height=0.9)) plot.add_tools(WheelPanTool(dimension='height')) code = RECORD("event_name", "cb_obj.event_name", final=False) + \ RECORD("x0", "cb_obj.x0", final=False) + \ RECORD("x1", "cb_obj.x1", final=False) + \ RECORD("y0", "cb_obj.y0", final=False) + \ RECORD("y1", "cb_obj.y1") plot.js_on_event(RangesUpdate, CustomJS(code=code)) plot.add_tools(CustomAction(callback=CustomJS(code=""))) plot.toolbar_sticky = False page = single_plot_page(plot) button = page.get_toolbar_button('wheel-pan') button.click() page.driver.execute_script(SCROLL(-200)) page.click_custom_action() results = page.results assert results['event_name'] == "rangesupdate" assert results['x0'] == 0 assert results['x1'] == 1 assert results['y0'] > 0 assert results['y1'] > 1 assert page.has_no_console_errors()
from bokeh.browserlib import view from bokeh.document import Document from bokeh.embed import file_html from bokeh.models.glyphs import Circle from bokeh.models import (Plot, LinearAxis, ColumnDataSource, Range1d, PanTool, WheelZoomTool) from bokeh.resources import INLINE x = arange(-2 * pi, 2 * pi, 0.1) y = sin(x) y2 = linspace(0, 100, len(y)) source = ColumnDataSource(data=dict(x=x, y=y, y2=y2)) plot = Plot(x_range=Range1d(start=-6.5, end=6.5), y_range=Range1d(start=-1.1, end=1.1), min_border=80) plot.extra_y_ranges = {"foo": Range1d(start=0, end=100)} circle = Circle(x="x", y="y", fill_color="red", size=5, line_color="black") plot.add_glyph(source, circle) plot.add_layout(LinearAxis(), 'below') plot.add_layout(LinearAxis(), 'left') circle2 = Circle(x="x", y="y2", fill_color="blue", size=5, line_color="black") plot.add_glyph(source, circle2, y_range_name="foo") plot.add_layout(LinearAxis(y_range_name="foo"), 'left')
def make_timeseries_datatable_plot_bokeh_server(df): source = ColumnDataSource(df) plot = Plot(title=Title(text="Rolling Spearman Rank Correlation)", align="center"), x_range=DataRange1d(), y_range=DataRange1d(), plot_width=1000, plot_height=300) plot.add_layout(LinearAxis(), 'below') yaxis = LinearAxis() plot.add_layout(yaxis, 'left') plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker)) # Add Glyphs correlation_glyph = Circle(x="Date", y="Correlation", fill_color="#396285", size=8, fill_alpha=0.5, line_alpha=0.5) target_glyph = Circle(x="Date", y="Target", fill_color="#396285", size=8, fill_alpha=0.5, line_alpha=0.5) hedge_glyph = Circle(x="Date", y="Hedge", fill_color="#396285", size=8, fill_alpha=0.5, line_alpha=0.5) correlation = plot.add_glyph(source, correlation_glyph) target = plot.add_glyph(source, target_glyph) hedge = plot.add_glyph(source, hedge_glyph) # Add the tools tooltips = [("Date", "@Date"), ("Correlation", "@Correlation"), ("Target", "@Target"), ("Hedge", "@Hedge")] correlation_hover_tool = HoverTool(renderers=[correlation], tooltips=tooltips) target_hover_tool = HoverTool(renderers=[target], tooltips=tooltips) hedge_hover_tool = HoverTool(renderers=[hedge], tooltips=tooltips) select_tool = BoxSelectTool(renderers=[target, hedge, correlation], dimensions='width') plot.add_tools(target_hover_tool, hedge_hover_tool, correlation_hover_tool, select_tool) return plot
def test_server_callback_resolve_attr_spec_tap_event(self): plot = Plot() event = Tap(plot, x=42) msg = Callback.resolve_attr_spec('cb_obj.x', event, plot) self.assertEqual(msg, {'id': plot.ref['id'], 'value': 42})
plot.title = "%s vs. taylor(%s, n=%d)" % (expr, expr, order) legend.legends = [ ("%s" % expr, [line_f_glyph]), ("taylor(%s)" % expr, [line_t_glyph]), ] source.data = dict(x=x, fy=fy, ty=ty) slider.value = order source = ColumnDataSource(data=dict(x=[], fy=[], ty=[])) xdr = Range1d(-7, 7) ydr = Range1d(-20, 200) plot = Plot(x_range=xdr, y_range=ydr, plot_width=800, plot_height=400) line_f = Line(x="x", y="fy", line_color="blue", line_width=2) line_f_glyph = plot.add_glyph(source, line_f) plot.add_layout(line_f_glyph) line_t = Line(x="x", y="ty", line_color="red", line_width=2) line_t_glyph = plot.add_glyph(source, line_t) plot.add_layout(line_t_glyph) xaxis = LinearAxis() plot.add_layout(xaxis, 'below') yaxis = LinearAxis() plot.add_layout(yaxis, 'left')
def pyramid(): xdr = DataRange1d() ydr = FactorRange(factors=groups) y_scale = CategoricalScale() plot = Plot(x_range=xdr, y_range=ydr, y_scale=y_scale, plot_width=600, plot_height=500, toolbar_location=None) xaxis = LinearAxis() plot.add_layout(xaxis, 'below') plot.add_layout(CategoricalAxis(), 'left') plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker)) m = HBar(left="value", right=0, y="group", height=1, fill_color="#3B8686") mglyph = plot.add_glyph(source_pyramid_m, m) f = HBar(left=0, right="value", y="group", height=1, fill_color="#CFF09E") fglyph = plot.add_glyph(source_pyramid_f, f) plot.add_layout(Legend(items=[("Male", [mglyph]), ("Female", [fglyph])])) return plot
def verify_axis(self, axis_name): plot = Plot() # no need for setUp() range_obj = getattr(plot, 'extra_{}_ranges'.format(axis_name)) range_obj['foo_range'] = self.get_range_instance() self.assertTrue(range_obj['foo_range'])
class TaskStream(DashboardComponent): """ Task Stream The start and stop time of tasks as they occur on each core of the cluster. """ def __init__(self, n_rectangles=1000, clear_interval=20000, **kwargs): """ kwargs are applied to the bokeh.models.plots.Plot constructor """ self.n_rectangles = n_rectangles self.clear_interval = clear_interval self.last = 0 self.source = ColumnDataSource(data=dict(start=[], duration=[], key=[], name=[], color=[], worker=[], y=[], worker_thread=[], alpha=[])) x_range = DataRange1d() y_range = DataRange1d(range_padding=0) self.root = Plot(title=Title(text="Task Stream"), id='bk-task-stream-plot', x_range=x_range, y_range=y_range, toolbar_location="above", min_border_right=35, **kwargs) self.root.add_glyph( self.source, Rect(x="start", y="y", width="duration", height=0.8, fill_color="color", line_color="color", line_alpha=0.6, fill_alpha="alpha", line_width=3)) self.root.add_layout(DatetimeAxis(axis_label="Time"), "below") ticker = BasicTicker(num_minor_ticks=0) self.root.add_layout( LinearAxis(axis_label="Worker Core", ticker=ticker), "left") self.root.add_layout( Grid(dimension=1, grid_line_alpha=0.4, ticker=ticker)) hover = HoverTool(point_policy="follow_mouse", tooltips=""" <div> <span style="font-size: 12px; font-weight: bold;">@name:</span> <span style="font-size: 10px; font-family: Monaco, monospace;">@duration</span> <span style="font-size: 10px;">ms</span> </div> """) # export = ExportTool() # export.register_plot(self.root) self.root.add_tools( hover, # export, BoxZoomTool(), ResetTool(reset_size=False), PanTool(dimensions="width"), WheelZoomTool(dimensions="width")) # Required for update callback self.task_stream_index = [0] def update(self, messages): with log_errors(): index = messages['task-events']['index'] old = rectangles = messages['task-events']['rectangles'] if not index or index[-1] == self.task_stream_index[0]: return ind = bisect(index, self.task_stream_index[0]) rectangles = { k: [v[i] for i in range(ind, len(index))] for k, v in rectangles.items() } self.task_stream_index[0] = index[-1] # If there has been a significant delay then clear old rectangles if rectangles['start']: m = min(map(add, rectangles['start'], rectangles['duration'])) if m > self.last: self.last, last = m, self.last if m > last + self.clear_interval: self.source.data.update(rectangles) return self.source.stream(rectangles, self.n_rectangles)
def __init__(self, **kwargs): names = [ 'processes', 'disk-read', 'cores', 'cpu', 'disk-write', 'memory', 'last-seen', 'memory_percent', 'host' ] self.source = ColumnDataSource({k: [] for k in names}) columns = { name: TableColumn(field=name, title=name.replace('_percent', ' %')) for name in names } cnames = [ 'host', 'cores', 'processes', 'memory', 'cpu', 'memory_percent' ] formatters = { 'cpu': NumberFormatter(format='0.0 %'), 'memory_percent': NumberFormatter(format='0.0 %'), 'memory': NumberFormatter(format='0 b'), 'latency': NumberFormatter(format='0.00000'), 'last-seen': NumberFormatter(format='0.000'), 'disk-read': NumberFormatter(format='0 b'), 'disk-write': NumberFormatter(format='0 b'), 'net-send': NumberFormatter(format='0 b'), 'net-recv': NumberFormatter(format='0 b') } table = DataTable( source=self.source, columns=[columns[n] for n in cnames], ) for name in cnames: if name in formatters: table.columns[cnames.index(name)].formatter = formatters[name] mem_plot = Plot(title=Title(text="Memory Usage (%)"), toolbar_location=None, x_range=Range1d(start=0, end=1), y_range=Range1d(start=-0.1, end=0.1), **kwargs) mem_plot.add_glyph( self.source, Circle(x='memory_percent', y=0, size=10, fill_alpha=0.5)) mem_plot.add_layout(LinearAxis(), 'below') hover = HoverTool(point_policy="follow_mouse", tooltips=""" <div> <span style="font-size: 10px; font-family: Monaco, monospace;">@host: </span> <span style="font-size: 10px; font-family: Monaco, monospace;">@memory_percent</span> </div> """) mem_plot.add_tools(hover, BoxSelectTool()) if 'sizing_mode' in kwargs: sizing_mode = {'sizing_mode': kwargs['sizing_mode']} else: sizing_mode = {} self.root = column(mem_plot, table, id='bk-worker-table', **sizing_mode)
def __init__(self, **kwargs): self.source = ColumnDataSource( data={ 'time': [], 'cpu': [], 'memory_percent': [], 'network-send': [], 'network-recv': [] }) x_range = DataRange1d(follow='end', follow_interval=30000, range_padding=0) resource_plot = Plot(x_range=x_range, y_range=Range1d(start=0, end=1), toolbar_location=None, min_border_bottom=10, **kwargs) line_opts = dict(line_width=2, line_alpha=0.8) g1 = resource_plot.add_glyph( self.source, Line(x='time', y='memory_percent', line_color="#33a02c", **line_opts)) g2 = resource_plot.add_glyph( self.source, Line(x='time', y='cpu', line_color="#1f78b4", **line_opts)) resource_plot.add_layout( LinearAxis(formatter=NumeralTickFormatter(format="0 %")), 'left') legend_opts = dict(location='top_left', orientation='horizontal', padding=5, margin=5, label_height=5) resource_plot.add_layout( Legend(items=[('Memory', [g1]), ('CPU', [g2])], **legend_opts)) network_plot = Plot(x_range=x_range, y_range=DataRange1d(start=0), toolbar_location=None, **kwargs) g1 = network_plot.add_glyph( self.source, Line(x='time', y='network-send', line_color="#a6cee3", **line_opts)) g2 = network_plot.add_glyph( self.source, Line(x='time', y='network-recv', line_color="#b2df8a", **line_opts)) network_plot.add_layout(DatetimeAxis(axis_label="Time"), "below") network_plot.add_layout(LinearAxis(axis_label="MB/s"), 'left') network_plot.add_layout( Legend(items=[('Network Send', [g1]), ('Network Recv', [g2])], **legend_opts)) tools = [ PanTool(dimensions='width'), WheelZoomTool(dimensions='width'), BoxZoomTool(), ResetTool() ] if 'sizing_mode' in kwargs: sizing_mode = {'sizing_mode': kwargs['sizing_mode']} else: sizing_mode = {} combo_toolbar = ToolbarBox(tools=tools, logo=None, toolbar_location='right', **sizing_mode) self.root = row(column(resource_plot, network_plot, **sizing_mode), column(combo_toolbar, **sizing_mode), id='bk-resource-profiles-plot', **sizing_mode) # Required for update callback self.resource_index = [0]
def __init__(self, **kwargs): data = progress_quads(dict(all={}, memory={}, erred={}, released={})) self.source = ColumnDataSource(data=data) x_range = DataRange1d() y_range = Range1d(-8, 0) self.root = Plot(id='bk-task-progress-plot', x_range=x_range, y_range=y_range, toolbar_location=None, **kwargs) self.root.add_glyph( self.source, Quad(top='top', bottom='bottom', left='left', right='right', fill_color="#aaaaaa", line_color="#aaaaaa", fill_alpha=0.2)) self.root.add_glyph( self.source, Quad(top='top', bottom='bottom', left='left', right='released-loc', fill_color="color", line_color="color", fill_alpha=0.6)) self.root.add_glyph( self.source, Quad(top='top', bottom='bottom', left='released-loc', right='memory-loc', fill_color="color", line_color="color", fill_alpha=1.0)) self.root.add_glyph( self.source, Quad(top='top', bottom='bottom', left='erred-loc', right='erred-loc', fill_color='#000000', line_color='#000000', fill_alpha=0.3)) self.root.add_glyph( self.source, Text(text='show-name', y='bottom', x='left', x_offset=5, text_font_size=value('10pt'))) self.root.add_glyph( self.source, Text(text='done', y='bottom', x='right', x_offset=-5, text_align='right', text_font_size=value('10pt'))) hover = HoverTool(point_policy="follow_mouse", tooltips=""" <div> <span style="font-size: 14px; font-weight: bold;">Name:</span> <span style="font-size: 10px; font-family: Monaco, monospace;">@name</span> </div> <div> <span style="font-size: 14px; font-weight: bold;">All:</span> <span style="font-size: 10px; font-family: Monaco, monospace;">@all</span> </div> <div> <span style="font-size: 14px; font-weight: bold;">Memory:</span> <span style="font-size: 10px; font-family: Monaco, monospace;">@memory</span> </div> <div> <span style="font-size: 14px; font-weight: bold;">Erred:</span> <span style="font-size: 10px; font-family: Monaco, monospace;">@erred</span> </div> """) self.root.add_tools(hover)
class TaskProgress(DashboardComponent): """ Progress bars per task type """ def __init__(self, **kwargs): data = progress_quads(dict(all={}, memory={}, erred={}, released={})) self.source = ColumnDataSource(data=data) x_range = DataRange1d() y_range = Range1d(-8, 0) self.root = Plot(id='bk-task-progress-plot', x_range=x_range, y_range=y_range, toolbar_location=None, **kwargs) self.root.add_glyph( self.source, Quad(top='top', bottom='bottom', left='left', right='right', fill_color="#aaaaaa", line_color="#aaaaaa", fill_alpha=0.2)) self.root.add_glyph( self.source, Quad(top='top', bottom='bottom', left='left', right='released-loc', fill_color="color", line_color="color", fill_alpha=0.6)) self.root.add_glyph( self.source, Quad(top='top', bottom='bottom', left='released-loc', right='memory-loc', fill_color="color", line_color="color", fill_alpha=1.0)) self.root.add_glyph( self.source, Quad(top='top', bottom='bottom', left='erred-loc', right='erred-loc', fill_color='#000000', line_color='#000000', fill_alpha=0.3)) self.root.add_glyph( self.source, Text(text='show-name', y='bottom', x='left', x_offset=5, text_font_size=value('10pt'))) self.root.add_glyph( self.source, Text(text='done', y='bottom', x='right', x_offset=-5, text_align='right', text_font_size=value('10pt'))) hover = HoverTool(point_policy="follow_mouse", tooltips=""" <div> <span style="font-size: 14px; font-weight: bold;">Name:</span> <span style="font-size: 10px; font-family: Monaco, monospace;">@name</span> </div> <div> <span style="font-size: 14px; font-weight: bold;">All:</span> <span style="font-size: 10px; font-family: Monaco, monospace;">@all</span> </div> <div> <span style="font-size: 14px; font-weight: bold;">Memory:</span> <span style="font-size: 10px; font-family: Monaco, monospace;">@memory</span> </div> <div> <span style="font-size: 14px; font-weight: bold;">Erred:</span> <span style="font-size: 10px; font-family: Monaco, monospace;">@erred</span> </div> """) self.root.add_tools(hover) def update(self, messages): with log_errors(): msg = messages['progress'] if not msg: return d = progress_quads(msg) self.source.data.update(d) if messages['tasks']['deque']: self.root.title.text = ( "Progress -- total: %(total)s, " "in-memory: %(in-memory)s, processing: %(processing)s, " "waiting: %(waiting)s, failed: %(failed)s" % messages['tasks']['deque'][-1])
d3 = summer_end + (calendar_end - summer_end) / 2 text_source = ColumnDataSource( dict( dates=[d1, d2, d3], times=[dt.time(11, 30)] * 3, texts=["CST (UTC+1)", "CEST (UTC+2)", "CST (UTC+1)"], )) xdr = DataRange1d() ydr = DataRange1d() title = "Daylight Hours - Warsaw, Poland" plot = Plot(title=title, x_range=xdr, y_range=ydr, plot_width=800, plot_height=400) patch1 = Patch(x="dates", y="times", fill_color="skyblue", fill_alpha=0.8) plot.add_glyph(patch1_source, patch1) patch2 = Patch(x="dates", y="times", fill_color="orange", fill_alpha=0.8) plot.add_glyph(patch2_source, patch2) line1 = Line(x="dates", y="sunrises", line_color="yellow", line_width=2) line1_glyph = plot.add_glyph(source, line1) line2 = Line(x="dates", y="sunsets", line_color="red", line_width=2) line2_glyph = plot.add_glyph(source, line2)
def test_plot_raises_error_if_toolbar_and_tools_are_set(): with pytest.raises(ValueError): Plot(tools=[PanTool()], toolbar=Toolbar())
WheelZoomTool, PreviewSaveTool, Legend, ) from bokeh.resources import INLINE x = np.linspace(-2 * pi, 2 * pi, 1000) y = sin(x) z = cos(x) source = ColumnDataSource(data=dict(x=x, y=y)) xdr = DataRange1d() ydr = DataRange1d() plot = Plot(x_range=xdr, y_range=ydr, min_border=50) line_glyph = Line(x="x", y="y", line_color="blue") line = plot.add_glyph(source, line_glyph) plot.add_layout(LinearAxis(), 'above') plot.add_layout(LinearAxis(), 'below') plot.add_layout(LinearAxis(), 'left') plot.add_layout(LinearAxis(), 'right') pan = PanTool() wheel_zoom = WheelZoomTool() preview_save = PreviewSaveTool() plot.add_tools(pan, wheel_zoom, preview_save)
def make_correlation_datatable(correl_df): """ the input datframe must have columns ['Target (as string)', 'Hedge (as string)', 'Correlation ( as float )'] :param correl_df: :return: """ correl_df.reset_index(inplace=True) source = ColumnDataSource(correl_df) target_ts_asset = sorted(correl_df["Target"].unique()) hedge_ts_asset = sorted(correl_df["Hedge"].unique()) columns = [ TableColumn(field="Target", title="Target Timeseries", formatter=StringFormatter(font_style="bold", text_color='red')), TableColumn(field="Hedge", title="Hedge Timeseries", formatter=StringFormatter(font_style="bold", text_color='blue')), TableColumn(field="Correlation", title="Correlation", formatter=StringFormatter(font_style="bold", text_color='darkgreen')) ] data_table = DataTable(source=source, columns=columns, editable=False, width=1000) plot = Plot(title=Title( text="Correlations, Target vs. Hedge Timeseries)", align="center"), x_range=DataRange1d(), y_range=DataRange1d(), plot_width=1000, plot_height=300) # Set up x & y axis plot.add_layout(LinearAxis(), 'below') yaxis = LinearAxis() plot.add_layout(yaxis, 'left') plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker)) # Add Glyphs correlation_glyph = Circle(x="index", y="Correlation", fill_color="#396285", size=8, fill_alpha=0.5, line_alpha=0.5) target_glyph = Circle(x="index", y="Target", fill_color="#396285", size=8, fill_alpha=0.5, line_alpha=0.5) hedge_glyph = Circle(x="index", y="Hedge", fill_color="#396285", size=8, fill_alpha=0.5, line_alpha=0.5) correlation = plot.add_glyph(source, correlation_glyph) target = plot.add_glyph(source, target_glyph) hedge = plot.add_glyph(source, hedge_glyph) # Add the tools tooltips = [("Correlation", "@Correlation"), ("Target", "@Target"), ("Hedge", "@Hedge")] correlation_hover_tool = HoverTool(renderers=[correlation], tooltips=tooltips) target_hover_tool = HoverTool(renderers=[target], tooltips=tooltips) hedge_hover_tool = HoverTool(renderers=[hedge], tooltips=tooltips) select_tool = BoxSelectTool(renderers=[target, hedge, correlation], dimensions='width') plot.add_tools(target_hover_tool, hedge_hover_tool, correlation_hover_tool, select_tool) layout = Column(plot, data_table) the_doc = Document() the_doc.add_root(layout) return the_doc
nx.draw(G, with_labels=True, node_size=nodeSize2, node_color='#EFC9AF', node_shape='h', #node_shape="d,h,o,p,s,v,x," alpha=0.7, #node transparancy rate out of '1' linewidths=4, font_size=10, font_color='#104C91', font_weight='bold', width=1, edge_color='#1F8AC0' ) # -------------------- Setting a Plot option part -------------------- plot = Plot(plot_width=1000, plot_height=750, x_range=Range1d(-1.2, 1.2), y_range=Range1d(-1.2, 1.2)) plot.title.text = "My Positive Words Graph (hold 'shift' key for multi-clicking)" plot.add_tools(HoverTool(tooltips=None), TapTool(), BoxSelectTool()) # -------------------- Edge adding in Graph part -------------------- popular = dict() G = nx.DiGraph() for line in posWordsList: words = line.split() # adding edge G.add_edge(words[0], words[1]) G.add_edge(words[1], words[2]) # word-frequency for word in words:
def add_autocomplete(doc): # note: for some reason, bokeh_server_page requires a 'canvas' in the document plot = Plot() doc.add_root(column(text_input, plot))
def make_example_datatable(): source = ColumnDataSource(mpg) print(source.column_names) manufacturers = sorted(mpg["manufacturer"].unique()) models = sorted(mpg["model"].unique()) transmissions = sorted(mpg["trans"].unique()) drives = sorted(mpg["drv"].unique()) classes = sorted(mpg["class"].unique()) columns = [ TableColumn(field="manufacturer", title="Manufacturer", editor=SelectEditor(options=manufacturers), formatter=StringFormatter(font_style="bold")), TableColumn(field="model", title="Model", editor=StringEditor(completions=models)), TableColumn(field="displ", title="Displacement", editor=NumberEditor(step=0.1), formatter=NumberFormatter(format="0.0")), TableColumn(field="year", title="Year", editor=IntEditor()), TableColumn(field="cyl", title="Cylinders", editor=IntEditor()), TableColumn(field="trans", title="Transmission", editor=SelectEditor(options=transmissions)), TableColumn(field="drv", title="Drive", editor=SelectEditor(options=drives)), TableColumn(field="class", title="Class", editor=SelectEditor(options=classes)), TableColumn(field="cty", title="City MPG", editor=IntEditor()), TableColumn(field="hwy", title="Highway MPG", editor=IntEditor()), ] data_table = DataTable(source=source, columns=columns, editable=True, width=1000) plot = Plot(title=None, x_range=DataRange1d(), y_range=DataRange1d(), plot_width=1000, plot_height=300) # Set up x & y axis plot.add_layout(LinearAxis(), 'below') yaxis = LinearAxis() plot.add_layout(yaxis, 'left') plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker)) # Add Glyphs cty_glyph = Circle(x="index", y="cty", fill_color="#396285", size=8, fill_alpha=0.5, line_alpha=0.5) hwy_glyph = Circle(x="index", y="hwy", fill_color="#CE603D", size=8, fill_alpha=0.5, line_alpha=0.5) cty = plot.add_glyph(source, cty_glyph) hwy = plot.add_glyph(source, hwy_glyph) # Add the tools tooltips = [ ("Manufacturer", "@manufacturer"), ("Model", "@model"), ("Displacement", "@displ"), ("Year", "@year"), ("Cylinders", "@cyl"), ("Transmission", "@trans"), ("Drive", "@drv"), ("Class", "@class"), ] cty_hover_tool = HoverTool(renderers=[cty], tooltips=tooltips + [("City MPG", "@cty")]) hwy_hover_tool = HoverTool(renderers=[hwy], tooltips=tooltips + [("Highway MPG", "@hwy")]) select_tool = BoxSelectTool(renderers=[cty, hwy], dimensions='width') plot.add_tools(cty_hover_tool, hwy_hover_tool, select_tool) layout = Column(plot, data_table) doc = Document() doc.add_root(layout) return doc
def write_bokeh_graph(data_frame, html_output, project_code): df_tp = data_frame.T df_tp.index = pd.to_datetime(df_tp.index) df_tp.sort_index(inplace=True) df_columns_count = df_tp.shape[0] df_rows_count = df_tp.shape[1] colors = viridis(len(df_tp.columns)) # option_sets hover = HoverTool(tooltips=[("name", "@name"), ("time", "@time"), ("count", "@count"), ] ) tools_opt = ["resize", hover, "save", "pan", "wheel_zoom", "reset"] graph_opt = dict(width=900, x_axis_type="datetime", toolbar_location="left", tools=tools_opt, toolbar_sticky=False, background_fill_alpha=0, border_fill_alpha=0, ) line_opt = dict(line_width=3, alpha=0.8) output_file(html_output, mode="inline") legend_items = [] # figure and line glyphs warning_figure = figure(title=project_code + " rvt warnings", **graph_opt, ) for i, warning_type in enumerate(df_tp.columns): # print(f"df_tp.index is: \n{df_tp.index}") line_name_dict = [warning_type for _ in range(df_columns_count)] cds = ColumnDataSource(data=dict(x=df_tp.index, y=df_tp[warning_type], name=line_name_dict, count=df_tp[warning_type], time=df_tp.index.strftime("%Y-%m-%d %H:%M:%S"), ) ) warning_figure.line("x", "y", color=colors[i], name="name", source=cds, **line_opt ) legend_items.append((warning_type, colors[i])) square_size, legend_sq_offset = 20, 20 legend_plot_height = df_rows_count * (legend_sq_offset + square_size) # print(f"plot height is: {legend_plot_height}") legend = Plot(plot_width=900, plot_height=legend_plot_height, x_range=Range1d(0, 300), y_range=Range1d(0, legend_plot_height), toolbar_location="left", background_fill_alpha=0, border_fill_alpha=0, outline_line_alpha=0, ) for i, item in enumerate(legend_items): warn_type = item[0] color = item[1] square_y_pos = legend_plot_height - legend_sq_offset - i * (legend_sq_offset + square_size) square = Square(x=square_size, y=square_y_pos, size=square_size, fill_color=color, line_alpha=0, ) legend.add_glyph(square) warning_count_text = str(df_tp[warn_type][-1]).rjust(5) warning_text = warn_type count_txt = Text(x=square_size + 15, y=square_y_pos, text_align="right", text_baseline="middle", text=[warning_count_text], text_font_size="10pt", ) legend.add_glyph(count_txt) warn_txt = Text(x=square_size + 16, y=square_y_pos, text_align="left", text_baseline="middle", text=[warning_text[:120]], text_font_size="10pt", ) legend.add_glyph(warn_txt) save(column(style_plot(warning_figure), legend)) print(colorful.bold_green(f" {html_output}\n updated successfully.")) return df_tp
document = Document() session = Session() session.use_doc('linked_tap_server') session.load_document(document) N = 9 x = np.linspace(-2, 2, N) y = x**2 source1 = ColumnDataSource(dict(x=x, y=y, size=[20] * N)) xdr1 = DataRange1d(sources=[source1.columns("x")]) ydr1 = DataRange1d(sources=[source1.columns("y")]) plot1 = Plot(title="Plot1", x_range=xdr1, y_range=ydr1, plot_width=400, plot_height=400) plot1.tools.append(TapTool(plot=plot1)) plot1.add_glyph(source1, Circle(x="x", y="y", size="size", fill_color="red")) plot1.toolbar_location = None source2 = ColumnDataSource(dict(x=x, y=y, color=["blue"] * N)) xdr2 = DataRange1d(sources=[source2.columns("x")]) ydr2 = DataRange1d(sources=[source2.columns("y")]) plot2 = Plot(title="Plot2", x_range=xdr2, y_range=ydr2, plot_width=400, plot_height=400) plot2.tools.append(TapTool(plot=plot2))
def test_plot_raises_error_if_toolbar_and_logo_are_set(): with pytest.raises(ValueError): Plot(logo='grey', toolbar=Toolbar())
import numpy as np from bokeh.io import curdoc, show from bokeh.models import ColumnDataSource, Grid, HexDot, LinearAxis, Plot N = 9 x = np.linspace(-2, 2, N) y = x**2 sizes = np.linspace(10, 20, N) source = ColumnDataSource(dict(x=x, y=y, sizes=sizes)) plot = Plot( title=None, plot_width=300, plot_height=300, min_border=0, toolbar_location=None) glyph = HexDot(x="x", y="y", size="sizes", line_color="#dd1c77", fill_color=None) plot.add_glyph(source, glyph) xaxis = LinearAxis() plot.add_layout(xaxis, 'below') yaxis = LinearAxis() plot.add_layout(yaxis, 'left') plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker)) plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker)) curdoc().add_root(plot) show(plot)
class Population(object): year = 2010 location = "World" def __init__(self): from bokeh.models import ColumnDataSource from bokeh.document import Document # from bokeh.session import Session from bokeh.sampledata.population import load_population self.document = curdoc() #Document() self.session = session # self.session = Session() # self.session.use_doc('population_reveal') # self.session.load_document(self.document) self.df = load_population() self.source_pyramid = ColumnDataSource(data=dict()) # just render at the initialization self._render() def _render(self): self.pyramid_plot() self.create_layout() self.document.add(self.layout) self.update_pyramid() def pyramid_plot(self): from bokeh.models import (Plot, DataRange1d, LinearAxis, Grid, Legend, SingleIntervalTicker) from bokeh.models.glyphs import Quad xdr = DataRange1d() ydr = DataRange1d() self.plot = Plot(title="Widgets", x_range=xdr, y_range=ydr, plot_width=600, plot_height=600) xaxis = LinearAxis() self.plot.add_layout(xaxis, 'below') yaxis = LinearAxis(ticker=SingleIntervalTicker(interval=5)) self.plot.add_layout(yaxis, 'left') self.plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker)) self.plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker)) male_quad = Quad(left="male", right=0, bottom="groups", top="shifted", fill_color="#3B8686") male_quad_glyph = self.plot.add_glyph(self.source_pyramid, male_quad) female_quad = Quad(left=0, right="female", bottom="groups", top="shifted", fill_color="#CFF09E") female_quad_glyph = self.plot.add_glyph(self.source_pyramid, female_quad) self.plot.add_layout( Legend(legends=dict(Male=[male_quad_glyph], Female=[female_quad_glyph]))) def on_year_change(self, attr, old, new): self.year = int(new) self.update_pyramid() def on_location_change(self, attr, old, new): self.location = new self.update_pyramid() def create_layout(self): from bokeh.models.widgets import Select, HBox, VBox years = list(map(str, sorted(self.df.Year.unique()))) locations = sorted(self.df.Location.unique()) year_select = Select(title="Year:", value="2010", options=years) location_select = Select(title="Location:", value="World", options=locations) year_select.on_change('value', self.on_year_change) location_select.on_change('value', self.on_location_change) controls = HBox(year_select, location_select) self.layout = VBox(controls, self.plot) def update_pyramid(self): pyramid = self.df[(self.df.Location == self.location) & (self.df.Year == self.year)] male = pyramid[pyramid.Sex == "Male"] female = pyramid[pyramid.Sex == "Female"] total = male.Value.sum() + female.Value.sum() male_percent = -male.Value / total female_percent = female.Value / total groups = male.AgeGrpStart.tolist() shifted = groups[1:] + [groups[-1] + 5] self.source_pyramid.data = dict( groups=groups, shifted=shifted, male=male_percent, female=female_percent, )
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))