def create_panel(dynamic, static, title, size=60): """ return a Panel object with title """ # create a column layout of widgets for setting the dynamic parameters dlist = [] for d in dynamic: value = r0[title][d] slider = widgetbox(Slider(title=d, value=value, start=0, end=10 * value), width=400, height=size) slider.children[0].on_change('value', update_figs) text = widgetbox(PreText(text='range:'), width=60, height=size) minus = widgetbox(Button(label='-'), width=size, height=size) plus = widgetbox(Button(label='+'), width=size, height=size) minus.children[0].on_click(update_sliders) plus.children[0].on_click(update_sliders) dlist.append(column(slider, row(minus, text, plus))) dcol = column(dlist) # create a column layout of TextInput widgets for setting the static parameters slist = [] for s in static: value = str(r0[title][s]) text = widgetbox(TextInput(value=value, title=s), height=size) text.children[0].on_change('value', update_figs) slist.append(text) scol = column(slist) return Panel(child=row(dcol, scol), title=title)
def test_gridplot_merge_tools_nested(): p1, p2, p3, p4, p5, p6, p7 = figure(), figure(), figure(), figure(), figure(), figure(), figure() r1 = row(p1, p2) r2 = row(p3, p4) c = column(row(p5), row(p6)) gridplot([[r1, r2], [c, p7]], merge_tools=True) for p in p1, p2, p3, p4, p5, p6, p7: assert p.toolbar_location is None
def __init__(self, xs, ys): self.xs=xs self.ys=ys self.source = ColumnDataSource(data=dict(xs=xs, ys=ys)) self.fig = figure(title='sin function', x_range=[min(xs), max(ys)], y_range=[min(ys), max(ys)]) self.fig.line('xs', 'ys', source=self.source) self.text = TextInput(title='Title', value='sin function') self.offset = Slider(title="offset", value=0.0, start=-5.0, end=5.0, step=0.1) self.amplitude = Slider(title="amplitude", value=1.0, start=-5.0, end=5.0, step=0.1) self.phase = Slider(title="phase", value=0.0, start=0.0, end=2*np.pi, step=0.1) self.freq = Slider(title="frequency", value=1.0, start=0.1, end=5.1, step=0.1) widget_list = [self.text, self.offset, self.amplitude, self.phase, self.freq] for widget in widget_list: if widget!=self.text: widget.on_change('value', self.update_data) else: widget.on_change('value', self.update_title) inputs=widgetbox(*[widget_list]) self.plot=row(inputs,self.fig,width=800)
def test_layout_html_on_parent_first(): p = Plot(x_range=Range1d(), y_range=Range1d()) layout = row(p) bie.get_layout_html(layout) bie.get_layout_html(p, height=100, width=100)
def interactive_figure(self): """Add interactivity, ie. the option to show/hide lines to the figure.""" lines = self.plot_figure() # Generates a list of lines labels = [line for line in lines.keys()] # Prepare a list of labels for the tickboxes lineNames = ['l'+str(x) for x in range(len(lines))] # Prepare a list of names for the lines lines = {k: v for k, v in zip(lineNames, lines.values())} # Create a dictionary {name: line} activeL = list(range(len(lines))) # List of all line index to mark them as active in CheckboxGroup JScode = [self._visible_line_JS(k) for k in lines] # Generate JavaScript for each line JScode = '\n'.join(JScode) # From a list to a single string with open(osjoin(getcwd(), 'mLearning', 'JScodeAllLines.js'), 'r') as fileJS: buttonJS = fileJS.read() # Read JavaScript code from a file to toggle the visibility of all lines # with open(osjoin(getcwd(), 'mLearning', 'JScode.js'), 'w+') as codeFile: # codeFile.write(JScode) # Write whole CustomJS to a file for debugging purposes callback = CustomJS(code=JScode, args={}) # Args will be added once checkbox and button are added to lines checkbox = CheckboxGroup(labels=labels, active=activeL, # Labels to be ticked from the beginning callback=callback, name='checkbox') # JavaScript var name buttonCallback = CustomJS(code=buttonJS, args={}) # Same as for callback button = Button(label="Select/Unselect All", # Button HTML text button_type="default", callback=buttonCallback, name='button') # JavaScript var name lines['checkbox'], lines['button'] = checkbox, button # Adding widget to lines callback.args, buttonCallback.args = lines, lines # And then lines to callback layout = row(self.fig, widgetbox(children=[button, checkbox], width=200)) # One row, two columns logging.debug('Interaction implemented') return layout
def __init__(self, target): self.target = target[::-1] self.source1 = ColumnDataSource(data=dict(image=[self.target])) self.alpha = Slider(title="alpha", value=30, start=10, end=50, step=1) self.sigma = Slider(title="sigma", value=3, start=1, end=20, step=1) self.fig1 = self.define_figure('image') self.regist_image(self.fig1,self.source1) blurred = ndi.gaussian_filter(self.target, sigma=self.sigma.value) self.source2 = ColumnDataSource(data=dict(image=[blurred])) self.fig2 = self.define_figure('blurred') self.regist_image(self.fig2,self.source2) filtered = ndi.gaussian_filter(blurred, sigma=1) sharped = blurred+self.alpha.value*(blurred-filtered) sharped = sharped.astype(np.uint8) self.source3 = ColumnDataSource(data=dict(image=[sharped])) self.fig3 = self.define_figure('sharped') self.regist_image(self.fig3,self.source3) widget_list = [self.alpha, self.sigma] for widget in widget_list: widget.on_change('value', self.update_data) inputs = widgetbox(*[widget_list]) self.plot = row(inputs, gridplot( [[self.fig1, self.fig2, self.fig3]]), width=600)
def test_layout(self): p = figure(plot_width=200, plot_height=300) d = Document() d.add_root(row(p)) with pytest.warns(UserWarning) as warns: util.set_single_plot_width_height(d, 400, 500) assert len(warns) == 1 assert warns[0].message.args[0] == _SIZE_WARNING
def compose_layout(self): """Compose the layout ot the app, the main elements are the widgets to select the dataset, the metric, a div for the title, a plot and a table """ # Load metrics and datasets self.metrics = get_metrics(default='AM1') self.datasets = get_datasets(default='cfht') # Get args from the app URL or use defaults args = get_url_args(doc=curdoc, defaults={'metric': self.metrics['default']}) self.selected_dataset = args['ci_dataset'] self.selected_metric = args['metric'] # get specifications for the selected metric self.specs = get_specs(self.selected_metric) self.selected_window = args['window'] # dataset select widget dataset_select = Select(title="Data Set:", value=self.selected_dataset, options=self.datasets['datasets'], width=100) dataset_select.on_change("value", self.on_dataset_change) # thresholds are used to make plot annotations self.configure_thresholds() # metric select widget metric_select = Select(title="Metric:", value=self.selected_metric, options=self.metrics['metrics'], width=100) metric_select.on_change("value", self.on_metric_change) self.data = \ get_meas_by_dataset_and_metric(self.selected_dataset, self.selected_metric, self.selected_window) self.update_data_source() self.make_plot() self.make_table() if len(self.data['values']) < 1: self.loading.text = "No data to display" else: self.loading.text = "" self.layout = column(row(widgetbox(metric_select, width=150), widgetbox(dataset_select, width=150)), widgetbox(self.title, width=1000), self.plot, widgetbox(self.table_title, width=1000), self.table)
def main(): """Invoke when run directly as a program.""" args = parse_arguments() df = pd.read_csv(args.infile, sep='\s+', names=["amplicon", "meancov", "gene"]) df['offsetcov'] = df['meancov'] + 0.1 # shift zero values by 0.1 df = df.dropna().reset_index(drop=True) # Make a hover (show amplicon name on mouse-over) hover = HoverTool(tooltips=[("Amplicon", "@names"), ("Y value", "$y")]) tools = [PanTool(), BoxZoomTool(), WheelZoomTool(), RedoTool(), UndoTool(), ResetTool(), hover, SaveTool()] # Produce plot output_file(args.outfile) fig = figure(tools=tools, width=1200, height=600, y_axis_type='log') # Fill plot with one point for each amplicon: xvals, yvals, labels, colors = [], [], [], [] for i, (name, group) in enumerate(df.groupby('gene', sort=False)): xvals.extend(list(group.index)) yvals.extend(list(group.offsetcov)) labels.extend(list(group.amplicon)) # Elements in the same group should have the same color. Cycle between colors in COLOR_CYCLE: colors.extend([COLOR_CYCLE[i % len(COLOR_CYCLE)]] * len(list(group.index))) data = ColumnDataSource(data=dict(x=xvals, y=yvals, names=labels, colors=colors)) fig.circle(x='x', y='y', color='colors', size=10, source=data) # Make span lines on 0.05, 0.1, 0.2, 1 and 5 mutiples of mean amplicon coverage: mean_coverage = df.offsetcov.mean() span_lines = [(5.0, 'Blue'), (1.0, 'Green'), (0.2, 'Red'), (0.1, 'Purple'), (0.05, 'Magenta')] xmin, xmax = min(xvals) - 1, max(xvals) + 1 for ratio, color in span_lines: fig.line([xmin, xmax], [mean_coverage * ratio] * 2, line_color=color, line_dash='dashed', legend='{:.0f} % of mean coverage'.format(ratio * 100)) # Customize plot: ymax = 2.0 * max(df.offsetcov.max() + 1000, mean_coverage * 5) ymin = 0.2 fig.y_range = Range1d(ymin, ymax) fig.x_range = Range1d(xmin, xmax) fig.xaxis.major_tick_line_color = None # Turn off x-axis major ticks fig.xaxis.minor_tick_line_color = None # Turn off x-axis minor ticks fig.xaxis.major_label_text_font_size = '0pt' # Hack to remove tick labels fig.xaxis.axis_label = 'Amplicon' fig.yaxis.axis_label = 'Log10 (Amplicon coverage)' fig.legend.location = "bottom_right" script, div = components(layouts.row(fig)) with open(os.path.join(os.path.dirname(args.outfile), 'plot.js'), 'wt') as jfile: jfile.write('\n'.join(script.split('\n')[2:-1])) with open(args.outfile, 'wt') as ofile: env = Environment(loader=FileSystemLoader(os.path.dirname(args.template))) page_template = env.get_template(os.path.basename(args.template)) html_text = page_template.render({'bokeh_div': div}) # pylint: disable=no-member ofile.write(html_text)
def createMap(data, selectorColumn='MetricName'): # unique names ops = list(data[selectorColumn].unique()) # data msk = data[selectorColumn] == ops[0] source = ColumnDataSource(data=dict(lat=data['Latitude'][msk], lon=data['Longitude'][msk], disp=data['DisplayName'][msk], metric=data['MetricName'][msk], name=data['OrganisationName'][msk], value=data['Value'][msk])) all = {} for o in ops: msk = data[selectorColumn] == o all[o] = dict(lat=data['Latitude'][msk], lon=data['Longitude'][msk], disp=data['DisplayName'][msk], metric=data['MetricName'][msk], name=data['OrganisationName'][msk], value=data['Value'][msk]) all = ColumnDataSource(all) # create figure bk.output_file("MetricsMap.html", mode="cdn") fig = GMapPlot(plot_width=800, plot_height=700, logo=None, x_range=Range1d(), y_range=Range1d(), map_options=GMapOptions(lat=53.4808, lng=-1.2426, zoom=7), api_key='AIzaSyBQH3HGn6tpIrGxekGGRAVh-hISYAPsM78') fig.map_options.map_type = "roadmap" fig.title.text = "Performance Metrics" # hovering information hover = HoverTool(tooltips=[("Name", "@name"), ("Metrics", "@metric"), ("Value", "@value")]) # add tools fig.add_tools(PanTool(), BoxZoomTool(), WheelZoomTool(), hover) # add data circle = Circle(x="lon", y="lat", size=5, fill_color="blue", fill_alpha=0.8, line_color=None) fig.add_glyph(source, circle) # create callback callback = CustomJS(args=dict(source=source), code=""" var f = cb_obj.get('value'); var d = all.get('data')[f]; source.set('data', d); source.trigger('change'); """) callback.args["source"] = source callback.args["all"] = all # Set up widgets select = Select(title="Select", value=ops[0], options=ops, callback=callback) # show the map bk.show(row(select, fig))
def __init__(self, worker, **kwargs): with log_errors(): self.worker = worker names = ['nbytes', 'duration', 'bandwidth', 'count', 'type', 'inout-color', 'type-color', 'key', 'key-color', 'start', 'stop'] quantities = ['nbytes', 'duration', 'bandwidth', 'count', 'start', 'stop'] colors = ['inout-color', 'type-color', 'key-color'] # self.source = ColumnDataSource({name: [] for name in names}) self.source = ColumnDataSource({ 'nbytes': [1, 2], 'duration': [0.01, 0.02], 'bandwidth': [0.01, 0.02], 'count': [1, 2], 'type': ['int', 'str'], 'inout-color': ['blue', 'red'], 'type-color': ['blue', 'red'], 'key': ['add', 'inc'], 'start': [1, 2], 'stop': [1, 2] }) self.x = Select(title='X-Axis', value='nbytes', options=quantities) self.x.on_change('value', self.update_figure) self.y = Select(title='Y-Axis', value='bandwidth', options=quantities) self.y.on_change('value', self.update_figure) self.size = Select(title='Size', value='None', options=['None'] + quantities) self.size.on_change('value', self.update_figure) self.color = Select(title='Color', value='inout-color', options=['black'] + colors) self.color.on_change('value', self.update_figure) if 'sizing_mode' in kwargs: kw = {'sizing_mode': kwargs['sizing_mode']} else: kw = {} self.control = widgetbox([self.x, self.y, self.size, self.color], width=200, **kw) self.last_outgoing = 0 self.last_incoming = 0 self.kwargs = kwargs self.layout = row(self.control, self.create_figure(**self.kwargs), **kw) self.root = self.layout
def create_layout(): year_select = Select(title="Year:", value="2010", options=years) location_select = Select(title="Location:", value="World", options=locations) year_select.on_change('value', on_year_change) location_select.on_change('value', on_location_change) controls = row(children=[year_select, location_select]) layout = column(children=[controls, pyramid(), population()]) return layout
def createLayout(self): # Layout of Page self.inputTab1 = Panel(child=self.TW_rocks, title='Rock Models') self.inputTab2 = Panel(child=self.TW_fluids, title='Fluid Mixes') self.inputTab3 = Panel(child=self.TW_pres, title='Pressure Scenarios') self.inputTab4 = Panel(child=self.TW_out, title='Model Calculations') self.inputTabs = Tabs(tabs=[self.inputTab1, self.inputTab2, self.inputTab3, self.inputTab4], width=self.pagewidth, height=200) textrowob = Div(text="<h1> Overburden: </h1>") selectrowob = row(self.selectObr, self.selectObf, width=500, height=50, sizing_mode="scale_both") textrowres = Div(text="<h1> Reservoir: </h1>") selectrowres = row(self.selectResR, self.selectResf, width=500, height=50, sizing_mode="scale_both") selectrowpres = row(self.selectPres, self.slideDepth, width=500, height=50, sizing_mode="scale_both") self.layout = column(self.inputTabs, textrowob, selectrowob, textrowres, selectrowres, selectrowpres, width=self.pagewidth)
def serve(datasource): columns = list(datasource.keys()) positive_vars = [k for k in columns if np.all(datasource[k] > 0)] x = Select(title='X-Axis', value='in_degree', options=columns) y = Select(title='Y-Axis', value='pagerank', options=columns) size = Select(title='Size', value='None', options=['None'] + positive_vars) color = Select(title='Color', value='None', options=['None'] + columns) controls = layouts.widgetbox([x, y, color, size], width=200) plot = bokeh_plot(datasource) document = layouts.row(controls, plot)
def modify_document(self, doc): self.network.whois() devices_df = self.network.devices dev = ColumnDataSource(devices_df) columns = [ TableColumn(field=" Device ID", title="Dev ID"), TableColumn(field="Address", title="Address"), TableColumn(field="Manufacturer", title="Manuf"), TableColumn(field="Name", title="Name"), ] data_table = DataTable(source=dev, columns=columns) layout = row([data_table]) doc.add_root(layout) doc.title = "BACnet devices" return doc
def modify_document(self, doc): controller = self.network.notes[0] notes_df = pd.DataFrame(self.network.notes[1]).reset_index() notes_df.columns = ["index", "notes"] notes = ColumnDataSource(notes_df) self.columns = [ TableColumn(field="index", title="Timestamp"), TableColumn(field="notes", title="Notes"), ] self.data_table = DataTable(source=notes, columns=self.columns) layout = row([self.data_table]) doc.add_root(layout) doc.title = "Notes for %s" % controller # doc.add_periodic_callback(self.update_data,100) return doc
def modify_doc(doc): x = np.linspace(0, 10, 1000) y = np.log(x) * np.sin(x) source = ColumnDataSource(data=dict(x=x, y=y)) plot = figure(title="Simple plot with slider") plot.line('x', 'y', source=source) slider = Slider(start=1, end=10, value=1, step=0.1) def callback(attr, old, new): y = np.log(x) * np.sin(x*new) source.data = dict(x=x, y=y) slider.on_change('value', callback) doc.add_root(row(widgetbox(slider), plot))
def __init__(self, server, sizing_mode='stretch_both', **kwargs): self.server = server self.counter_figures = {} self.counter_sources = {} self.digest_figures = {} self.digest_sources = {} self.sizing_mode = sizing_mode if self.server.digests: for name in self.server.digests: self.add_digest_figure(name) for name in self.server.counters: self.add_counter_figure(name) figures = merge(self.digest_figures, self.counter_figures) figures = [figures[k] for k in sorted(figures)] if len(figures) <= 5: self.root = column(figures, sizing_mode=sizing_mode) else: self.root = column(*[row(*pair, sizing_mode=sizing_mode) for pair in partition_all(2, figures)], sizing_mode=sizing_mode)
title=u"选择因子", width=300, options=factors_list) factor_select.on_change('value', lambda attr, old, new: update_factor_data()) window_select = Select(value='20', title=u'选择窗口', width=300, options=ks) window_select.on_change('value', lambda attr, old, new: update_factor_data()) metrics_select = Select(value="Normal_IC", title=u"因子衡量标准", width=300, options=metrics) recalculate() update_data() update_factor_data() time_input = row(train_date_text, test_date_text) momentum_factor_input = row(five_day_return_text, hundred_twenty_day_return_text, thirty_day_average_return_text) value_factor_input = row(pe_text) defensive_factor_input = row(thirty_day_volatility) factor_input = row(factor_select, window_select, metrics_select) inputs = column(time_input, momentum_factors, momentum_factor_input, value_factors, value_factor_input, defensive_factors, defensive_factor_input, factor_input) curdoc().add_root( column(inputs, update_button, plot_normal_ic, plot_cone, plot_group, plot_value, plot_return)) curdoc().title = u"因子模型"
global layout global energy_per_capita new_df = data_changed(energy_per_capita) if new_df is not None: energy_per_capita = new_df plots_box.children[0] = create_line(energy_per_capita) plots_box.children[1] = create_bar(energy_per_capita) line = create_line(energy_per_capita) bar = create_bar(energy_per_capita) desc1 = Paragraph(text=""" This example shows live integration between bokeh server and Excel using XLWings.""") desc2 = Paragraph(text=""" *** YOU MUST HAVE EXCEL and XLWINGS INSTALLED ON YOUR MACHINE FOR IT TO WORK *** """) desc3 = Paragraph(text=""" It opens this plots window and an excel spreadsheet instance with the values being plotted. When user changes the values on the excel spreadsheet the plots will be updated accordingly. It's not required to save the spreadsheet for the plots to update. """) plots_box = row(line, bar) layout = column(desc1, desc2, desc3, plots_box) curdoc().add_root(layout) curdoc().add_periodic_callback(update, 500) session.show() # open the document in a browser session.loop_until_closed() # run forever
ss2 = s2.data_source x_axis = Span(location=0, dimension='width', line_color='black', line_alpha=0.4, line_width=2) p2.add_layout(x_axis) # endregion # region Create a third graph to show accuracy of predictions p3 = figure(plot_width=800, plot_height=800) # endregion # region global Variables c = row(p, p2, p3) step_count = [] x_point = [] y_point = [] pred_peak = [] peaktpeak = [] # endregion # region Choose stock ticker ticker = 'MSFT' # endregion @linear() def update(step): # region Get stock price
source = ColumnDataSource(data={'x': fertility, 'y': female_literacy}) # Create a new plot: plot plot = figure() # Add circles to the plot plot.circle('x', 'y', source=source) # Define a callback function: update_plot def update_plot(attr, old, new): # If the new Selection is 'female_literacy', update 'y' to female_literacy if new == 'female_literacy': source.data = {'x': fertility, 'y': female_literacy} # Else, update 'y' to population else: source.data = {'x': fertility, 'y': population} # Create a dropdown Select widget: select select = Select(title="distribution", options=['female_literacy', 'population'], value='female_literacy') # Attach the update_plot callback to the 'value' property of select select.on_change('value', update_plot) # Create layout and add to current document layout = row(select, plot) curdoc().add_root(layout)
def get_layout_data(self): H_LINE_1 = 20 H_LINE_2 = 40 H_GRAPH = 220 W_INFO_LABEL = 100 W_INFO_SIZE = 400 W_BOX1 = W_INFO_LABEL + W_INFO_SIZE H_PLOT = 380 TOOLS = 'save,hover' data_table = DataTable( source=self.DS, columns=self.table_columns, width=W_INFO_LABEL + W_INFO_SIZE, height=H_LINE_1 + H_LINE_2 + H_GRAPH, sizing_mode="stretch_width", ) self.div_status = Div(text='', width=W_INFO_SIZE, height=H_LINE_2, background='lightyellow') div_status_label = Div(text='Informatii:', width=W_INFO_LABEL) info_row = row(div_status_label, self.div_status) inputs_and_status = [] if self.debug: FN = self.log.config_data['DATA'] self.df = self.log.load_dataframe(FN, folder='output') self.log.P("Loaded data from '{}':\n{}".format(FN, self.df.iloc[:5,:10])) inputs_and_status = [ row( Div(text='Datele incarcate:', width=W_INFO_LABEL), Div(text=FN, width=W_INFO_SIZE, height=H_LINE_1, background="lightyellow") ) ] else: file_inp = FileInput(accept=".csv", width=W_INFO_SIZE,height=H_LINE_1) file_inp.on_change('value', self.upload_data) inputs_and_status = [row( Div(text='Incarcati fisierul:', width=W_INFO_LABEL), file_inp )] bar_list = self.config['BARS'] all_bar_lines = [] bars = [] width = W_BOX1 #self.W // len(bar_list) self.log.P("Plot width: {}".format(width)) for dct_count_data in self.counts_data: bar = dct_count_data['FIELD'] new_line = dct_count_data.get('NEWLINE', 0) is_progress = dct_count_data.get('PROGRESS', 0) if new_line: if len(bars) == 0: raise ValueError('Cannot change bar line with no graphs before') all_bar_lines.append(row(bars)) bars = [] if bar in bar_list: bar_name = dct_count_data['TITLE'] data_type = dct_count_data['TYPE'].upper() title = 'Analiza {} dupa '.format( "evolutiei procesului de screening" if is_progress else "distributiei totale" ) + bar_name options = dict( title=title, sizing_mode='stretch_width', tools=TOOLS, width=width, height=H_PLOT, ) if data_type in ["STR", "DATE"]: p = figure( x_range=['one','two', '...'], **options, ) p.xaxis.major_label_orientation = np.pi/3 p_labels = LabelSet( x='value', y='count', text='count', level='glyph', x_offset=-13.5, y_offset=0, source=dct_count_data['DS'], render_mode='canvas' ) p.add_layout(p_labels) else: p = figure( **options ) plot = p.vbar(x='value', top='count', source=dct_count_data['DS'], width=0.9) p.y_range.start = 0 p.y_range.range_padding = 0.2 p.xgrid.grid_line_color = None dct_count_data['FIGURE'] = p dct_count_data['PLOT'] = plot self.set_figure_range(bar) bars.append(p) all_bar_lines.append(row(bars)) bars = [] for dct_count_data in self.counts_data: bar = dct_count_data['FIELD'] is_analysis_by_target = dct_count_data.get('TARGET_ANALYSIS', 0) if not is_analysis_by_target: continue new_line = dct_count_data.get('NEWLINE', 0) is_progress = dct_count_data.get('PROGRESS', 0) if new_line: if len(bars) == 0: raise ValueError('Cannot change bar line with no graphs before') all_bar_lines.append(row(bars)) bars = [] if bar in bar_list: bar_name = dct_count_data['TITLE'] data_type = dct_count_data['TYPE'].upper() title = 'Analiza {} dupa '.format( "evolutiei procesului de screening" if is_progress else "distributiei cazurilor {}".format(self.target_positive) ) + bar_name options = dict( title=title, sizing_mode='stretch_width', tools=TOOLS, width=width, height=H_PLOT, ) if data_type in ["STR", "DATE"]: p = figure( x_range=['one','two', '...'], **options, ) p.xaxis.major_label_orientation = np.pi/3 p_labels = LabelSet( x='value', y='count', text='count', level='glyph', x_offset=-13.5, y_offset=0, source=dct_count_data['DS_TARGET'], render_mode='canvas' ) p.add_layout(p_labels) else: p = figure( **options ) plot = p.vbar(x='value', top='count', source=dct_count_data['DS_TARGET'], width=0.9) p.y_range.start = 0 p.y_range.range_padding = 0.2 p.xgrid.grid_line_color = None dct_count_data['FIGURE_TARGET'] = p dct_count_data['PLOT_TARGET'] = plot self.set_figure_range(bar) bars.append(p) all_bar_lines.append(row(bars)) p_target = figure( title=self.target_data['TITLE'], x_range=['one','two', '...'], width=W_INFO_SIZE, height=H_GRAPH, tools=TOOLS ) p_target.y_range.start = 0 p_target.y_range.range_padding = 0.3 plot_target = p_target.vbar( x='value', top='count', source=self.target_data['DS'], width=0.9) labels = LabelSet( x='value', y='count', text='count', level='glyph', x_offset=-13.5, y_offset=0, source=self.target_data['DS'], render_mode='canvas' ) p_target.add_layout(labels) self.target_data['FIGURE'] = p_target self.target_data['PLOT'] = plot_target target_row = row( Div(text='Distributia rezultatelor:',width=100), p_target ) self.set_figure_range(self.target_data['FIELD']) inputs_and_status += [info_row, target_row] ctrl_input = column(inputs_and_status) bar_plots = column(all_bar_lines) data_ctrls = row(ctrl_input, data_table, sizing_mode="stretch_width") this_layout = column(data_ctrls, bar_plots, sizing_mode="stretch_width") # app_layout = layout( # [ # [ctrl_input] # [data_table], # ], # # sizing_mode="scale_both" # ) return this_layout
y_range=[-2.5, 2.5]) plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6) freq = Slider(title="frequency", value=1.0, start=0.1, end=5.1, step=0.1) def update_data(attrname, old, new): k = freq.value # Generate the new curve x = np.linspace(0, 4 * np.pi, N) y = np.sin(k * x) source.data = dict(x=x, y=y) freq.on_change('value', update_data) # Set up layouts and add to document widget_box = widgetbox(freq) curdoc().add_root(row(widget_box, plot, width=800)) curdoc().title = "Sliders" # def change_slider_in_python(): # freq.value = np.random.uniform(0.1, 5.1) # # curdoc().add_periodic_callback(change_slider_in_python, 2000)
def update(): current = df[(df['salary'] >= slider.value[0]) & (df['salary'] <= slider.value[1])].dropna() source.data = { 'name' : current.name, '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.callback = 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 = widgetbox(slider, button) table = widgetbox(data_table) curdoc().add_root(row(controls, table)) curdoc().title = "Export CSV" update()
color="white", line_color="#3A5785") vh1 = pv.quad(left=0, bottom=vedges[:-1], top=vedges[1:], right=vzeros, alpha=0.5, **LINE_ARGS) vh2 = pv.quad(left=0, bottom=vedges[:-1], top=vedges[1:], right=vzeros, alpha=0.1, **LINE_ARGS) layout = column(row(p, pv), row(ph, Spacer(width=200, height=200))) curdoc().add_root(layout) curdoc().title = "Selection Histogram" def update(attr, old, new): inds = np.array(new['1d']['indices']) if len(inds) == 0 or len(inds) == len(x): hhist1, hhist2 = hzeros, hzeros vhist1, vhist2 = vzeros, vzeros else: neg_inds = np.ones_like(x, dtype=np.bool) neg_inds[inds] = False hhist1, _ = np.histogram(x[inds], bins=hedges) vhist1, _ = np.histogram(y[inds], bins=vedges)
def update_data(attrname, old, new): #a = aperture.value m = magnitude.value e = exptime.value luvoir.aperture = aperture.value hdi.set_pixel_sizes(luvoir) # adaptively set the pixel sizes wave = hdi.pivotwave snr = phot_etc.compute_snr(luvoir, hdi, e, m) source.data = dict(x=wave[2:-3], y=snr[2:-3], desc=hdi.bandnames[2:-3]) source2.data = dict(x=hdi.pivotwave[0:2], y=snr[0:2], desc=hdi.bandnames[0:2]) source3.data = dict(x=hdi.pivotwave[-3:], y=snr[-3:], desc=hdi.bandnames[-3:]) for w in [aperture, exptime, magnitude]: # iterate on changes to parameters w.on_change('value', update_data) # Set up layouts and add to document inputs = WidgetBox(children=[aperture, exptime, magnitude]) curdoc().add_root(row(children=[inputs, snr_plot])) script = autoload_server(model=None, app_path="/simple_etc", url="pancho.local:5006") #print(script)
def app(doc, hist_storage_, data_storage_, freq_storage_, depolarizer, names): # вспомогательные глобальные data_source = ColumnDataSource({key: [] for key in names}) fit_handler = { "fit_line": None, "input_fields": {}, "fit_indices": tuple() } utc_plus_7h = 7 * 3600 time_coef = 10**3 # Пересчёт времени в мс для формата datetime Bokeh fit_line_points_amount = 300 # Количество точек для отрисовки подгоночной кривой depol_list = [] datetime_formatter = DatetimeTickFormatter( milliseconds=['%M:%S:%3Nms'], seconds=['%H:%M:%S'], minsec=['%H:%M:%S'], minutes=['%H:%M:%S'], hourmin=['%H:%M:%S'], hours=['%H:%M:%S'], days=["%d.%m"], months=["%Y-%m-%d"], ) # Гистограмма пятна img, img_x_std, img_y_std = hist_storage_.get_hist_with_std() hist_source = ColumnDataSource(data=dict(image=[img])) width_ = config.GEM_X * 5 hist_height_ = config.GEM_Y * 5 hist_fig = figure(plot_width=width_, plot_height=hist_height_, x_range=(0, config.GEM_X), y_range=(0, config.GEM_Y)) hist_fig.image(image='image', x=0, y=0, dw=config.GEM_X, dh=config.GEM_Y, palette="Spectral11", source=hist_source) hist_label = Label( x=0, y=0, x_units='screen', y_units='screen', text=f"x_std={'%.2f' % img_x_std},y_std={'%.2f' % img_y_std}", render_mode='css', border_line_color='black', border_line_alpha=1.0, background_fill_color='white', background_fill_alpha=1.0) hist_fig.add_layout(hist_label) hist_buffer_len = config.hist_buffer_len - 1 hist_slider = RangeSlider(start=0, end=hist_buffer_len, value=(0, hist_buffer_len), step=1, title="Срез пятна (от..до) сек назад") def hist_update(): img, img_x_std, img_y_std = hist_storage_.get_hist_with_std( hist_buffer_len - hist_slider.value[1], hist_buffer_len - hist_slider.value[0]) hist_label.text = f"x_std={'%.2f' % img_x_std},y_std={'%.2f' % img_y_std}" hist_source.data = {'image': [img]} # График асимметрии asym_fig = figure( plot_width=width_, plot_height=400, tools="box_zoom, xbox_select, wheel_zoom, pan, save, reset", active_scroll="wheel_zoom", active_drag="pan", toolbar_location="below", lod_threshold=100, x_axis_location=None, x_range=DataRange1d()) asym_fig.yaxis.axis_label = "мм" asym_fig.extra_x_ranges = { "time_range": asym_fig.x_range, "depolarizer": asym_fig.x_range, "sec": asym_fig.x_range } depol_axis = LinearAxis(x_range_name="depolarizer", axis_label='Деполяризатор', major_label_overrides={}, major_label_orientation=pi / 2) asym_fig.add_layout( LinearAxis(x_range_name="time_range", axis_label='Время', formatter=datetime_formatter), 'below') # Прямая, с которой идёт отсчёт времени для подгонки zone_of_interest = Span(location=0, dimension='height', line_color='green', line_dash='dashed', line_width=3) sec_axis = LinearAxis( x_range_name='sec', axis_label='Секунды') # Секундная ось сверху (настр. диапазон) sec_axis.formatter = FuncTickFormatter( code= f"return ((tick - {zone_of_interest.location}) / {time_coef}).toFixed(1);" ) def double_tap(event): """Двойной клик для перемещения отсчёта времени для подгонки""" zone_of_interest.location = event.x sec_axis.formatter = FuncTickFormatter( code=f"return ((tick - {event.x}) / {time_coef}).toFixed(1);") asym_fig.add_layout(depol_axis, 'below') asym_fig.add_layout(sec_axis, 'above') asym_fig.add_layout(zone_of_interest) asym_fig.on_event(DoubleTap, double_tap) def draw_selected_area(attr, old, new): """Подсветка выделенной для подгонки области""" # Удаляет предыдущую выделенную область asym_fig.renderers = [ r for r in asym_fig.renderers if r.name != 'fit_zone' ] if not new.indices: fit_handler["fit_indices"] = tuple() return l_time_ = data_source.data['time'][min(new.indices)] r_time_ = data_source.data['time'][max(new.indices)] if l_time_ != r_time_: fit_handler["fit_indices"] = (l_time_, r_time_) box_select = BoxAnnotation(left=l_time_, right=r_time_, name="fit_zone", fill_alpha=0.1, fill_color='red') asym_fig.add_layout(box_select) asym_box_select_overlay = asym_fig.select_one(BoxSelectTool).overlay asym_box_select_overlay.line_color = "firebrick" data_source.on_change('selected', draw_selected_area) def create_whisker(data_name: str): """ Создает усы для data_name от time :param data_name: имя поля данных из data_storage (у данных должны быть поля '_up_error', '_down_error') :return: Bokeh Whisker """ return Whisker(source=data_source, base="time", upper=data_name + "_up_error", lower=data_name + "_down_error") def create_render(data_name: str, glyph: str, color: str): """ Рисует data_name от time :param data_name: имя поля данных из data_storage :param glyph: ['circle', 'square'] :param color: цвет :return: Bokeh fig """ if glyph == 'circle': func = asym_fig.circle elif glyph == 'square': func = asym_fig.square else: raise ValueError('Неверное значение glyph') return func('time', data_name, source=data_source, name=data_name, color=color, nonselection_alpha=1, nonselection_color=color) # Список линий на графике асимметрии: data_name, name, glyph, color asym_renders_name = [('y_one_asym', 'ΔY ONE', 'circle', 'black'), ('y_cog_asym', 'ΔY COG', 'circle', 'green'), ('x_one_asym', 'ΔX ONE', 'square', 'black'), ('x_cog_asym', 'ΔX COG', 'square', 'green')] pretty_names = dict([(data_name, name) for data_name, name, *_ in asym_renders_name]) asym_renders = [ create_render(data_name, glyph, color) for data_name, _, glyph, color in asym_renders_name ] asym_error_renders = [ create_whisker(data_name) for data_name, *_ in asym_renders_name ] for render, render_error in zip(asym_renders, asym_error_renders): asym_fig.add_layout(render_error) render.js_on_change( 'visible', CustomJS(args=dict(x=render_error), code="x.visible = cb_obj.visible")) asym_fig.add_layout( Legend(items=[(pretty_names[r.name], [r]) for r in asym_renders], click_policy="hide", location="top_left", background_fill_alpha=0.2, orientation="horizontal")) # Вывод информации о точке при наведении мыши asym_fig.add_tools( HoverTool( renderers=asym_renders, formatters={"time": "datetime"}, mode='vline', tooltips=[ ("Время", "@time{%F %T}"), *[(pretty_names[r.name], f"@{r.name}{'{0.000}'} ± @{r.name + '_error'}{'{0.000}'}") for r in asym_renders], ("Деполяризатор", f"@depol_energy{'{0.000}'}") ])) # Окно ввода периода усреднения period_input = TextInput(value='300', title="Время усреднения (с):") # Глобальный список параметров, для сохранения результатов запросов к data_storage params = {'last_time': 0, 'period': int(period_input.value)} def update_data(): """ Обновляет данные для пользовательского интерфейса, собирая их у data_storage """ if params['period'] != int(period_input.value): data_source.data = {name: [] for name in names} params['period'] = int(period_input.value) params['last_time'] = 0 depol_axis.ticker = [] depol_axis.major_label_overrides.clear() depol_list.clear() points, params['last_time'] = data_storage_.get_mean_from( params['last_time'], params['period']) if not points['time']: return points['time'] = [(i + utc_plus_7h) * time_coef for i in points['time'] ] # Учёт сдвижки UTC+7 для отрисовки for time, energy in zip(points['time'], points['depol_energy']): if energy == 0: continue depol_axis.major_label_overrides[time] = str(energy) depol_list.append(time) depol_axis.ticker = depol_list # TODO: оптимизировать data_source.stream({key: np.array(val) for key, val in points.items()}, rollover=250) def period_correction_func(attr, old, new): """Проверка введенного значения на целое число больше нуля""" if not new.isdigit() or int(new) <= 0: period_input.value = old period_input.on_change('value', period_correction_func) # Создание панели графиков (вкладок) def create_fig(data_names: list, colors: list, y_axis_name: str, ers: str = None): """Создаёт график data_names : time. Если в data_names несколько имён, то они будут на одном графике. Возвращает fig. :param data_names: список с именами полей данных из data_storage :param colors: список цветов, соотв. элементам из fig_names :param y_axis_name: имя оси Y :param ers: 'err', 'pretty' --- вид усов (у данных должны быть поля '_up_error', '_down_error'), 'err' --- усы обыкновенные 'pretty' --- усы без шляпки и цветом совпадающим с цветом точки :return fig --- Bokeh figure """ if len(data_names) != len(colors): raise IndexError('Кол-во цветов и графиков не совпадает') fig = figure(plot_width=width_, plot_height=300, tools="box_zoom, wheel_zoom, pan, save, reset", active_scroll="wheel_zoom", lod_threshold=100, x_axis_type="datetime") for fig_name, color in zip(data_names, colors): if ers == 'err': fig.add_layout( Whisker(source=data_source, base="time", upper=fig_name + '_up_error', lower=fig_name + '_down_error')) elif ers == 'pretty': fig.add_layout( Whisker(source=data_source, base="time", upper=fig_name + '_up_error', lower=fig_name + '_down_error', line_color=color, lower_head=None, upper_head=None)) fig.circle('time', fig_name, source=data_source, size=5, color=color, nonselection_alpha=1, nonselection_color=color) fig.yaxis.axis_label = y_axis_name fig.xaxis.axis_label = 'Время' fig.xaxis.formatter = datetime_formatter fig.x_range = asym_fig.x_range return fig figs = [(create_fig(['y_one_l'], ['black'], 'Y [мм]', 'err'), 'Y ONE L'), (create_fig(['y_one_r'], ['black'], 'Y [мм]', 'err'), 'Y ONE R'), (create_fig(['y_cog_l'], ['black'], 'Y [мм]', 'err'), 'Y COG L'), (create_fig(['y_cog_r'], ['black'], 'Y [мм]', 'err'), 'Y COG R'), (create_fig(['rate' + i for i in ['_l', '_r']], ['red', 'blue'], 'Усл. ед.', 'pretty'), 'Rate'), (create_fig(['corrected_rate' + i for i in ['_l', '_r']], ['red', 'blue'], 'Усл. ед.', 'pretty'), 'Corr. rate'), (create_fig(['delta_rate'], ['black'], 'Корр. лев. - корр. пр.', 'err'), 'Delta corr. rate'), (create_fig(['charge'], ['blue'], 'Ед.'), 'Charge')] tab_handler = Tabs( tabs=[Panel(child=fig, title=fig_name) for fig, fig_name in figs], width=width_) # Окно статуса деполяризатора depol_status_window = Div(text="Инициализация...", width=500, height=500) depol_start_stop_buttons = RadioButtonGroup( labels=["Старт", "Стоп"], active=(0 if depolarizer.is_scan else 1)) fake_depol_button = Button(label="Деполяризовать", width=200) fake_depol_button.on_click(GEM.depolarize) depol_input_harmonic_number = TextInput(value=str( '%.1f' % depolarizer.harmonic_number), title=f"Номер гармоники", width=150) depol_input_attenuation = TextInput(value=str('%.1f' % depolarizer.attenuation), title=f"Аттенюатор (дБ)", width=150) depol_input_speed = TextInput( value=str(depolarizer.frequency_to_energy(depolarizer.speed, n=0)), title=f"Скорость ({'%.1f' % depolarizer.speed} Гц):", width=150) depol_input_step = TextInput( value=str(depolarizer.frequency_to_energy(depolarizer.step, n=0)), title=f"Шаг ({'%.1f' % depolarizer.step} Гц):", width=150) depol_input_initial = TextInput( value=str(depolarizer.frequency_to_energy(depolarizer.initial)), title=f"Начало ({'%.1f' % depolarizer.initial} Гц):", width=150) depol_input_final = TextInput( value=str(depolarizer.frequency_to_energy(depolarizer.final)), title=f"Конец ({'%.1f' % depolarizer.final} Гц):", width=150) depol_dict = { "speed": (depol_input_speed, depolarizer.set_speed), "step": (depol_input_step, depolarizer.set_step), "initial": (depol_input_initial, depolarizer.set_initial), "final": (depol_input_final, depolarizer.set_final), "harmonic_number": (depol_input_harmonic_number, depolarizer.set_harmonic_number), "attenuation": (depol_input_attenuation, depolarizer.set_attenuation) } def change_value_generator(value_name): """Возвращает callback функцию для параметра value_name деполяризатора""" def change_value(attr, old, new): if float(old) == float(new): return depol_input, depol_set = depol_dict[value_name] depol_current = depolarizer.get_by_name(value_name) try: if value_name in ['harmonic_number', 'attenuation']: new_val = float(new) elif value_name in ['speed', 'step']: new_val = depolarizer.energy_to_frequency(float(new), n=0) else: new_val = depolarizer.energy_to_frequency(float(new)) if depol_current == new_val: return depol_set(new_val) if value_name not in ['harmonic_number', 'attenuation']: name = depol_input.title.split(' ')[0] depol_input.title = name + f" ({'%.1f' % new_val} Гц):" except ValueError as e: if value_name in ['harmonic_number', 'attenuation']: depol_input.value = str(depol_current) elif value_name in ['speed', 'step']: depol_input.value = str( depolarizer.frequency_to_energy(depol_current, n=0)) else: depol_input.value = str( depolarizer.frequency_to_energy(depol_current)) print(e) return change_value depol_input_harmonic_number.on_change( 'value', change_value_generator('harmonic_number')) depol_input_attenuation.on_change('value', change_value_generator("attenuation")) depol_input_speed.on_change('value', change_value_generator("speed")) depol_input_step.on_change('value', change_value_generator("step")) depol_input_initial.on_change('value', change_value_generator("initial")) depol_input_final.on_change('value', change_value_generator("final")) def update_depol_status( ): # TODO: самому пересчитывать начало и конец сканирования по частотам """Обновляет статус деполяризатора, если какое-то значение поменялось другим пользователем""" depol_start_stop_buttons.active = 0 if depolarizer.is_scan else 1 depol_status_window.text = f""" <p>Сканирование: <font color={'"green">включено' if depolarizer.is_scan else '"red">выключено'}</font></p> <p/>Частота {"%.1f" % depolarizer.current_frequency} (Гц)</p> <p/>Энергия {"%.3f" % depolarizer.current_energy} МэВ</p>""" for value_name in ['speed', 'step']: depol_input, _ = depol_dict[value_name] depol_value = depolarizer.frequency_to_energy( depolarizer.get_by_name(value_name), n=0) if float(depol_input.value) != depol_value: depol_input.value = str(depol_value) for value_name in ['initial', 'final']: depol_input, _ = depol_dict[value_name] freq = depolarizer.get_by_name(value_name) energy = depolarizer.frequency_to_energy(freq) if float(depol_input.value) != energy: depol_input.value = str(energy) else: name = depol_input.title.split(' ')[0] depol_input.title = name + f" ({'%.1f' % freq} Гц):" for value_name in ['attenuation', 'harmonic_number']: depol_input, _ = depol_dict[value_name] depol_value = depolarizer.get_by_name(value_name) if float(depol_input.value) != depol_value: depol_input.value = str(int(depol_value)) depol_start_stop_buttons.on_change( "active", lambda attr, old, new: (depolarizer.start_scan() if new == 0 else depolarizer.stop_scan())) # Подгонка fit_line_selection_widget = Select(title="Fitting line:", width=200, value=asym_renders[0].name, options=[(render.name, pretty_names[render.name]) for render in asym_renders]) options = [name for name in fit.function_handler.keys()] if not options: raise IndexError("Пустой function_handler в fit.py") fit_function_selection_widget = Select(title="Fitting function:", value=options[0], options=options, width=200) fit_button = Button(label="FIT", width=200) def make_parameters_table(): """Создание поля ввода данных для подгонки: начальное значение, fix и т.д.""" name = fit_function_selection_widget.value t_width = 10 t_height = 12 rows = [ row(Paragraph(text="name", width=t_width, height=t_height), Paragraph(text="Fix", width=t_width, height=t_height), Paragraph(text="Init value", width=t_width, height=t_height), Paragraph(text="step (error)", width=t_width, height=t_height), Paragraph(text="limits", width=t_width, height=t_height), Paragraph(text="lower_limit", width=t_width, height=t_height), Paragraph(text="upper_limit", width=t_width, height=t_height)) ] fit_handler["input_fields"] = {} for param, value in fit.get_function_params(name): fit_handler["input_fields"][param] = {} fit_handler["input_fields"][param]["fix"] = CheckboxGroup( labels=[""], width=t_width, height=t_height) fit_handler["input_fields"][param]["Init value"] = TextInput( width=t_width, height=t_height, value=str(value)) fit_handler["input_fields"][param]["step (error)"] = TextInput( width=t_width, height=t_height, value='1') fit_handler["input_fields"][param]["limits"] = CheckboxGroup( labels=[""], width=t_width, height=t_height) fit_handler["input_fields"][param]["lower_limit"] = TextInput( width=t_width, height=t_height) fit_handler["input_fields"][param]["upper_limit"] = TextInput( width=t_width, height=t_height) rows.append( row(Paragraph(text=param, width=t_width, height=t_height), fit_handler["input_fields"][param]["fix"], fit_handler["input_fields"][param]["Init value"], fit_handler["input_fields"][param]["step (error)"], fit_handler["input_fields"][param]["limits"], fit_handler["input_fields"][param]["lower_limit"], fit_handler["input_fields"][param]["upper_limit"])) return column(rows) def clear_fit(): """Удаление подогнанной кривой""" if fit_handler["fit_line"] in asym_fig.renderers: asym_fig.renderers.remove(fit_handler["fit_line"]) energy_window = Div(text="Частота: , энергия: ") clear_fit_button = Button(label="Clear", width=200) clear_fit_button.on_click(clear_fit) def fit_callback(): if not fit_handler["fit_indices"]: return name = fit_function_selection_widget.value line_name = fit_line_selection_widget.value left_time_, right_time_ = fit_handler["fit_indices"] left_ind_ = bisect.bisect_left(data_source.data['time'], left_time_) right_ind_ = bisect.bisect_right(data_source.data['time'], right_time_, lo=left_ind_) if left_ind_ == right_ind_: return clear_fit() x_axis = data_source.data['time'][left_ind_:right_ind_] y_axis = data_source.data[line_name][left_ind_:right_ind_] y_errors = data_source.data[line_name + '_up_error'][left_ind_:right_ind_] - y_axis init_vals = { name: float(val["Init value"].value) for name, val in fit_handler["input_fields"].items() } steps = { "error_" + name: float(val["step (error)"].value) for name, val in fit_handler["input_fields"].items() } fix_vals = { "fix_" + name: True for name, val in fit_handler["input_fields"].items() if val["fix"].active } limit_vals = { "limit_" + name: (float(val["lower_limit"].value), float(val["upper_limit"].value)) for name, val in fit_handler["input_fields"].items() if val["limits"].active } kwargs = {} kwargs.update(init_vals) kwargs.update(steps) kwargs.update(fix_vals) kwargs.update(limit_vals) # Предобработка времени, перевод в секунды, вычитание сдвига (для лучшей подгонки) left_ = zone_of_interest.location x_time = x_axis - left_ # Привёл время в интервал от 0 x_time /= time_coef # Перевёл в секунды # Создание точек, которые передадутся в подогнанную функцию с параметрами, # и точек, которые соответсвуют реальным временам на графике (т.е. без смещения к 0) fit_line_real_x_axis = np.linspace(left_time_, right_time_, fit_line_points_amount) fit_line_x_axis = fit_line_real_x_axis - left_ fit_line_x_axis /= time_coef m = fit.create_fit_func(name, x_time, y_axis, y_errors, kwargs) fit.fit(m) params_ = m.get_param_states() for param in params_: fit_handler["input_fields"][ param['name']]["Init value"].value = "%.3f" % param['value'] fit_handler["input_fields"][ param['name']]["step (error)"].value = "%.3f" % param['error'] if param['name'] == "depol_time": freq = freq_storage_.find_closest_freq(param['value'] + left_ / time_coef - utc_plus_7h) freq_error = abs(depolarizer.speed * param['error']) energy = depolarizer.frequency_to_energy( freq) if freq != 0 else 0 energy_error = depolarizer.frequency_to_energy( freq_error, depolarizer._F0, 0) energy_window.text = "<p>Частота: %8.1f +- %.1f Hz,</p> <p>Энергия: %7.3f +- %.1f МэВ</p>" % ( freq, freq_error, energy, energy_error) fit_handler["fit_line"] = asym_fig.line( fit_line_real_x_axis, fit.get_line(name, fit_line_x_axis, [x['value'] for x in params_]), color="red", line_width=2) fit_button.on_click(fit_callback) # Инициализация bokeh app, расположение виджетов column_1 = column(gridplot([tab_handler], [asym_fig], merge_tools=False), period_input, width=width_ + 50) widgets_ = WidgetBox(depol_start_stop_buttons, depol_input_harmonic_number, depol_input_attenuation, depol_input_speed, depol_input_step, depol_input_initial, depol_input_final, depol_status_window) row_21 = column(hist_fig, hist_slider) column_21 = column(widgets_) if config.GEM_idle: column_22 = column(fit_button, clear_fit_button, fake_depol_button, fit_line_selection_widget, fit_function_selection_widget, energy_window, make_parameters_table()) make_parameters_table_id = 6 else: column_22 = column(fit_button, clear_fit_button, fit_line_selection_widget, fit_function_selection_widget, energy_window, make_parameters_table()) make_parameters_table_id = 5 def rebuild_table(attr, old, new): column_22.children[make_parameters_table_id] = make_parameters_table() fit_function_selection_widget.on_change("value", rebuild_table) row_22 = row(column_21, column_22) column_2 = column(row_21, row_22, width=width_ + 50) layout_ = layout([[column_1, column_2]]) # Настройка документа Bokeh update_data() doc.add_periodic_callback(hist_update, 1000) # TODO запихнуть в один callback doc.add_periodic_callback(update_data, 1000) # TODO: подобрать периоды doc.add_periodic_callback(update_depol_status, 1000) doc.title = "Laser polarimeter" doc.add_root(layout_)
tools='box_select,pan,wheel_zoom,box_zoom,reset', x_range=[ min(country_cases['confirmed']), max(country_cases['confirmed']) + 35000 ], y_range=[ min(country_cases['recovered']), max(country_cases['recovered']) + 2000 ]) hover = HoverTool(tooltips=[('Country', '@country'), ('Number of Confirmed Cases', '@x'), ('Number of Recoveries', '@y')]) p1.add_tools(hover) p1.circle(x='x', y='y', size='sizes', source=source, color={ 'field': 'y', 'transform': color_mapper }) layout = row(p, p1) output_file('cor.html') show(layout)
def spectroscopy_plot(source_id): """TODO normalization? should this be handled at data ingestion or plot-time?""" source = Source.query.get(source_id) spectra = Source.query.get(source_id).spectra if len(spectra) == 0: return None, None, None color_map = dict(zip([s.id for s in spectra], viridis(len(spectra)))) data = pd.concat([ pd.DataFrame({ 'wavelength': s.wavelengths, 'flux': s.fluxes, 'id': s.id, 'instrument': s.instrument.telescope.nickname }) for i, s in enumerate(spectra) ]) split = data.groupby('id') hover = HoverTool(tooltips=[('wavelength', '$x'), ('flux', '$y'), ('instrument', '@instrument')]) plot = figure(plot_width=600, plot_height=300, sizing_mode='scale_both', tools='box_zoom,wheel_zoom,pan,reset', active_drag='box_zoom') plot.add_tools(hover) model_dict = {} for i, (key, df) in enumerate(split): model_dict['s' + str(i)] = plot.line(x='wavelength', y='flux', color=color_map[key], source=ColumnDataSource(df)) plot.xaxis.axis_label = 'Wavelength (Å)' plot.yaxis.axis_label = 'Flux' plot.toolbar.logo = None # TODO how to choose a good default? plot.y_range = Range1d(0, 1.03 * data.flux.max()) toggle = CheckboxWithLegendGroup( labels=[s.instrument.telescope.nickname for s in spectra], active=list(range(len(spectra))), width=100, colors=[color_map[k] for k, df in split]) toggle.callback = CustomJS(args={ 'toggle': toggle, **model_dict }, code=""" for (let i = 0; i < toggle.labels.length; i++) { eval("s" + i).visible = (toggle.active.includes(i)) } """) elements = CheckboxWithLegendGroup( labels=list(SPEC_LINES.keys()), active=[], width=80, colors=[c for w, c in SPEC_LINES.values()]) z = TextInput(value=str(source.red_shift), title="z:") v_exp = TextInput(value='0', title="v_exp:") for i, (wavelengths, color) in enumerate(SPEC_LINES.values()): el_data = pd.DataFrame({'wavelength': wavelengths}) el_data['x'] = el_data['wavelength'] * (1 + source.red_shift) model_dict[f'el{i}'] = plot.segment( x0='x', x1='x', # TODO change limits y0=0, y1=1e-13, color=color, source=ColumnDataSource(el_data)) model_dict[f'el{i}'].visible = False # TODO callback policy: don't require submit for text changes? elements.callback = CustomJS(args={ 'elements': elements, 'z': z, 'v_exp': v_exp, **model_dict }, code=""" let c = 299792.458; // speed of light in km / s for (let i = 0; i < elements.labels.length; i++) { let el = eval("el" + i); el.visible = (elements.active.includes(i)) el.data_source.data.x = el.data_source.data.wavelength.map( x_i => (x_i * (1 + parseFloat(z.value)) / (1 + parseFloat(v_exp.value) / c)) ); el.data_source.change.emit(); } """) z.callback = elements.callback v_exp.callback = elements.callback layout = row(plot, toggle, elements, column(z, v_exp)) return _plot_to_json(layout)
def photometry_plot(source_id): """Create scatter plot of photometry for source. Parameters ---------- source_id : int ID of source to be plotted. Returns ------- (str, str) Returns (docs_json, render_items) json for the desired plot. """ color_map = {'ipr': 'yellow', 'rpr': 'red', 'g': 'green'} data = pd.read_sql( DBSession().query( Photometry, Telescope.nickname.label('telescope')).join(Instrument).join( Telescope).filter(Photometry.source_id == source_id).statement, DBSession().bind) if data.empty: return None, None, None for col in ['mag', 'e_mag', 'lim_mag']: # TODO remove magic number; where can this logic live? data.loc[np.abs(data[col]) > 90, col] = np.nan data['color'] = [color_map.get(f, 'black') for f in data['filter']] data['label'] = [ f'{t} {f}-band' for t, f in zip(data['telescope'], data['filter']) ] data['observed'] = ~np.isnan(data.mag) split = data.groupby(['label', 'observed']) plot = figure(plot_width=600, plot_height=300, active_drag='box_zoom', tools='box_zoom,wheel_zoom,pan,reset', y_range=(np.nanmax(data['mag']) + 0.1, np.nanmin(data['mag']) - 0.1)) model_dict = {} for i, ((label, is_obs), df) in enumerate(split): key = ("" if is_obs else "un") + 'obs' + str(i // 2) model_dict[key] = plot.scatter( x='observed_at', y='mag' if is_obs else 'lim_mag', color='color', marker='circle' if is_obs else 'inverted_triangle', fill_color='color' if is_obs else 'white', source=ColumnDataSource(df)) plot.xaxis.axis_label = 'Observation Date' plot.xaxis.formatter = DatetimeTickFormatter(hours=['%D'], days=['%D'], months=['%D'], years=['%D']) plot.toolbar.logo = None hover = HoverTool(tooltips=[('observed_at', '@observed_at{%D}'), ('mag', '@mag'), ('lim_mag', '@lim_mag'), ('filter', '@filter')], formatters={'observed_at': 'datetime'}) plot.add_tools(hover) toggle = CheckboxWithLegendGroup(labels=list(data.label.unique()), active=list( range(len(data.label.unique()))), colors=list(data.color.unique())) # TODO replace `eval` with Namespaces # https://github.com/bokeh/bokeh/pull/6340 toggle.callback = CustomJS(args={ 'toggle': toggle, **model_dict }, code=""" for (let i = 0; i < toggle.labels.length; i++) { eval("obs" + i).visible = (toggle.active.includes(i)) eval("unobs" + i).visible = (toggle.active.includes(i)); } """) layout = row(plot, toggle) return _plot_to_json(layout)
def overview_tab(df, x_name, date_name, measure): def make_dataset(category_list, range_start, range_end): reduced = pd.DataFrame() for cat in category_list: subset = df[df[x_name] == cat] if (type(range_start) == int) or (type(range_start) == float): range_start = datetime.fromtimestamp(range_start / 1000) range_end = datetime.fromtimestamp(range_end / 1000) print(range_start, range_end) subset = subset[(subset[date_name] > range_start) & (subset[date_name] < range_end)] reduced = reduced.append(subset) temp = pd.DataFrame(zip(viridis(len(category_list)), category_list), columns=['color', x_name]) reduced = pd.merge(reduced, temp, on = x_name) reduced = reduced.sort_values(by=date_name, ascending=True) return ColumnDataSource(reduced) def style(p): # Title p.title.align = 'center' p.title.text_font_size = '20pt' p.title.text_font = 'serif' # Axis titles p.xaxis.axis_label_text_font_size = '14pt' p.xaxis.axis_label_text_font_style = 'bold' p.yaxis.axis_label_text_font_size = '14pt' p.yaxis.axis_label_text_font_style = 'bold' # Tick labels p.xaxis.major_label_text_font_size = '12pt' p.yaxis.major_label_text_font_size = '12pt' p.xaxis.formatter = DatetimeTickFormatter( hours=["%d %B %Y"], days=["%d %B %Y"], months=["%d %B %Y"], years=["%d %B %Y"] ) # Names in Angles p.xaxis.major_label_orientation = np.pi / 4 return p def make_plot(src): # Create the blank plot p = figure(plot_width=1200, plot_height=700, title=measure + ' vs ' + date_name, x_axis_label=date_name, y_axis_label=measure) # p.line(src.data[date_name], src.data[measure], line_width=0.9, line_color='grey') # p.circle(src.data[date_name], src.data[measure], fill_color='grey', line_color= 'black') p.line(x = date_name, y = measure, source = src, line_width=0.9, line_color='grey') p.circle(x = date_name, y = measure, source = src, size = 10, fill_color='color', fill_alpha=0.75, line_color='black', hover_fill_alpha=1.0, hover_fill_color='green') # Hover tool referring to our own data field using @ and # a position on the graph using $ h = HoverTool(tooltips=[(x_name, '@' + x_name), (measure, '@' + measure)]) # Add the hover tool to the graph p.add_tools(h) # Style the plot p = style(p) return p def update(attr, old, new): categories_to_plot = [category_selection.labels[i] for i in category_selection.active] new_src = make_dataset(categories_to_plot, range_select.value[0], range_select.value[1]) src.data.update(new_src.data) df = df.sort_values(by = date_name, ascending= True) available_categories = list(set(df[x_name])) category_selection = CheckboxGroup(labels=available_categories, active=[i for i in range(len(available_categories))]) category_selection.on_change('active', update) # Initial categories and data source initial_categories = [category_selection.labels[i] for i in category_selection.active] # categories and colors range_select = DateRangeSlider(start=df[date_name].iloc[0], end=df[date_name].iloc[-1], value=(df[date_name].iloc[0], df[date_name].iloc[-1]), step=1, title='Time Window') range_select.on_change('value', update) # Initial categories and data source src = make_dataset(initial_categories, range_start = range_select.value[0], range_end = range_select.value[1]) p = make_plot(src) # Put controls in a single element controls = WidgetBox(category_selection, range_select) # Create a row layout layout = row(controls, p) # Make a tab with the layout tab = Panel(child = layout, title = 'Overview') return tab
yr = slider.value # x=x_select.value # y=y_select.value #label axes of plot # plot.xaxis.axis_label = x # plot.yaxis.axis_label = y #set new final_df new_data = { 'x': final_df.fertility[final_df['Year'] == yr], 'y': final_df.life[final_df['Year'] == yr], 'Country': final_df.Country[final_df['Year'] == yr], # 'pop' : final_df.population[final_df['Year']==yr], 'region': final_df.region[final_df['Year'] == yr], } #assign new_final_df to source.final_df source.data = new_data # Add title to figure: plot.title.text plot.title.text = 'Gapminder final_df for %d' % yr # Attach the callback to the 'value' property of slider slider.on_change('value', update_plot) # Make a row layout of widgetbox(slider) and plot and add it to the current document layout = row(widgetbox(slider), plot) curdoc().add_root(layout) #curdoc().title = 'GapMinder' # #saved as gapminder_slider.py
kdims = [x.value, y.value] opts, style = {}, {} opts['color_index'] = color.value if color.value != 'None' else None if size.value != 'None': opts['size_index'] = size.value opts['scaling_factor'] = (1./df[size.value].max())*200 points = hv.Points(df, kdims=kdims, label=label).opts(plot=opts, style=style) return renderer.get_plot(points).state def update(attr, old, new): layout.children[1] = create_figure() x = Select(title='X-Axis', value='mpg', options=quantileable) x.on_change('value', update) y = Select(title='Y-Axis', value='hp', options=quantileable) y.on_change('value', update) size = Select(title='Size', value='None', options=['None'] + quantileable) size.on_change('value', update) color = Select(title='Color', value='None', options=['None'] + quantileable) color.on_change('value', update) controls = widgetbox([x, y, color, size], width=200) layout = row(controls, create_figure()) curdoc().add_root(layout) curdoc().title = "Crossfilter"
def density_tab(flights): # Dataset for density plot based on overall rating, range of overall rating, # and bandwidth for density estimation def make_dataset(carrier_list, range_start, range_end, bandwidth): xs = [] ys = [] colors = [] labels = [] for i, carrier in enumerate(carrier_list): subset = flights[flights['Country'] == carrier] subset = subset[subset['Overall Rating'].between( range_start, range_end)] kde = gaussian_kde(subset['Overall Rating'], bw_method=bandwidth) # Evenly space x values x = np.linspace(range_start, range_end, 100) # Evaluate pdf at every value of x y = kde.pdf(x) # Append the values to plot xs.append(list(x)) ys.append(list(y)) # Append the colors and label colors.append(airline_colors[i]) labels.append(carrier) new_src = ColumnDataSource(data={ 'x': xs, 'y': ys, 'color': colors, 'label': labels }) return new_src def make_plot(src): p = figure(plot_width=700, plot_height=700, title='Density Plot of Overll Rating by Country', x_axis_label='Overall Rating', y_axis_label='Density') p.multi_line('x', 'y', color='color', legend='label', line_width=3, source=src) # Hover tool with next line policy hover = HoverTool(tooltips=[('Country', '@label'), ('points', '$x'), ('Density', '$y')], line_policy='next') # Add the hover tool and styling p.add_tools(hover) p = style(p) return p def update(attr, old, new): # List of carriers to plot carriers_to_plot = [ carrier_selection.labels[i] for i in carrier_selection.active ] # If no bandwidth is selected, use the default value if bandwidth_choose.active == []: bandwidth = None # If the bandwidth select is activated, use the specified bandwith else: bandwidth = bandwidth_select.value new_src = make_dataset(carriers_to_plot, range_start=range_select.value[0], range_end=range_select.value[1], bandwidth=bandwidth) src.data.update(new_src.data) def style(p): # Title p.title.align = 'center' p.title.text_font_size = '20pt' p.title.text_font = 'serif' # Axis titles p.xaxis.axis_label_text_font_size = '14pt' p.xaxis.axis_label_text_font_style = 'bold' p.yaxis.axis_label_text_font_size = '14pt' p.yaxis.axis_label_text_font_style = 'bold' # Tick labels p.xaxis.major_label_text_font_size = '12pt' p.yaxis.major_label_text_font_size = '12pt' return p # Carriers and colors available_carriers = list(set(flights['Country'])) available_carriers.sort() airline_colors = Category20_16 airline_colors.sort() # Carriers to plot carrier_selection = CheckboxGroup(labels=available_carriers, active=[0, 1]) carrier_selection.on_change('active', update) range_select = RangeSlider(start=0, end=180, value=(0, 120), step=5, title='points') range_select.on_change('value', update) # Initial carriers and data source initial_carriers = [ carrier_selection.labels[i] for i in carrier_selection.active ] # Bandwidth of kernel bandwidth_select = Slider(start=0.1, end=5, step=0.1, value=0.5, title='Bandwidth for Density Plot') bandwidth_select.on_change('value', update) # Whether to set the bandwidth or have it done automatically bandwidth_choose = CheckboxButtonGroup( labels=['Choose Bandwidth (Else Auto)'], active=[]) bandwidth_choose.on_change('active', update) # Make the density data source src = make_dataset(initial_carriers, range_start=range_select.value[0], range_end=range_select.value[1], bandwidth=bandwidth_select.value) # Make the density plot p = make_plot(src) # Add style to the plot p = style(p) # Put controls in a single element controls = WidgetBox(range_select, bandwidth_select, bandwidth_choose, carrier_selection) # Create a row layout layout = row(controls, p) # Make a tab with the layout tab = Panel(child=layout, title='Density Plot') return tab
N = 10 x = np.linspace(0, 4 * np.pi, N) y = np.sin(x) options = dict(tools="", toolbar_location=None, plot_height=300, plot_width=300) p1 = figure(title="Line (300 x 100)", **options) p1.plot_height = 100 p1.line(x, y) p2 = figure(title="Annular wedge (100 x 300)", title_location='right', **options) p2.plot_width = 100 p2.annular_wedge(x, y, 10, 20, 0.6, 4.1, inner_radius_units="screen", outer_radius_units="screen") p3 = figure(title="Bezier (300 x 300)", **options) p3.bezier(x, y, x + 0.4, y, x + 0.1, y + 0.2, x - 0.1, y - 0.2) p4 = figure(title="Quad (300 x 300)", **options) p4.quad(x, x - 0.2, y, y - 0.2) spacer_1 = Spacer(width=100, height=100) spacer_2 = Spacer(width=300, height=100) paragraph = Paragraph(text="We build up a grid plot manually. Try changing the mode yourself.") MODE = 'fixed' widgets = widgetbox([paragraph], sizing_mode=MODE) row_1 = row([spacer_1, p1, spacer_2], sizing_mode=MODE) row_2 = row([p2, p3, p4], sizing_mode=MODE) layout = column([widgets, row_1, row_2], sizing_mode=MODE) show(layout)
) import distributed.bokeh SIZING_MODE = 'scale_width' WIDTH = 600 messages = distributed.bokeh.messages # global message store doc = curdoc() task_stream = TaskStream(1000, sizing_mode=SIZING_MODE, width=WIDTH, height=300, clear_interval=10000) doc.add_periodic_callback(lambda: task_stream.update(messages), messages['task-events']['interval']) task_progress = TaskProgress(sizing_mode=SIZING_MODE, width=WIDTH, height=160) doc.add_periodic_callback(lambda: task_progress.update(messages), 50) memory_usage = MemoryUsage(sizing_mode=SIZING_MODE, width=WIDTH, height=60) doc.add_periodic_callback(lambda: memory_usage.update(messages), 50) resource_profiles = ResourceProfiles(sizing_mode=SIZING_MODE, width=WIDTH, height=80) doc.add_periodic_callback(lambda: resource_profiles.update(messages), messages['task-events']['interval']) layout = column( row(resource_profiles.root, sizing_mode=SIZING_MODE), row(memory_usage.root, sizing_mode=SIZING_MODE), row(task_stream.root, sizing_mode=SIZING_MODE), row(task_progress.root, sizing_mode=SIZING_MODE), sizing_mode=SIZING_MODE ) doc.add_root(layout)
output_file("callback.html") x = [random() for x in range(500)] y = [random() for y in range(500)] s1 = ColumnDataSource(data=dict(x=x, y=y)) p1 = figure(plot_width=400, plot_height=400, tools="lasso_select", title="Select Here") p1.circle('x', 'y', source=s1, alpha=0.6) s2 = ColumnDataSource(data=dict(x=[], y=[])) p2 = figure(plot_width=400, plot_height=400, x_range=(0, 1), y_range=(0, 1), tools="", title="Watch Here") p2.circle('x', 'y', source=s2, alpha=0.6) s1.callback = CustomJS(args=dict(s2=s2), code=""" var inds = cb_obj.selected.indices; var d1 = cb_obj.data; var d2 = s2.data; d2['x'] = [] d2['y'] = [] for (i = 0; i < inds.length; i++) { d2['x'].push(d1['x'][inds[i]]) d2['y'].push(d1['y'][inds[i]]) } s2.change.emit(); """) layout = row(p1, p2) show(layout)
def activity_details(local_time, activity_group_name): f''' # Activity Details: {local_time} ({activity_group_name}) ''' ''' $contents ''' ''' ## Load Data Open a connection to the database and load the data we require. ''' s = session('-v2') activity = std_activity_statistics(s, local_time=local_time, activity_group_name=activity_group_name) details = activity_statistics(s, 'Climb %', ACTIVE_TIME, ACTIVE_DISTANCE, local_time=local_time, activity_group_name=activity_group_name) health = std_health_statistics(s) hr_zones = hr_zones_from_database(s, local_time, activity_group_name) f''' ## Activity Plots To the right of each plot of data against distance is a related plot of cumulative data (except the last, cadence, which isn't useful and so replaced by HR zones). Green and red areas indicate differences between the two dates. Additional red lines on the altitude plot are auto-detected climbs. Plot tools support zoom, dragging, etc. ''' output_file(filename='/dev/null') sp = comparison_line_plot(700, 200, DISTANCE_KM, MED_SPEED_KMH, activity, ylo=0) sp_c = cumulative_plot(200, 200, MED_SPEED_KMH, activity, ylo=0) el = comparison_line_plot(700, 200, DISTANCE_KM, ELEVATION_M, activity, x_range=sp.x_range) add_climbs(el, details, activity) el_c = cumulative_plot(200, 200, CLIMB_MS, activity) hri = comparison_line_plot(700, 200, DISTANCE_KM, HR_IMPULSE_10, activity, ylo=0, x_range=sp.x_range) hri_c = cumulative_plot(200, 200, HR_IMPULSE_10, activity, ylo=0) hr = comparison_line_plot(700, 200, DISTANCE_KM, HEART_RATE_BPM, activity, x_range=sp.x_range) add_hr_zones(hr, activity, DISTANCE_KM, hr_zones) hr_c = cumulative_plot(200, 200, HEART_RATE_BPM, activity) pw = comparison_line_plot(700, 200, DISTANCE_KM, MED_POWER_ESTIMATE_W, activity, ylo=0, x_range=sp.x_range) pw_c = cumulative_plot(200, 200, MED_POWER_ESTIMATE_W, activity, ylo=0) cd = comparison_line_plot(700, 200, DISTANCE_KM, MED_CADENCE, activity, ylo=0, x_range=sp.x_range) hr_h = histogram_plot(200, 200, HR_ZONE, activity, xlo=1, xhi=5) show( gridplot([[el, el_c], [sp, sp_c], [hri, hri_c], [hr, hr_c], [pw, pw_c], [cd, hr_h]])) ''' ## Activity Maps ''' map = map_plot(400, 400, activity) m_el = map_intensity_signed(200, 200, activity, GRADE_PC, ranges=map, power=0.5) m_sp = map_intensity(200, 200, activity, SPEED_KMH, ranges=map, power=2) m_hr = map_intensity(200, 200, activity, HR_IMPULSE_10, ranges=map) m_pw = map_intensity(200, 200, activity, MED_POWER_ESTIMATE_W, ranges=map) show( row(map, gridplot([[m_el, m_sp], [m_hr, m_pw]], toolbar_location='right'))) ''' ## Activity Statistics ''' ''' Active time and distance exclude pauses. ''' details[[ACTIVE_TIME, ACTIVE_DISTANCE]].dropna(). \ transform({ACTIVE_TIME: format_seconds, ACTIVE_DISTANCE: format_metres}) ''' Climbs are auto-detected and shown only for the main activity. They are included in the elevation plot above. ''' if present(details, CLIMB_TIME): display( transform( details.filter(like='Climb').dropna(), { CLIMB_TIME: format_seconds, CLIMB_ELEVATION: format_metres, CLIMB_DISTANCE: format_metres, CLIMB_GRADIENT: format_percent, CLIMB_POWER: format_watts, CLIMB_CATEGORY: lambda x: x })) ''' ## Health and Fitness ''' fitness, fatigue = like(FITNESS_D_ANY, health.columns), like(FATIGUE_D_ANY, health.columns) colours = ['black'] * len(fitness) + ['red'] * len(fatigue) alphas = [1.0] * len(fitness) + [0.5] * len(fatigue) ff = multi_line_plot(900, 300, TIME, fitness + fatigue, health, colours, alphas=alphas) xrange = ff.x_range if ff else None add_multi_line_at_index(ff, TIME, fitness + fatigue, health, colours, alphas=alphas, index=-1) atd = std_distance_time_plot(900, 200, health, x_range=ff.x_range) shr = multi_plot( 900, 200, TIME, [DAILY_STEPS, REST_HR], health, ['grey', 'red'], alphas=[1, 0.5], x_range=xrange, rescale=True, plotters=[bar_plotter(dt.timedelta(hours=20)), dot_plotter()]) add_band(shr, TIME, LO_REST_HR, HI_REST_HR, health, 'red', alpha=0.1, y_range_name=REST_HR) show(column(ff, atd, shr))
p1.x_range.callback = CustomJS(args=dict(source=source), code=jscode % ('x', 'width')) p1.y_range.callback = CustomJS(args=dict(source=source), code=jscode % ('y', 'height')) p2 = figure(title='See Zoom Window Here', x_range=(0, 100), y_range=(0, 100), tools='', plot_width=400, plot_height=400) p2.scatter(x, y, radius=radii, fill_color=colors, fill_alpha=0.6, line_color=None) rect = Rect(x='x', y='y', width='width', height='height', fill_alpha=0.1, line_color='black', fill_color='black') p2.add_glyph(source, rect) layout = row(p1, p2) show(layout)
label1ya.text = "reduced to = " + str(np.around(100 * mp2[0], decimals=2)) + "%" label50a.text = 'reduced to = ' + str(np.around(MA2, decimals=1)) label75a.text = 'reduced to = ' + str(np.around(A72, decimals=1)) label25a.text = 'reduced to = ' + str(np.around(A22, decimals=1)) for w in [AgeSlider, EventMortalitySlider]: w.on_change('value', update_data) GenderRadioButtons.on_change('active', update_data) FreqRadioButtons.on_change('active', update_data) inputs = column(AgeSlider, EventMortalitySlider, FreqRadioButtons, GenderRadioButtons) # read in html strings for header and footer # with open ("LifeHeader.txt", "r") as myfile: # texttop=myfile.read() with open("LifeFooter.txt", "r") as myfile: textbottom = myfile.read() # divtop = Div(text=texttop, sizing_mode="scale_width") divbottom = Div(text=textbottom, sizing_mode="scale_width") # create the document # curdoc().add_root(divtop) curdoc().add_root(row(inputs, plot)) curdoc().add_root(divbottom) curdoc().title = "LifeExpectancy"
def tuning_tab(beam, acc): '''Tuning accelerator ''' pre = PreText(text='''You can configure accelerator elements.''') element_button = RadioButtonGroup( labels=['Accels', 'Solenoids', 'Quadrupoles'], active=0) tune_button = Button(label='Tune', button_type="success") select = Select(options=[itm.name for itm in acc.Ez_beamline.values()]) select_maxfield = Slider(start=-5.0, end=5.0, step=0.1, value=0.0, title='MaxField [MV/m]', format='0[.]0') line_source = ColumnDataSource(data={'z': [0, 0], 'x': [-0.1, 0.1]}) field_source = ColumnDataSource(data={'z': acc.z, 'Fz': acc.Ez(acc.z)}) field_plot = figure(x_axis_label='z [m]', y_axis_label='Ez [MV/m]', width=330, height=210) field_plot.line('z', 'Fz', source=field_source, line_color='#3A5785', line_alpha=0.7, line_width=1) envelope_plot = figure(x_axis_label='z [m]', y_axis_label='Envelope, x [m]', width=650, height=250) envelope_source = ColumnDataSource(data={'z': acc.z, 'x': 0*acc.z, '-x': 0*acc.z}) centroid_source = ColumnDataSource(data={'z': acc.z, 'x': 0*acc.z}) envelope_plot.line('z', 'x', source=envelope_source, line_color='#3A5785', line_alpha=0.7, line_width=1) envelope_plot.line('z', '-x', source=envelope_source, line_color='#3A5785', line_alpha=0.7, line_width=1) envelope_plot.line('z', 'x', source=line_source, line_color='#3A5785', line_alpha=0.1, line_width=10) envelope_plot.line('z', 'x', source=centroid_source, line_color='#3A5785', line_alpha=0.7, line_width=1, line_dash=[3,5]) controls = row(column(pre, element_button, select, select_maxfield, tune_button), field_plot) tab = Panel(child=column(controls, envelope_plot), title='Tuning') def element_handler(new, acc=acc): if new == 0: select.options=[itm.name for itm in acc.Ez_beamline.values()] select_maxfield.start = -5.0 select_maxfield.end = 5.0 select_maxfield.step = 0.1 if select.options == []: select_maxfield.value = 0.0 select.value = '' else: select_maxfield.value = acc.Ez_beamline[select.options[0]].max_field select.value = [itm.name for itm in acc.Ez_beamline.values()][0] select_maxfield.format='0[.]0' select_maxfield.title = 'MaxField [MV/m]' field_source.data = {'z': acc.z, 'Fz': acc.Ez(acc.z)} field_plot.yaxis.axis_label = 'Ez [MV/m]' if new == 1: select.options=[itm.name for itm in acc.Bz_beamline.values()] select_maxfield.start = 0.000 select_maxfield.end = 0.500 select_maxfield.step = 0.001 if select.options == []: select_maxfield.value = 0.000 select.value = '' else: select_maxfield.value = acc.Bz_beamline[select.options[0]].max_field select.value = [itm.name for itm in acc.Bz_beamline.values()][0] select_maxfield.format='0[.]000' select_maxfield.title = 'MaxField [T]' field_source.data = {'z': acc.z, 'Fz': acc.Bz(acc.z)} field_plot.yaxis.axis_label = 'Bz [T]' if new == 2: select.options=[itm.name for itm in acc.Gz_beamline.values()] select_maxfield.start = -10.0 select_maxfield.end = 10.0 select_maxfield.step = 0.1 if select.options == []: select_maxfield.value = 0.0 select.value = '' else: select_maxfield.value = acc.Gz_beamline[select.options[0]].max_field select.value = [itm.name for itm in acc.Gz_beamline.values()][0] select_maxfield.format='0[.]0' select_maxfield.title = 'MaxField [T/m]' field_source.data = {'z': acc.z, 'Fz': acc.Gz(acc.z)} field_plot.yaxis.axis_label = 'Gz [T/m]' def update_select_maxfield(attrname, old, new, acc=acc): if new != '': if element_button.active == 0: select_maxfield.value = acc.Ez_beamline[new].max_field line_source.data = {'z': [acc.Ez_beamline[new].z0, acc.Ez_beamline[new].z0], 'x': [-0.1, 0.1]} if element_button.active == 1: select_maxfield.value = acc.Bz_beamline[new].max_field line_source.data = {'z': [acc.Bz_beamline[new].z0, acc.Bz_beamline[new].z0], 'x': [-0.1, 0.1]} if element_button.active == 2: select_maxfield.value = acc.Gz_beamline[new].max_field line_source.data = {'z': [acc.Gz_beamline[new].z0, acc.Gz_beamline[new].z0], 'x': [-0.1, 0.1]} def tune_handler(new, beam=beam, acc=acc): if select.value != '': if element_button.active == 0: acc.Ez_beamline[select.value].max_field = select_maxfield.value acc.compile() field_source.data = {'z': acc.z, 'Fz': acc.Ez(acc.z)} if element_button.active == 1: acc.Bz_beamline[select.value].max_field = select_maxfield.value acc.compile() field_source.data = {'z': acc.z, 'Fz': acc.Bz(acc.z)} if element_button.active == 2: acc.Gz_beamline[select.value].max_field = select_maxfield.value acc.compile() field_source.data = {'z': acc.z, 'Fz': acc.Gz(acc.z)} beam.df['p2'] = beam.df['pz']*beam.df['pz'] + beam.df['px']*beam.df['px'] + beam.df['py']*beam.df['py'] E = beam.df['p2'].mean()**0.5 - beam.type.mass*rp.c**2/rp.e/1e6 I = np.sign(beam.type.charge) * beam.charge * rp.c / (beam.df['z'].max()-beam.df['z'].min()) X = beam.df['x'].max() Y = beam.df['y'].max() Xp = beam.df['px'].max() / beam.df['pz'].max() Yp = beam.df['py'].max() / beam.df['pz'].max() X_off = beam.df['x'].mean() Y_off = beam.df['x'].mean() Xp_off = beam.df['px'].mean() / beam.df['pz'].max() Yp_off = beam.df['py'].mean() / beam.df['pz'].max() beta = beam.df['pz'].max() / (E + beam.type.mass*rp.c**2/rp.e/1e6) gamma = 1/(1-beta**2)**0.5 df = beam.df df['xp'] = df['px']/df['pz'] df['yp'] = df['py']/df['pz'] df['xp2'] = df['xp']*df['xp'] df['yp2'] = df['yp']*df['yp'] df['x xp'] = df['x']*df['xp'] df['y yp'] = df['y']*df['yp'] df['x2'] = df['x']*df['x'] df['y2'] = df['y']*df['y'] df['rms x'] = df['x2'].mean()**0.5 df['rms y'] = df['y2'].mean()**0.5 df['rms x Emittance'] = (df['x2'].mean()*df['xp2'].mean() - df['x xp'].mean()**2)**0.5 df['rms y Emittance'] = (df['y2'].mean()*df['yp2'].mean() - df['y yp'].mean()**2)**0.5 Emitt_x = df['rms x Emittance'].max()*gamma*beta Emitt_y = df['rms y Emittance'].max()*gamma*beta kv_beam = kv.Beam(energy=E, current=I, radius_x=X, radius_y=Y, radius_xp=Xp, radius_yp=Yp, normalized_emittance_x=Emitt_x, normalized_emittance_y=Emitt_y, x=X_off, y=Y_off, xp=Xp_off, yp=Yp_off, charge=np.sign(beam.type.charge)) kv_sim = kv.Simulation(kv_beam, acc) kv_sim.track() envelope_source.data = {'z': acc.z, 'x': kv_sim.envelope_x(acc.z), '-x': -kv_sim.envelope_x(acc.z)} centroid_source.data = {'z': acc.z, 'x': kv_sim.centroid_x(acc.z)} element_button.on_click(element_handler) select.on_change('value', update_select_maxfield) tune_button.on_click(tune_handler) return tab
from bokeh.io import output_file, show from bokeh.layouts import row from bokeh.plotting import figure output_file("layout.html") x = list(range(11)) y0 = x y1 = [10 - i for i in x] y2 = [abs(i - 5) for i in x] # create a new plot s1 = figure(width=250, plot_height=250, title=None) s1.circle(x, y0, size=10, color="navy", alpha=0.5) # create another one s2 = figure(width=250, height=250, title=None) s2.triangle(x, y1, size=10, color="firebrick", alpha=0.5) # create and another s3 = figure(width=250, height=250, title=None) s3.square(x, y2, size=10, color="olive", alpha=0.5) # put the results in a row show(row(s1, s2, s3))
def get_thiel_analysis_plots(ulog, px4_ulog, db_data, vehicle_data, link_to_main_plots): global dfdata, simsource, simsource_static, realsource, realsource_static, usimsource, ts1, ts2, x, y """ get all bokeh plots shown on the Thiel analysis page :return: list of bokeh plots """ def _resample(time_array, data, desired_time): """ resample data at a given time to a vector of desired_time """ data_f = interp1d(time_array, data, fill_value='extrapolate') return data_f(desired_time) sim = False if link_to_main_plots.find("sim") is not -1: temp_link_to_main_plots = link_to_main_plots.replace('sim', '') sim = True if sim: print("do some sim stuff") else: print("do regular stuff") page_intro = """ <p> This page shows the correspondance between a simulated and a real flight log. </p> """ # curdoc().template_variables['title_html'] = get_heading_html( # ulog, px4_ulog,db_data, None, [('Open Main Plots', link_to_main_plots,)], # 'Thiel Analysis') + page_intro curdoc().template_variables['title_html'] = get_heading_html( ulog, px4_ulog, db_data, None, additional_links=[( 'Open Main Plots', link_to_main_plots, ), ("Open Matching Simulation Log", '/browse?search=sim')]) # set up plots simsource = ColumnDataSource(data=dict(x=[], y=[])) simsource_static = ColumnDataSource(data=dict(x=[], y=[])) realsource = ColumnDataSource(data=dict(realx=[], realy=[])) realsource_static = ColumnDataSource(data=dict(realx=[], realy=[])) cur_dataset = ulog.get_dataset('vehicle_local_position') dfdata = pd.DataFrame(cur_dataset.data) print(dfdata['x']) keys = [] data = ulog.data_list for d in data: data_keys = [f.field_name for f in d.field_data] data_keys.remove('timestamp') # print (data_keys) keys.append(data_keys) t = cur_dataset.data['timestamp'] x = cur_dataset.data['x'] y = cur_dataset.data['y'] usimsource = ColumnDataSource(data=dict(x=t, y=y)) usimsource_static = ColumnDataSource(data=dict(x=t, y=y)) simtools = 'xpan,wheel_zoom,xbox_select,reset' realtools = 'xpan,wheel_zoom,reset' ts1 = figure(plot_width=900, plot_height=200, tools=simtools, x_axis_type='linear', active_drag="xbox_select") ts1.line('x', 'y', source=simsource, line_width=2) ts1.circle('x', 'y', size=1, source=simsource_static, color=None, selection_color="orange") ts2 = figure(plot_width=900, plot_height=200, tools=realtools, x_axis_type='linear') # to adjust ranges, add something like this: x_range=Range1d(0, 1000), y_range = None, # ts2.x_range = ts1.x_range ts2.line('realx', 'realy', source=realsource, line_width=2) ts2.circle('realx', 'realy', size=1, source=realsource_static, color="orange") plots = [] flight_mode_changes = get_flight_mode_changes(ulog) x_range_offset = (ulog.last_timestamp - ulog.start_timestamp) * 0.05 x_range = Range1d(ulog.start_timestamp - x_range_offset, ulog.last_timestamp + x_range_offset) # cur_dataset = {} # cur_dataset = ulog.get_dataset('vehicle_gps_position') # # x = cur_dataset.data['vehicle_local_position'] # # y = cur_dataset.data['y'] # # FIXME: bokeh should be able to handle np.nan values properly, but # # we still get a ValueError('Out of range float values are not JSON # # compliant'), if x or y contains nan # non_nan_indexes = np.logical_not(np.logical_or(np.isnan(x), np.isnan(y))) # x = x[non_nan_indexes] # y = y[non_nan_indexes] # if check_if_all_zero: # if np.count_nonzero(x) == 0 and np.count_nonzero(y) == 0: # raise ValueError() # data_source = ColumnDataSource(data=dict(x=x, y=y)) # data_set['timestamp'] = cur_dataset.data['timestamp'] # plot positions # datatype = Select(value='XY', options=DEFAULT_FIELDS) datatype = Select(value='XY', options=keys[0]) datatype.on_change('value', sim_change) file_input = FileInput(accept=".ulg") file_input.on_change('value', upload_new_data_sim) file_input2 = FileInput(accept=".ulg") file_input2.on_change('value', upload_new_data_real) intro_text = Div( text="""<H2>Sim/Real Thiel Coefficient Calculator</H2>""", width=500, height=100, align="center") sim_upload_text = Paragraph(text="Upload a simulator datalog:", width=500, height=15) real_upload_text = Paragraph( text="Upload a corresponding real-world datalog:", width=500, height=15) choose_field_text = Paragraph(text="Choose a data field to compare:", width=500, height=15) #checkbox_group = CheckboxGroup(labels=["x", "y", "vx","vy","lat","lon"], active=[0, 1]) simsource_static.selected.on_change('indices', simselection_change) # The below are in case you want to see the x axis range change as you pan. Poorly documented elsewhere! #ts1.x_range.on_change('end', lambda attr, old, new: print ("TS1 X range = ", ts1.x_range.start, ts1.x_range.end)) #ts2.x_range.on_change('end', lambda attr, old, new: print ("TS2 X range = ", ts2.x_range.start, ts2.x_range.end)) ts1.x_range.on_change( 'end', lambda attr, old, new: change_sim_scale(ts1.x_range.start)) ts2.x_range.on_change( 'end', lambda attr, old, new: change_real_scale(ts2.x_range.start)) # set up layout widgets = column(datatype, stats) sim_button = column(sim_reverse_button) real_button = column(real_reverse_button) main_row = row(widgets) series = column(ts1, sim_button, ts2, real_button) layout = column(main_row, series) # initialize update() curdoc().add_root(intro_text) curdoc().add_root(sim_upload_text) curdoc().add_root(file_input) curdoc().add_root(real_upload_text) curdoc().add_root(file_input2) curdoc().add_root(choose_field_text) curdoc().add_root(layout) curdoc().title = "Flight data" # plot_config['custom_tools'] = 'xpan,wheel_zoom,xbox_select,reset' # Local position for axis in ['x', 'y', 'z']: data_plot = DataPlot(data, plot_config, 'vehicle_local_position', y_axis_label='[m]', title='Local Position ' + axis.upper(), plot_height='small', x_range=x_range) data_plot.add_graph([axis], colors2[0:1], [axis.upper() + ' Estimated'], mark_nan=True) data_plot.change_dataset('vehicle_local_position_setpoint') data_plot.add_graph([axis], colors2[1:2], [axis.upper() + ' Setpoint'], use_step_lines=True) plot_flight_modes_background(data_plot, flight_mode_changes) if data_plot.finalize() is not None: plots.append(data_plot) x_range_offset = (ulog.last_timestamp - ulog.start_timestamp) * 0.05 x_range = Range1d(ulog.start_timestamp - x_range_offset, ulog.last_timestamp + x_range_offset) # exchange all DataPlots with the bokeh_plot jinja_plot_data = [] for i in range(len(plots)): if plots[i] is None: plots[i] = column(param_changes_button, width=int(plot_width * 0.99)) if isinstance(plots[i], DataPlot): if plots[i].param_change_label is not None: param_change_labels.append(plots[i].param_change_label) plot_title = plots[i].title plots[i] = plots[i].bokeh_plot fragment = 'Nav-'+plot_title.replace(' ', '-') \ .replace('&', '_').replace('(', '').replace(')', '') jinja_plot_data.append({ 'model_id': plots[i].ref['id'], 'fragment': fragment, 'title': plot_title }) curdoc().template_variables['plots'] = jinja_plot_data return plots
# set to roughly extent of points x_range = Range1d(start=airports['x'].min() - 10000, end=airports['x'].max() + 10000, bounds=None) y_range = Range1d(start=airports['y'].min() - 10000, end=airports['y'].max() + 10000, bounds=None) # create plot and add tools p = figure(tools='wheel_zoom,pan', x_range=x_range, y_range=y_range, title=title) p.axis.visible = False hover_tool = HoverTool(tooltips=[("Name", "@name"), ("Elevation", "@elevation (m)")]) p.add_tools(hover_tool) p.add_tile(tile_source) # create point glyphs p.circle(x='x', y='y', size=9, fill_color="#F46B42", line_color="#D2C4C1", line_width=1.5, source=points_source) return p # create a tile source tile_options = {} tile_options['url'] = 'http://tile.stamen.com/terrain/{Z}/{X}/{Y}.png' tile_options['attribution'] = """ Map tiles by <a href="http://stamen.com">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>. Data by <a href="http://openstreetmap.org">OpenStreetMap</a>, under <a href="http://www.openstreetmap.org/copyright">ODbL</a>. """ mq_tile_source = WMTSTileSource(**tile_options) carto = plot(CARTODBPOSITRON, 'airports_map_cartodb.html') mq = plot(mq_tile_source, 'airports_map.html') show(row([carto, mq]))
# Ein Schieberegler wird definiert freq = Slider(title="freq", value=1.0, start=1, end=105, step=0.1) # wir holen uns eine Datei für das logging log = open('/tmp/bokeh.log', 'a') # Diese Funktion soll gerufen werden, wenn der Schieberegler sich ändert .. def update_data(attrname, old, new): k = freq.value x = np.linspace(0, X_MAX, N) y = np.sin(k * x) source.data = dict(x=x, y=y) # füge eine fiktive Berechnugns-Zeit von einer Sekunde ein sleep(1) # Wir schreiben den log log_line_template = "%s: attribute: %s, old: %s, new: %s\n" log_line = log_line_template % (time.time(), attrname, old, new) log.write(log_line) # .. was hier verdrahtet wird freq.on_change('value', update_data) # Hier wird eine Box im Browser erzeut, welche den Schieberegler enthält inputs = widgetbox(freq) # Diese Box wir im HTML-Document mit dem Plot in einer Zeile ausgerichtet curdoc().add_root(row(inputs, plot, width=800))
xmenu = [] for param in r0.keys(): for item in r0[param]: xmenu.append((item, item)) xmenu.append(None) xdrop = Dropdown(menu=xmenu[:-1], button_type='primary') xdrop.on_change('value', update_xdrop) # create the Panel and Tabs objects for setting up the investment parameters panels = [] for param in r0.keys(): panels.append(create_panel(param, r0[param])) tabs = Tabs(tabs=panels, width=1000) # create the app layout top = row(fig, widgetbox(xdrop, width=300)) layout = column(top, tabs) # update the document and initialize the app by setting the Dropdown value curdoc().add_root(layout) param0 = list(r0.keys())[0] xdrop.value = list(r0[param0].keys())[0]
hover.tooltips = [ ("Observation Starts", "@RealStarts"), ("Duration in Minutes", "@Starts"), ("Observation Counts", "@RealCounts"), ("Bird's Name", "@Name"), ] p.add_tools(hover) return p # ============================================================================================= # Task5: draw the figure and add bokeh server for interactive visualization # ============================================================================================= # call datasource_construction function to get the source source = datasource_construct(df) # call draw_plot function to create the plots p = draw_plot(source) layout = column(p, row(select_category, width=200)) # ======= using bokeh server to run the application ======== # reference: https://bokeh.pydata.org/en/latest/docs/user_guide/server.html curdoc().add_root(layout) # ======= optional: output the result file ======== output_file('dvc_exc2_skeleton.html')
df=pd.DataFrame({'x':x,'y':y,'label':label}) source = ColumnDataSource(data=dict(x=df.x, y=df.y,label=df.label)) plot_figure = figure(title='Select',plot_height=450, plot_width=600, tools="save,reset", toolbar_location="below") plot_figure.scatter('x', 'y', source=source, size=10,color='label') select = Select(title="Filter plot by color:", value="All", options=["All", "Red", "Orange"]) def select_click(attr,old,new): active_select=select.value ##Getting radio button value # filter the dataframe with value in select if active_select!='All': selected_df=df[df['label']==active_select] else: selected_df=df.copy() source.data=dict(x=selected_df.x, y=selected_df.y,label=selected_df.label) select.on_change('value',select_click) layout=row(select, plot_figure) curdoc().add_root(layout) curdoc().title = "Select Bokeh Server"
color=c, size=sz, line_color="white", alpha=0.6, hover_color='white', hover_alpha=0.5) return p def update(attr, old, new): layout.children[1] = create_figure() x = Select(title='X-Axis', value='mpg', options=columns) x.on_change('value', update) y = Select(title='Y-Axis', value='hp', options=columns) y.on_change('value', update) size = Select(title='Size', value='None', options=['None'] + quantileable) size.on_change('value', update) color = Select(title='Color', value='None', options=['None'] + quantileable) color.on_change('value', update) controls = widgetbox([x, y, color, size], width=200) layout = row(controls, create_figure()) curdoc().add_root(layout) curdoc().title = "Crossfilter"
from bokeh.plotting import figure from bokeh.layouts import row from bokeh.io import save def make_figure(output_backend): p = figure(plot_width=400, plot_height=400, output_backend=output_backend, title="Backend: %s" % output_backend) p.circle(x=[1, 2, 3], y=[1, 2, 3], radius=0.25, color="blue", alpha=0.5) p.annulus(x=[1, 2, 3], y=[1, 2, 3], inner_radius=0.1, outer_radius=0.20, color="orange") return p canvas = make_figure("canvas") webgl = make_figure("webgl") svg = make_figure("svg") save(row(canvas, webgl, svg))
def trend_chart(returns_series, compounding: bool = False, height: int = 350, width: int = 800): """Trend chart of the result using Bokeh. Parameters ---------- returns_series : Pandas Series Series contains returns. compounding : bool, default False Whether returns are reinvested back into the account. height : int Height of the plot width : int Width of the plot Returns ------- None """ data = returns_series if compounding: cum = (data + 1).cumprod() else: cum = data.cumsum() + 1 cum = pd.DataFrame(cum) source = ColumnDataSource(data=cum) p = figure(x_axis_type="datetime", title="Trend Line", plot_height=height, plot_width=width) p.xgrid.grid_line_color = None p.ygrid.grid_line_alpha = 0.5 p.xaxis.axis_label = 'Time' p.yaxis.axis_label = 'Total Return' lines = [] for i in range(len(cum.columns)): lines.append( p.line("Date", cum.columns[i], source=source, line_width=2, line_alpha=0.8, line_color=Spectral10[i % 10], legend_label=cum.columns[i], muted_color=Spectral10[i % 10], muted_alpha=0.1)) p.legend.location = "top_left" p.legend.click_policy = "mute" LABELS = list(cum.columns) checkbox_group = CheckboxGroup(labels=LABELS) checkbox_group.active = list(range(len(LABELS))) code = """ for (var i = 0; i < lines.length; i++) { lines[i].visible = false; if (cb_obj.active.includes(i)){lines[i].visible = true;} } """ callback = CustomJS(code=code, args={'lines': lines}) checkbox_group.js_on_click(callback) layout = row(p, checkbox_group) show(layout)
from bokeh.charts import Histogram, output_file, show from bokeh.layouts import row from bokeh.sampledata.autompg import autompg as df hist = Histogram(df, values='mpg', title="Auto MPG Histogram", plot_width=400) hist2 = Histogram(df, values='mpg', label='cyl', color='cyl', legend='top_right', title="MPG Histogram by Cylinder Count", plot_width=400) output_file('hist.html') show(row(hist, hist2))
('Price', '@nadac_per_unit')], formatters={'date': 'datetime'})) return plot def update_plot(attrname, old, new): ver = vselect.value df1 = df.loc[df['ndc'] == int(new)] df1['date'] = pd.to_datetime(df1['date']) df1 = df1.set_index(['date']) df1.sort_index(inplace=True) newSource = ColumnDataSource(df1) source.data = newSource.data df = pd.read_csv('plotting_data.csv') ver = '54034808' #Initial id number cc = df['ndc'].astype(str).unique() #select-menu options vselect = Select(value=ver, title='Drug ID', options=sorted((cc))) source = get_dataset(df, ver) plot = make_plot(source, "Drug Prices") vselect.on_change('value', update_plot) controls = row(vselect) curdoc().add_root(row(plot, controls)) show(plot)
function1_input.on_change('value', input_change) # text input for the second function to be convolved function2_input = TextInput(value=convolution_settings.function1_input_init, title="my second function:") function2_input.on_change('value', input_change) # initialize plot toolset = "crosshair,pan,reset,resize,save,wheel_zoom" # Generate a figure container plot = Figure(plot_height=400, plot_width=400, tools=toolset, title="Convolution of two functions", x_range=[convolution_settings.x_min_view, convolution_settings.x_max_view], y_range=[convolution_settings.y_min_view, convolution_settings.y_max_view]) # Plot the line by the x,y values in the source property plot.line('x', 'y', source=source_function1, line_width=3, line_alpha=0.6, color='red', legend='function 1') plot.line('x', 'y', source=source_function2, color='green', line_width=3, line_alpha=0.6, legend='function 2') plot.line('x', 'y', source=source_result, color='blue', line_width=3, line_alpha=0.6, legend='convolution') plot.scatter('x', 'y', source=source_xmarker, color='black') plot.line('x', 'y', source=source_xmarker, color='black', line_width=3) plot.patch('x', 'y_pos', source=source_overlay, fill_color='blue', fill_alpha=.2) plot.patch('x', 'y_neg', source=source_overlay, fill_color='red', fill_alpha=.2) # calculate data update_data() # lists all the controls in our app controls = widgetbox(x_value_input, function_type, function1_input, function2_input, width=400) # make layout curdoc().add_root(row(plot, controls, width=800))
def readData(self, station): stationOutputFile = os.path.expanduser( f'~/Downloads/Weather/{station.ID}.csv') if os.path.exists(stationOutputFile): stationDF = pd.read_csv(stationOutputFile, index_col=0, parse_dates=True) else: interesingElements = ['PRCP', 'TMAX', 'TMIN', 'TAVG'] stationDF = pd.DataFrame(columns=['StationId', 'Date'] + interesingElements) dataPath = os.path.expanduser( "~/Downloads/Weather/ghcnd_all.tar.gz") with tarfile.open(dataPath) as alltar: stationFileTarInfo = alltar.getmember( f'ghcnd_all/{station.ID}.dly') with alltar.extractfile(stationFileTarInfo) as stationFile: for line in stationFile: line = line if isinstance( line, str) else line.decode('utf-8') element = line[17:21] if element not in interesingElements: continue stationId = line[0:11] startDate = datetime.date(int(line[11:15]), int(line[15:17]), 1) for day in range(1, 32): startField = 21 + (day - 1) * 8 value = float(line[startField:startField + 5].strip()) if value == -9999: continue fieldDate = startDate.replace(day=day) stationDF.at[fieldDate, element] = value stationDF.to_csv(stationOutputFile) yearlyPrecip = stationDF.groupby(lambda p: p.year)['PRCP'].sum() print(yearlyPrecip) yearlyPlot = figure( title=f"Precipitation by calendar year: {station.NAME}", x_axis_label='Year', y_axis_label='mm * 100') yearlyPlot.line(yearlyPrecip.index, yearlyPrecip) monthlyPrecip = stationDF.groupby( lambda p: p.replace(day=1))['PRCP'].sum() monthlyPlot = figure(title=f"Precipitation by month: {station.NAME}", x_axis_type="datetime", x_axis_label='Month', y_axis_label='mm * 100') monthlyPlot.line(monthlyPrecip.index, monthlyPrecip) monthlyComparisonPlot = figure( title=f"Precipitation by month comparison: {station.NAME}", x_axis_label='Month', y_axis_label='mm * 100') for year in range(stationDF.index.min().year, stationDF.index.max().year + 1): yearData = stationDF[stationDF.index.year == year].groupby( lambda p: p.replace(day=1))['PRCP'].sum() monthlyComparisonPlot.line(yearData.index.month, yearData) stationRow = row(yearlyPlot, monthlyPlot, monthlyComparisonPlot) curdoc().add_root(stationRow)
radii = np.random.random(size=N) * 1.5 colors = [ "#%02x%02x%02x" % (int(r), int(g), 150) for r, g in zip(50+2*x, 30+2*y) ] p = figure(tools="pan,wheel_zoom,zoom_in,zoom_out,reset") p.scatter(x, y, radius=radii, fill_color=colors, fill_alpha=0.6, line_color=None) # Add a div to display events and a button to trigger button click events div = Div(width=1000) button = Button(label="Button", button_type="success") layout = column(button, row(p, div)) point_attributes = ['x','y','sx','sy'] pan_attributes = point_attributes + ['delta_x', 'delta_y'] pinch_attributes = point_attributes + ['scale'] wheel_attributes = point_attributes+['delta'] ## Register Javascript event callbacks # Button event button.js_on_event(events.ButtonClick, display_event(div)) # LOD events p.js_on_event(events.LODStart, display_event(div)) p.js_on_event(events.LODEnd, display_event(div))
columns = [ TableColumn(field='x', title='Parameter'), TableColumn(field='y', title="Calibrated Value") ] heading_para = Div(text="<font color ='#808080'><h4> Calibrated Parameters </h4></font><br><br>",\ width = 800, height = 4) # Set up heading for parameters data_table2 = DataTable(source=source3, columns=columns, width=300, height=120) # Set up data table #export_table= Button(label='Export Table', button_type="default") # Create export table button #export_table.on_click(exportParam) # Export Function # Layout widgetrow1 = widgetbox(spacing4, w_loadinput) widgetcol2 = widgetbox(w_k1, w_k2, w_k3, w_k4, w_loadpara) widgetcol3 = widgetbox(w_d1, w_d2, w_rfcf, w_ecorr) #,w_savepara) widget7 = widgetbox(heading_dis, data_table1, w_fn, spacing6, heading2) widget5 = widgetbox(C_title, spacing2, spacing1, w_calibrate, heading_para, data_table2) #,export_table) widget6 = widgetbox(RM_title, spacing3, spacing5, w_runmodel, heading_error, data_table) r = row(heading) g = gridplot([[widget7, widgetrow1, prain], [widgetcol2, widgetcol3, pdischarge], [widget6, widget5, pstorage]]) w = column(r, g) curdoc().add_root(w) curdoc().title = "Sugawara GUI_sample1"
label_fixation_button.on_click(label_fixation_cb) remove_button = Button(label='remove') remove_button.on_click(remove_cb) trial_text = TextInput(value=str(trialNum)) trial_text.on_change('value', trial_text_cb) nextTrial_button = Button(label='+trial') nextTrial_button .on_click(next_trial_cb) prevTrial_button= Button(label='-trial') prevTrial_button.on_click(prev_trial_cb) from bokeh.layouts import row buttonBox = row(label_saccade_button, label_pursuit_button, label_fixation_button, remove_button) trialSelectBox = row(prevTrial_button, trial_text, nextTrial_button) #, sizing_mode='scale_width' ########################################################################### # Get the HTML description header from os.path import dirname, join desc = bkM.Div(text=open(join(dirname(__file__), "description.html")).read(), width=800) ########################################################################### # Add desc, figure and widgets to a layout from bokeh.layouts import layout layout = layout([[desc], [fig], [buttonBox],[trialSelectBox]]) ########################################################################### # Add layout to current document
"justify-content": "space-between", "display": "flex" }) div1 = Div( text= """Transformations: US Dollars, year over year growth rate and cumulative purchases in 2017 vs 2020.\n The later transformation cumulates Chinese purchases over each month in 2017 and 2020 and compares each. Because 2017 is the benchmark year for The Agreement, this measure provides a sense, for each product category, China's progress towards meeting their purchase commitments.\n """, width=400, background=background, style={ "justify-content": "space-between", "display": "flex" }) controls = column(product_select, div0, level_select, div1) height = int(1.95 * 533) width = int(1.95 * 675) layout = row(make_plot(), controls, sizing_mode="scale_height", max_height=height, max_width=width, min_height=int(0.25 * height), min_width=int(0.25 * width)) curdoc().add_root(layout) curdoc().title = "us-china-products"