def create(self): for _ in range(self.num_cameras): cam = BokehEventViewerCamera(self) cam.enable_pixel_picker(self.num_waveforms) cam.create_view_widget() cam.update_view_widget() cam.add_colorbar() self.cameras.append(cam) self.camera_layouts.append(cam.layout) for iwav in range(self.num_waveforms): wav = BokehEventViewerWaveform(self) active_color = self.cameras[0].active_colors[iwav] wav.fig.select(name='line')[0].glyph.line_color = active_color wav.enable_time_picker() wav.create_view_widget() wav.update_view_widget() self.waveforms.append(wav) self.waveform_layouts.append(wav.layout) self.layout = layout([ [column(self.camera_layouts), column(self.waveform_layouts)], ])
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 export(): nonlocal data import bokeh.charts as bch from bokeh.layouts import column # from bokeh.models import HoverTool, GlyphRenderer bch.output_file("Chart.html") data = data.iloc[1:, :] # TOOLS = "pan, wheel_zoom, box_zoom, crosshair, resize, reset "# , hover" title = "History (total result: {0:.2f} €)".format(result) if bonus > 0: title = title[:-1] + ", excluding Bonus: {0:.2f} €)".format(bonus) cols = ["Paid-in", "Balance", "Normalised", "Total Result"] if bonus > 0: cols = ["Paid-in", "Balance", "Normalised", "Total Result incl Bonus", "Total Result"] tsline = bch.TimeSeries(data, x="Time", y=cols, title=title, # tools=TOOLS, ylabel='Euro', legend=True, width=1250, height=550) """ from bokeh.models import HoverTool hover = HoverTool( tooltips=[ ("index", "$index"), ("(x,y)", "($x, $y)"), ("desc", "$balance"), # ("test", data.iloc["$index", 4]) ] ) tsline.add_tools(hover) """ if open_browser: bch.show(column(tsline)) else: bch.save(column(tsline)) import matplotlib.pyplot as plt import matplotlib matplotlib.style.use('ggplot') data.plot(x="Time", y=cols) plt.savefig("Chart.pdf")
def modify_doc(doc): plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) slider = Slider(start=0, end=10, value=1, title="bar", css_classes=["foo"], width=300) def cb(attr, old, new): slider.title = "baz" slider.on_change('value', cb) doc.add_root(column(slider, plot))
def test_js_on_change_executes(self, single_plot_page): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1])) plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_glyph(source, Circle(x='x', y='y', size=20)) text_input = TextInput(css_classes=['foo']) text_input.js_on_change('value', CustomJS(code=RECORD("value", "cb_obj.value"))) page = single_plot_page(column(text_input, plot)) el = page.driver.find_element_by_css_selector('.foo input') enter_text_in_element(page.driver, el, "val1") results = page.results assert results['value'] == 'val1' # double click to highlight and overwrite old text enter_text_in_element(page.driver, el, "val2", click=2) results = page.results assert results['value'] == 'val2' # Check clicking outside input also triggers enter_text_in_element(page.driver, el, "val3", click=2, enter=False) page.click_canvas_at_position(10, 10) results = page.results assert results['value'] == 'val3' assert page.has_no_console_errors()
def main(): figuresForAllFiles = []; for x in range(1000000): print '{0}\r'.format(x), print # Set up the argument parser # parser = argparse.ArgumentParser(description= 'Visualize operation log'); parser.add_argument('files', type=str, nargs='*', help='log files to process'); args = parser.parse_args(); if (len(args.files) == 0): parser.print_help() sys.exit(1) # Get names of standard CSS colors that we will use for the legend initColorList(); # output to static HTML file output_file(filename = "WT-log.html", title="Operation log"); for fname in args.files: figure = processFileAndCreatePlot(fname); figuresForAllFiles.append(figure); show(column(figuresForAllFiles));
def read_file_tab(self): """Lets the user choose a data file to read""" # Drop down list self.file_select = Select(name='Data files', value='', options=[], title='Data files') # Status text self.file_status = Div(text='', width=self.page_width) # Update the file_select and file_status controls with scan data self.scan_folder() # This line is here deliberately. The scan_folder would trigger # the on-change function and we don't want that first time around. self.file_select.on_change('value', self.file_changed) # Re-scan button file_rescan = Button(label="Rescan folder", button_type="success") file_rescan.on_click(self.scan_folder) # Layout c = column(self.file_select, self.file_status, file_rescan) return Panel(child=c, title="Read from file")
def test_copy_paste_to_textarea(self, bokeh_model_page): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1])) columns = [TableColumn(field='x', title='x'), TableColumn(field='y', title='y')] table = DataTable(source=source, columns=columns, editable=False, width=600) text_area = Div(text='<textarea id="T1"></textarea>') page = bokeh_model_page(column(table, text_area)) # Use reversed order to get the correct order copy_table_rows(page.driver, [2, 1]) # Copy is a little slow sleep(0.1) element = get_page_element(page.driver, '#T1') # Selenium doesn't paste until we write something to the element first # textarea works like a cell enter_text_in_cell_with_click_enter(page.driver, element, 'PASTED:') paste_values(page.driver, element) result = element.get_attribute('value') # The textarea now contains the content in the datatable assert result == '\nPASTED:\n0\t1\t1\n1\t2\t1\n' assert page.has_no_console_errors()
def __init__(self): xs = np.linspace(-np.pi, np.pi, 11) ys = xs Xs, Ys = np.meshgrid(xs, ys) self.Xs, self.Ys = Xs.flatten(), Ys.flatten() initdegree = 0 mat = rot_mat(initdegree) transXs, transYs = mat @ np.array([self.Xs, self.Ys]) TOOLS = "pan,lasso_select,save,reset" self.source = ColumnDataSource(data=dict(Xs=self.Xs, Ys=self.Ys, transXs=transXs, transYs=transYs)) self.fig = figure(tools=TOOLS, title="target", x_range=(-np.pi*np.sqrt(2)-1, np.pi*np.sqrt(2)+1), y_range=(-np.pi*np.sqrt(2)-1, np.pi*np.sqrt(2)+1)) self.fig.circle('Xs', 'Ys', source=self.source) self.transfig = figure(tools=TOOLS, title="transformed", x_range=self.fig.x_range, y_range=self.fig.y_range) self.transfig.circle('transXs', 'transYs', source=self.source, size=6) self.rot_param = Slider(title="degree", value=0, start=0, end=360, step=1) self.rot_param.on_change('value', self.update_data) self.plot = column(self.rot_param, gridplot([[self.fig, self.transfig]]))
def test_row_highlights_reflect_js_selection(self, bokeh_model_page): source = ColumnDataSource({'values': [1, 2]}) col = TableColumn(field='values', title='values') table = DataTable(source=source, columns=[col], editable=False, width=600) button = ButtonWrapper("Click", callback=CustomJS(args=dict(s=source), code=""" s.selected.indices = [1] """)) page = bokeh_model_page(column(button.obj, table)) row0 = get_table_cell(page.driver, 1, 1) assert 'selected' not in row0.get_attribute('class') row1 = get_table_cell(page.driver, 2, 1) assert 'selected' not in row1.get_attribute('class') button.click(page.driver) row0 = get_table_cell(page.driver, 1, 1) assert 'selected' not in row0.get_attribute('class') row1 = get_table_cell(page.driver, 2, 1) assert 'selected' in row1.get_attribute('class') assert page.has_no_console_errors()
def main(): maxmin_spec = ["Series/mxm", ["MaxMin/mxmin", "Transposer/trs"]] spec = ["Series/plot", ["SoundFileSource/src", "Stereo2Mono/s2m", ["Fanout/measurements", [ "ZeroCrossings/zcrs", "Rms/rms", maxmin_spec ]]]] accum_spec = ["Accumulator/accum", [spec]] playlist_folder = "/Users/georgetzanetakis/data/sound/yogi_tunes/" print(playlist_folder) wav_fnames = [f for f in os.listdir(playlist_folder) if f.endswith(".wav")] wav_fnames = [playlist_folder + s for s in wav_fnames] print(wav_fnames) # wav_fnames = ["/Users/georgetzanetakis/data/sound/yogi_tunes/1 - The Player's Hands (Instrumental).wav", # "6_lion_heart.wav", # "10_alienist.wav"] winSize = 44100 plot_net = create(accum_spec) inSamples = plot_net.getControl("mrs_natural/inSamples") inSamples.setValue_natural(winSize) nTimes = plot_net.getControl("mrs_natural/nTimes") fname = plot_net.getControl("Series/plot/SoundFileSource/src/mrs_string/filename") figs = [] for wav_fname in wav_fnames: fname.setValue_string(wav_fname) fsize = plot_net.getControl("Series/plot/SoundFileSource/src/mrs_natural/size").to_natural() srate = plot_net.getControl("Series/plot/SoundFileSource/src/mrs_real/osrate").to_real() nTicks = int(fsize /winSize) print(("nTicks=", nTicks)) nTimes.setValue_natural(nTicks) plot_net.tick() mydata = control2array(plot_net, "mrs_realvec/processedData") fig = bokeh_plot(mydata, wav_fname) figs.append(fig) show(column(*figs))
def __init__(self): self.xs = np.linspace(-2.0, 2.0, 100) self.ys = test_func(self.xs) self.source1 = ColumnDataSource(data=dict(xs=self.xs, ys=self.ys)) a = 0 txs, tys = get_tangentdata(a) self.source2 = ColumnDataSource(data=dict(txs=txs, tys=tys)) self.source3 = ColumnDataSource(data=dict(x=[a], y=[test_func(a)])) self.fig = figure(title='view tangent line', x_range=(-2.0, 2.0), y_range=(-0.2, 1.2)) self.fig.line('xs', 'ys', source=self.source1) self.fig.line('txs', 'tys', source=self.source2, color='orange') self.fig.circle('x', 'y', source=self.source3, color='red') self.slider = Slider(title='position', value=0, start=-1.5, end=1.5, step=0.1) self.slider.on_change('value', self.update_data) self.plot = column(self.slider, self.fig)
def main_doc(worker, extra, doc): with log_errors(): statetable = StateTable(worker) executing_ts = ExecutingTimeSeries(worker, sizing_mode='scale_width') communicating_ts = CommunicatingTimeSeries(worker, sizing_mode='scale_width') communicating_stream = CommunicatingStream(worker, sizing_mode='scale_width') xr = executing_ts.root.x_range communicating_ts.root.x_range = xr communicating_stream.root.x_range = xr doc.title = "Dask Worker Internal Monitor" add_periodic_callback(doc, statetable, 200) add_periodic_callback(doc, executing_ts, 200) add_periodic_callback(doc, communicating_ts, 200) add_periodic_callback(doc, communicating_stream, 200) doc.add_root(column(statetable.root, executing_ts.root, communicating_ts.root, communicating_stream.root, sizing_mode='scale_width')) doc.template = env.get_template('simple.html') doc.template_variables['active_page'] = 'main' doc.template_variables.update(extra) doc.theme = BOKEH_THEME
def main(): xs = np.linspace(-np.pi, np.pi, 10) ys = xs Xs, Ys = np.meshgrid(xs, ys) Xs, Ys = Xs.flatten(), Ys.flatten() theta = np.deg2rad(30) mat = np.array([[np.cos(theta), -np.sin(theta)], [np.sin(theta), np.cos(theta)]]) mat = np.array([[1,1], [1,1]]) transXs, transYs = mat @ np.array([Xs, Ys]) output_file("lasso_selector.html") TOOLS = "pan,lasso_select,save,reset" source = ColumnDataSource(data=dict(Xs=Xs, Ys=Ys, transXs=transXs, transYs=transYs)) f = figure(tools=TOOLS, title="target", x_range=(-np.pi*np.sqrt(2)-1, np.pi*np.sqrt(2)+1), y_range=(-np.pi*np.sqrt(2)-1, np.pi*np.sqrt(2)+1)) f.circle('Xs', 'Ys', source=source) transf = figure(x_range=f.x_range, y_range=f.y_range, tools=TOOLS, title="trans") transf.circle('transXs', 'transYs', source=source,size=6) grid = gridplot([[f, transf]]) show(column(Div(text="<h2>Transform before and after</h2>"), grid))
def __init__(self, **kwargs): names = ['processes', 'disk-read', 'cores', 'cpu', 'disk-write', 'memory', 'last-seen', 'memory_percent', 'host'] self.source = ColumnDataSource({k: [] for k in names}) columns = {name: TableColumn(field=name, title=name.replace('_percent', ' %')) for name in names} cnames = ['host', 'cores', 'processes', 'memory', 'cpu', 'memory_percent'] formatters = {'cpu': NumberFormatter(format='0.0 %'), 'memory_percent': NumberFormatter(format='0.0 %'), 'memory': NumberFormatter(format='0 b'), 'latency': NumberFormatter(format='0.00000'), 'last-seen': NumberFormatter(format='0.000'), 'disk-read': NumberFormatter(format='0 b'), 'disk-write': NumberFormatter(format='0 b'), 'net-send': NumberFormatter(format='0 b'), 'net-recv': NumberFormatter(format='0 b')} table = DataTable( source=self.source, columns=[columns[n] for n in cnames], ) for name in cnames: if name in formatters: table.columns[cnames.index(name)].formatter = formatters[name] mem_plot = Plot( title=Title(text="Memory Usage (%)"), toolbar_location=None, x_range=Range1d(start=0, end=1), y_range=Range1d(start=-0.1, end=0.1), **kwargs ) mem_plot.add_glyph( self.source, Circle(x='memory_percent', y=0, size=10, fill_alpha=0.5) ) mem_plot.add_layout(LinearAxis(), 'below') hover = HoverTool( point_policy="follow_mouse", tooltips=""" <div> <span style="font-size: 10px; font-family: Monaco, monospace;">@host: </span> <span style="font-size: 10px; font-family: Monaco, monospace;">@memory_percent</span> </div> """ ) mem_plot.add_tools(hover, BoxSelectTool()) if 'sizing_mode' in kwargs: sizing_mode = {'sizing_mode': kwargs['sizing_mode']} else: sizing_mode = {} self.root = column(mem_plot, table, id='bk-worker-table', **sizing_mode)
def modify_doc(doc): plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) slider = Slider(start=0, end=10, value=1, title="bar", css_classes=["foo"], width=300, callback_policy="mouseup") def cbv(attr, old, new): junk['v'] += 1 def cbvt(attr, old, new): junk['vt'] += 1 slider.on_change('value', cbv) slider.on_change('value_throttled', cbvt) doc.add_root(column(slider, plot))
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 __init__(self, worker, height=150, **kwargs): self.worker = worker self.names = ['cpu', 'memory', 'read_bytes', 'write_bytes', 'time'] if not WINDOWS: self.names.append('num_fds') self.source = ColumnDataSource({name: [] for name in self.names}) x_range = DataRange1d(follow='end', follow_interval=20000, range_padding=0) tools = 'reset,pan,wheel_zoom' self.cpu = figure(title="CPU", x_axis_type='datetime', height=height, tools=tools, x_range=x_range, **kwargs) self.cpu.line(source=self.source, x='time', y='cpu') self.cpu.yaxis.axis_label = 'Percentage' self.mem = figure(title="Memory", x_axis_type='datetime', height=height, tools=tools, x_range=x_range, **kwargs) self.mem.line(source=self.source, x='time', y='memory') self.mem.yaxis.axis_label = 'Bytes' self.bandwidth = figure(title='Bandwidth', x_axis_type='datetime', height=height, x_range=x_range, tools=tools, **kwargs) self.bandwidth.line(source=self.source, x='time', y='read_bytes', color='red') self.bandwidth.line(source=self.source, x='time', y='write_bytes', color='blue') self.bandwidth.yaxis.axis_label = 'Bytes / second' # self.cpu.yaxis[0].formatter = NumeralTickFormatter(format='0%') self.bandwidth.yaxis[0].formatter = NumeralTickFormatter(format='0.0b') self.mem.yaxis[0].formatter = NumeralTickFormatter(format='0.0b') plots = [self.cpu, self.mem, self.bandwidth] if not WINDOWS: self.num_fds = figure(title='Number of File Descriptors', x_axis_type='datetime', height=height, x_range=x_range, tools=tools, **kwargs) self.num_fds.line(source=self.source, x='time', y='num_fds') plots.append(self.num_fds) if 'sizing_mode' in kwargs: kw = {'sizing_mode': kwargs['sizing_mode']} else: kw = {} if not WINDOWS: self.num_fds.y_range.start = 0 self.mem.y_range.start = 0 self.cpu.y_range.start = 0 self.bandwidth.y_range.start = 0 self.last = 0 self.root = column(*plots, **kw) self.worker.monitor.update()
def init_panels(data, sensor_names, data_types, dates, node_id): data_sets = {dtype: DataSet(node_id, dtype, sensor_names[dtype], dates) for dtype in data_types} panels = {} for dset in data_sets.values(): dset.get_sources(data) dset.make_plot() dset.cbg.on_click(dset.update_plot) panels[dset.dtype] = Panel(child=column([dset.wb, dset.plot]), title=dset.dtype) return panels
def crossfilter_doc(worker, doc): with log_errors(): statetable = StateTable(worker) crossfilter = CrossFilter(worker) doc.add_periodic_callback(statetable.update, 500) doc.add_periodic_callback(crossfilter.update, 500) doc.add_root(column(statetable.root, crossfilter.root))
def __init__(self): N = 11 self.N = N xs = np.linspace(-np.pi, np.pi, N) ys = xs Xs, Ys = np.meshgrid(xs, ys) self.Xs, self.Ys = Xs.flatten(), Ys.flatten() a, b = 1, 0 c, d = 0, 1 mat = matrix(a, b, c, d) transXs, transYs = mat @ np.array([self.Xs, self.Ys]) TOOLS = "pan,save,reset" self.dic_xs = {"Xs{}".format(step): self.Xs[N*step:N*(step+1)] for step in range(N)} self.dic_ys = {"Ys{}".format(step): self.Ys[N*step:N*(step+1)] for step in range(N)} dic_trasn_xs = {"transXs{}".format( step): transXs[N*step:N*(step+1)] for step in range(N)} dic_trans_ys = {"transYs{}".format( step): transYs[N*step:N*(step+1)] for step in range(N)} data = {**self.dic_xs, **self.dic_ys, **dic_trasn_xs, **dic_trans_ys} colors = Category20[11] self.source = ColumnDataSource(data=data) self.fig = figure(tools=TOOLS, title="target", x_range=(-np.pi*np.sqrt(2)-1, np.pi*np.sqrt(2)+1), y_range=(-np.pi*np.sqrt(2)-1, np.pi*np.sqrt(2)+1)) for s in range(N): eval("""self.fig.scatter('Xs{0}', 'Ys{0}', source=self.source, color=colors[{0}])""".format(s)) self.transfig = figure(tools=TOOLS, title="transformed", x_range=self.fig.x_range, y_range=self.fig.y_range) for s in range(N): eval("""self.transfig.scatter('transXs{0}', 'transYs{0}', source=self.source, color=colors[{0}])""".format(s)) self.a_slider = Slider(title="a", value=a, start=-10, end=10, step=0.1) self.b_slider = Slider(title="b", value=b, start=-10, end=10, step=0.1) self.c_slider = Slider(title="c", value=c, start=-10, end=10, step=0.1) self.d_slider = Slider(title="d", value=d, start=-10, end=10, step=0.1) for widget in [self.a_slider, self.b_slider, self.c_slider, self.d_slider]: widget.on_change('value', self.update_data) box = widgetbox([self.a_slider, self.b_slider, self.c_slider, self.d_slider]) self.plot = column(gridplot([[self.a_slider, self.b_slider], [self.c_slider, self.d_slider]]), gridplot([[self.fig, self.transfig]]))
def workers_doc(scheduler, doc): with log_errors(): table = StateTable(scheduler) occupancy = Occupancy(scheduler, height=200, sizing_mode='scale_width') doc.add_periodic_callback(table.update, 500) doc.add_periodic_callback(occupancy.update, 500) doc.add_root(column(table.root, occupancy.root, sizing_mode='scale_width'))
def systemmonitor_doc(scheduler, doc): with log_errors(): table = StateTable(scheduler) sysmon = SystemMonitor(scheduler, sizing_mode='scale_width') doc.add_periodic_callback(table.update, 500) doc.add_periodic_callback(sysmon.update, 500) doc.add_root(column(table.root, sysmon.root, sizing_mode='scale_width'))
def main(options, args): #logger = log.get_logger("ginga", options=options) logger = log.get_logger("ginga", level=20, log_file="/tmp/ginga.log") #TOOLS = "pan,wheel_zoom,box_select,tap" TOOLS = "box_select" # create a new plot with default tools, using figure fig = figure(x_range=[0, 600], y_range=[0, 600], plot_width=600, plot_height=600, tools=TOOLS) viewer = ib.CanvasView(logger) viewer.set_figure(fig) bd = viewer.get_bindings() bd.enable_all(True) ## box_select_tool = fig.select(dict(type=BoxSelectTool)) ## box_select_tool.select_every_mousemove = True #tap_tool = fig.select_one(TapTool).renderers = [cr] # open a session to keep our local document in sync with server #session = push_session(curdoc()) #curdoc().add_periodic_callback(update, 50) def load_file(path): image = load_data(path, logger=logger) viewer.set_image(image) def load_file_cb(attr_name, old_val, new_val): #print(attr_name, old_val, new_val) load_file(new_val) def zoom_ctl_cb(attr_name, old_val, new_val): if new_val >= 0: new_val += 2 viewer.zoom_to(int(new_val)) scale = viewer.get_scale() logger.info("%f" % scale) viewer.onscreen_message("%f" % (scale), delay=0.3) # add a entry widget and configure with the call back #dstdir = options.indir dstdir = "" path_w = TextInput(value=dstdir, title="File:") path_w.on_change('value', load_file_cb) slide = Slider(start=-20, end=20, step=1, value=1) slide.on_change('value', zoom_ctl_cb) layout = column(fig, path_w, slide) curdoc().add_root(layout) if len(args) > 0: load_file(args[0])
def save(self, title='Training Results'): if len(self.figures) > 0: if os.path.isfile(self.plot_path): os.remove(self.plot_path) output_file(self.plot_path, title=title) plot = column(*self.figures) save(plot) self.clear() self.results.to_csv(self.path, index=False, index_label=False)
def modify_doc(doc): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1], val=["a", "b"])) plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_glyph(source, Circle(x='x', y='y', size=20)) plot.add_tools(CustomAction(callback=CustomJS(args=dict(s=source), code=RECORD("data", "s.data")))) group = RadioButtonGroup(labels=LABELS, css_classes=["foo"]) def cb(active): source.data['val'] = [active, "b"] group.on_click(cb) doc.add_root(column(group, plot))
def 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 modify_doc(doc): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1])) plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_glyph(source, Circle(x='x', y='y', size=20)) plot.add_tools(CustomAction(callback=CustomJS(args=dict(s=source), code=RECORD("data", "s.data")))) button = Button(css_classes=['foo']) def cb(event): source.data=dict(x=[10, 20], y=[10, 10]) button.on_event('button_click', cb) doc.add_root(column(button, plot))
def modify_doc(doc): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1], val=["a", "b"])) plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_glyph(source, Circle(x='x', y='y', size=20)) plot.add_tools(CustomAction(callback=CustomJS(args=dict(s=source), code=RECORD("data", "s.data")))) text_input = TextInput(css_classes=["foo"]) def cb(attr, old, new): source.data['val'] = [old, new] text_input.on_change('value', cb) doc.add_root(column(text_input, plot))
# print('imageInfoList',imageInfoList) fS = create_figure(imageInfoList) # series.children=[ticker1]+[row(p,p2,p1)]+[fS] series.children = [ticker1] + [row(p, p2, column(stats2, p1))] + [fS] return p.on_event(Tap, updateP) p2.on_event(Tap, updateP2) ticker1.on_change('value', ticker1_change) indd = 0 imageInfoList0 = [ d['Metadata_Plate'][indd], d['Metadata_Well'][indd], d['Metadata_FieldID'][indd], d['ObjectNumber'][indd] ] fS = create_figure(imageInfoList0) p.add_tools(hover) p2.add_tools(hover) plotss = row(p, p2, column(stats2, p1)) series = column(children=[ticker1] + [plotss] + [fS]) # series2 = row(children=[widgets]+[fS]) # show(series) # update() curdoc().add_root(series)
rendered_data = renderer.data_source # for new colors on update i = 0 # create a callback that will add a number in a random location, triggered by button to be added later def callback(): global i # BEST PRACTICE --- update .data in one step with a new dict new_data = dict() new_data['x'] = rendered_data.data['x'] + [random() * 70 + 15] new_data['y'] = rendered_data.data['y'] + [random() * 70 + 15] new_data['text_color'] = rendered_data.data['text_color'] + [ RdYlBu3[i % 3] ] new_data['text'] = rendered_data.data['text'] + [str(i)] rendered_data.data = new_data i = i + 1 # add a button widget and configure its click event with the call back button = Button(label="Press Me") button.on_click(callback) # put the button and plot in a layout and add to the document curdoc().add_root(column(button, p))
plot.children[1] = column(create_plots(Estimators)) #lowecase innerscope variables variable1, variable2 = Variable1, Variable2 #Create the widgets drop1 = Select(title="Variable 1", options=list(X.columns.values), value=variable1) drop2 = Select(title="Variable 2", options=list(X.columns.values), value=variable2) drop3 = Select(title="variable 3", options=list(X.columns.values), value=y) estimator_names = [str(estimator).split("(")[0] for estimator in Estimators] estimator_indices = [str(i) for i, name in enumerate(estimator_names)] estimator_select = MultiSelect(title="Estimators", options=estimator_names, value=estimator_names[0:5]) button = Button(label="Update", button_type="success") button.on_click(update) plot = row(widgetbox(drop1, drop2, drop3, estimator_select, button), column(create_plots(Estimators))) curdoc().add_root(plot) curdoc().title = "Wage Data Visualisation"
fill_color=factor_cmap('x', palette=palette, factors=result['genders'], start=1, end=2)) # create a plot and style its properties p.y_range.start = 0 p.x_range.range_padding = 0.025 p.xaxis.major_label_orientation = 1 p.xgrid.grid_line_color = None # create a callback def dropdown_callback(attr, old, new): result = getMedals(new) counts = sum(zip(result['data']['men'], result['data']['women']), ()) p.x_range = FactorRange(*result['range']) r.data_source.data = dict(x=result['range'], counts=counts) # button details, range restrictions for display, with the callback menu = [("1900", "1900"), ("1920", "1920"), ("1950", "1950"), ("1960", "1960"), ("1970", "1970"), ("1980", "1980"), ("1990", "1990"), ("2000", "2000"), ("2010", "2010"), ("2016", "2016")] dropdown = Dropdown(label="Start Year", button_type="warning", menu=menu) dropdown.on_change("value", dropdown_callback) # add button to the graph page curdoc().add_root(column(dropdown, p))
def plot_hist_gantt(sparkdf, start_column, end_column, hist_var, df=pd.DataFrame(), hist_grouped=False, gantt_pooled=False, unit=None): """ Plots histogram and linked Gantt chart of objects in Spark dataframe. :sparkdf: Input Spark dataframe. :param start_column: Start time column name. :param end_column: End time column name. :param hist_var: Histogram variable column name. :df: Pandas dataframe which can be optionally inputed to reduce redundant operations. :param hist_grouped: If True, each bin in the histogram will be a range of values; if False, each bin will be an individual value. :param gantt_pooled: if True, resulting Gantt chart will pool objects; if False, each object will reside on its own horizontal line. :param unit: Unit of timestamps in sparkdf. :return: None. """ if df.empty: df = sparkdf.sort(start_column).toPandas() if unit: df[start_column] = pd.to_datetime(df[start_column], unit=unit) df[end_column] = pd.to_datetime(df[end_column], unit=unit) # Histogram if hist_grouped: bins, counts, df_bins = bokeh_utils.group_hist(df, hist_var) else: bins, counts, df_bins = bokeh_utils.indiv_hist(sparkdf, hist_var) bin_column = 'bin' df[bin_column] = df_bins c0 = ColumnDataSource(data=df) c1 = ColumnDataSource(data=dict(bins=bins, counts=counts)) f1 = figure(title="Distribution of " + hist_var.capitalize() + "s", tools='box_select', height=500, x_range=bins) f1.vbar(source=c1, x='bins', top='counts', width=0.9) bar_width = 37 if hist_grouped else 75 calc_width = lambda h, w: 500 if len(h) < 5 else len(h) * w f1.width = calc_width(counts, bar_width) f1.xaxis.axis_label = hist_var.capitalize() f1.xgrid.grid_line_color = None f1.yaxis.axis_label = 'Count' f1.y_range.start = 0 # Gantt Chart c2 = ColumnDataSource(data={ start_column: [], end_column: [], hist_var: [], 'bottom': [], 'top': [] }) f2 = figure(title='Gantt Chart', tools='box_zoom,reset', width=1000, height=500, x_axis_type='datetime') f2.quad(source=c2, left=start_column, right=end_column, bottom='bottom', top='top') f2.xaxis.axis_label = 'Time' f2.xaxis.formatter = bokeh_utils.gantt_dtf() f2.add_tools( bokeh_utils.gantt_hover_tool(start_column, end_column, hist_var)) quote = bokeh_utils.quote jscode = bokeh_utils.hist_gantt_callback().format( start_column=quote(start_column), end_column=quote(end_column), bin_column=quote(bin_column), hist_var=quote(hist_var), gantt_pooled=str(gantt_pooled).lower()) c1.callback = CustomJS(code=jscode, args=dict(c0=c0, c2=c2, f2=f2)) layout = column(f1, f2) show(layout)
timeslider.value = timeslider.value+inc; console.log(timeslider.value); }, step_length_ms) setTimeout(function(){clearInterval(playback_interval)}, step_length_ms*num_steps) """) playbutton.js_on_click(animateSlider) #################################################### BAR PLOT #################################################### fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries'] counts = [5, 3, 4, 2, 4, 6] barplot = figure(x_range=fruits, plot_height=250, title="Fruit Counts", toolbar_location=None, tools="") barplot.vbar(x=fruits, top=counts, width=0.9) barplot.xgrid.grid_line_color = None barplot.y_range.start = 0 #################################################### LAYOUT AND ADD TO HMTL DOC #################################################### #m_layout = column(p, timeslider, widgetbox(playbutton, width=100), row(barplot)) m_layout = column(p, timeslider, widgetbox(playbutton, width=100)) curdoc().add_root(column(row(m_layout))) curdoc().title = "COVID-19 Dash"
def stack_bar(participation_values, member, labels, metric, choose): """ Creates a stacked bar graph showing percentages of participation for each member for each day/week + hover :param participation_values: Dict{ Member : { date : {'turns': float, 'speak, float } }, Member : ... } :param member: Member who is viewing the report (serves as base of bar stacks). Either.. - member key if no member_names dictionary is given, or - member name if member_names dictionary is given :param labels: List[date1, date2, ..., 'Average'] :param metric: turns' or 'speak' (Whether you want to use Turns or Speaking Time) :param choose: Whether or not to add Date Picker to choose dates :return: bokeh plot """ colors = brewer['Set2'][len(participation_values)] members = {} # To order members data = {} bottoms = {} color_members = {} for date in labels: bottoms[date] = 0 if member: # Order the members so that 'member' is always on the bottom of the stacked bar graph, and so that bars # will always be stacked in the same order. # members is a dictionary, e.g. {'0': 'Member1', '1': 'Member2', etc... } # color_members is a dictionary, e.g. {'Member1': 'color_hex_value_1', 'Member2': 'color_hex_value_2', etc... } i = 1 for member_name in participation_values: if member_name == member: members[str(0)] = member_name color_members[member_name] = colors[0] else: members[str(i)] = member_name color_members[member_name] = colors[i] i += 1 else: i = 0 for member_name in participation_values: members[str(i)] = member_name color_members[member_name] = colors[i] i += 1 total_particip = {'all': 0} for member in participation_values: total_particip[member] = 0 for date in labels: if date in participation_values[member]: particip = participation_values[member][date][metric] else: particip = 0 total_particip[member] += particip total_particip['all'] += particip for member in participation_values: participation_values[member]['Average'] = {} participation_values[member]['Average'][ metric] = total_particip[member] / total_particip['all'] * 100 x = 1 for date in labels: data[date] = {} data[date]['date'] = [] data[date]['x'] = [] data[date]['y'] = [] data[date][metric] = [] data[date]['member'] = [] data[date]['color'] = [] for i in range(len(members)): member = members[str(i)] if date in participation_values[member]: particip = participation_values[member][date][metric] else: particip = 0 data[date]['color'].append(color_members[member]) data[date]['date'].append(date) data[date]['x'].append(x) data[date][metric].append(particip) data[date]['y'].append(bottoms[date] + particip / 2) data[date]['member'].append(member) bottoms[date] += particip x += 1 src_all = {} for date in data: src_all[date] = ColumnDataSource(data=data[date]) source_p_values = ColumnDataSource(data=participation_values) source_colors = ColumnDataSource(data=color_members) source_members = ColumnDataSource(data=members) source_labels = ColumnDataSource(data=dict(labels=labels[:-2])) height = 500 width = 800 if metric == 'turns': hover = HoverTool(tooltips=""" <div> <div> <span style="font-size: 17px; font-weight: bold;">@member</span> </div> <div> <span style="font-size: 17px;">Date: </span> <span style="font-size: 17px; color: purple;">@date</span> </div> <div> <span style="font-size: 17px; font-weight: bold; color: green;">@turns%</span> <span style="font-size: 17px;"> Speaking Turns</span> </div> </div> """) p = figure( title= 'Your Percentage of Participation (Based on Number of Speaking Turns)', plot_width=width, plot_height=height, x_range=[0.5, len(labels) + 0.5], y_range=[-7, 101], tools=[hover], toolbar_location='above', sizing_mode='scale_width') p.yaxis.axis_label = 'Your Percentage of Participation (Speaking Turns)' elif metric == 'speak': hover = HoverTool(tooltips=""" <div> <div> <span style="font-size: 17px; font-weight: bold;">@member</span> </div> <div> <span style="font-size: 17px;">Date: </span> <span style="font-size: 17px; color: purple;">@date</span> </div> <div> <span style="font-size: 17px; font-weight: bold; color: green;">@speak%</span> <span style="font-size: 17px;"> Speaking Time</span> </div> </div> """) p = figure( title= 'Your Percentage of Participation (Based on Amount of Speaking Time)', plot_width=width, plot_height=height, x_range=[0.5, len(labels) + 0.5], y_range=[-15, 101], tools=[hover], toolbar_location='above', sizing_mode='scale_width') p.yaxis.axis_label = 'Your Percentage of Participation (Speaking Time)' legends = [] rects = [] texts = [] dates = data.keys() dates.sort() rect_avg = None for date in dates: rec = p.rect(source=src_all[date], width=.8, height=metric, x='x', y='y', fill_color='color', line_color='white') txt = p.text( source=ColumnDataSource(data={ 'date': [data[date]['date'][0]], 'x': [data[date]['x'][0]] }), text='date', x='x', y=-8, text_align='center', angle=.785) # radians if date == 'Average': rect_avg = rec else: if date != '': rects.append(rec) texts.append(txt) # For legend for member in color_members: sq = p.square(110, 110, size=0, color=color_members[member]) legends.append((member, [sq])) p.grid.grid_line_alpha = 0.4 label_font_style = 'normal' # 'italic', 'bold' p.xaxis.axis_label = 'Date' p.xaxis.axis_label_text_font_size = str(height / 50) + 'pt' p.xaxis.major_label_text_font_size = '0pt' p.xaxis.axis_label_text_font_style = label_font_style p.xaxis.ticker = FixedTicker(ticks=[0]) p.yaxis.major_label_text_font_size = str(height / 50) + 'pt' p.yaxis.axis_label_text_font_size = str(height / 50) + 'pt' p.yaxis.axis_label_text_font_style = label_font_style legend = Legend(legends=legends, location=(0, -30)) p.add_layout(legend, 'right') if choose: date_pickers = [] for i in range(len(labels) - 2): source_i = ColumnDataSource(data={'i': [i]}) if metric == 'turns': cb = CustomJS(args={ 'source_p_values': source_p_values, 'source_colors': source_colors, 'source_labels': source_labels, 'source_members': source_members, 'txt_source': texts[i].data_source, 'source_i': source_i, 'r_source_avg': rect_avg.data_source, 'r_source': rects[i].data_source }, code=""" var d = cb_obj.get('value'); var dMs = Date.parse(d); var dt = new Date(dMs); var day = dt.getDate(); day_str = day.toString(); if (day < 10){ day_str = '0' + day.toString(); }; var month = dt.getMonth() + 1; // Month is 1 less than actual picked month for some reason console.log(month); month_str = month.toString(); if (month < 10) { month_str = '0' + month.toString(); }; var date_str = month_str + '/' + day_str; var labels_data = source_labels.get('data'); var i = source_i.get('data')['i'][0]; labels_data['labels'].splice(i, 1, date_str); var labels = labels_data['labels']; console.log(labels); var p_data = source_p_values.get('data'); var total_turns = {'all': 0}; for (member in p_data) { total_turns[member] = 0; for (index in labels) { var turns = 0; var date = labels[index]; console.log(p_data[member]); if (date in p_data[member]) { turns = p_data[member][date]['turns']; } console.log(turns); total_turns[member] += turns; total_turns['all'] += turns; console.log(total_turns[member]); console.log(total_turns['all']); } } for (member in p_data) { p_data[member]['Average'] = {}; console.log(total_turns[member]); p_data[member]['Average']['turns'] = total_turns[member] / total_turns['all'] * 100; } var colors = source_colors.get('data'); var members = source_members.get('data'); new_data = {} bottom = 0 new_data['date'] = [] new_data['y'] = [] new_data['turns'] = [] new_data['member'] = [] new_data['color'] = [] for (i=0; i<Object.keys(members).length; i++){ member = members[i.toString()]; var turns = 0; if (date_str in p_data[member]) { turns = p_data[member][date_str]['turns']; }; new_data['color'].push(colors[member]); new_data['date'].push(date_str); new_data['turns'].push(turns); new_data['y'].push(bottom + turns/2); new_data['member'].push(member); bottom += turns; } new_avg_data = {} bottom = 0 new_avg_data['date'] = [] new_avg_data['y'] = [] new_avg_data['turns'] = [] new_avg_data['member'] = [] new_avg_data['color'] = [] for (i=0; i<Object.keys(members).length; i++){ member = members[i.toString()]; turns = p_data[member]['Average']['turns']; new_avg_data['color'].push(colors[member]); new_avg_data['date'].push('Average'); new_avg_data['turns'].push(turns); new_avg_data['y'].push(bottom + turns/2); new_avg_data['member'].push(member); bottom += turns; } var r_data = r_source.get('data'); var r_avg_data = r_source_avg.get('data'); var txt_data = txt_source.get('data'); for (key in new_data) { r_data[key] = new_data[key]; txt_data[key] = new_data[key]; r_avg_data[key] = new_avg_data[key]; } console.log(r_avg_data); r_source.trigger('change'); r_source_avg.trigger('change'); txt_source.trigger('change'); """) elif metric == 'speak': cb = CustomJS(args={ 'source_p_values': source_p_values, 'source_colors': source_colors, 'source_labels': source_labels, 'source_members': source_members, 'txt_source': texts[i].data_source, 'source_i': source_i, 'r_source_avg': rect_avg.data_source, 'r_source': rects[i].data_source }, code=""" var d = cb_obj.get('value'); var dMs = Date.parse(d); var dt = new Date(dMs); var day = dt.getDate(); day_str = day.toString(); if (day < 10){ day_str = '0' + day.toString(); }; var month = dt.getMonth() + 1; // Month is 1 less than actual picked month for some reason console.log(month); month_str = month.toString(); if (month < 10) { month_str = '0' + month.toString(); }; var date_str = month_str + '/' + day_str; var labels_data = source_labels.get('data'); var i = source_i.get('data')['i'][0]; labels_data['labels'].splice(i, 1, date_str); var labels = labels_data['labels']; console.log(labels); var p_data = source_p_values.get('data'); var total_turns = {'all': 0}; for (member in p_data) { total_turns[member] = 0; for (index in labels) { var turns = 0; var date = labels[index]; console.log(p_data[member]); if (date in p_data[member]) { turns = p_data[member][date]['speak']; } console.log(turns); total_turns[member] += turns; total_turns['all'] += turns; console.log(total_turns[member]); console.log(total_turns['all']); } } for (member in p_data) { p_data[member]['Average'] = {}; console.log(total_turns[member]); p_data[member]['Average']['speak'] = total_turns[member] / total_turns['all'] * 100; } var colors = source_colors.get('data'); var members = source_members.get('data'); new_data = {} bottom = 0 new_data['date'] = [] new_data['y'] = [] new_data['speak'] = [] new_data['member'] = [] new_data['color'] = [] for (i=0; i<Object.keys(members).length; i++){ member = members[i.toString()]; var turns = 0; if (date_str in p_data[member]) { turns = p_data[member][date_str]['speak']; }; new_data['color'].push(colors[member]); new_data['date'].push(date_str); new_data['speak'].push(turns); new_data['y'].push(bottom + turns/2); new_data['member'].push(member); bottom += turns; } new_avg_data = {} bottom = 0 new_avg_data['date'] = [] new_avg_data['y'] = [] new_avg_data['speak'] = [] new_avg_data['member'] = [] new_avg_data['color'] = [] for (i=0; i<Object.keys(members).length; i++){ member = members[i.toString()]; turns = p_data[member]['Average']['speak']; new_avg_data['color'].push(colors[member]); new_avg_data['date'].push('Average'); new_avg_data['speak'].push(turns); new_avg_data['y'].push(bottom + turns/2); new_avg_data['member'].push(member); bottom += turns; } var r_data = r_source.get('data'); var r_avg_data = r_source_avg.get('data'); var txt_data = txt_source.get('data'); for (key in new_data) { r_data[key] = new_data[key]; txt_data[key] = new_data[key]; r_avg_data[key] = new_avg_data[key]; } console.log(r_avg_data); r_source.trigger('change'); r_source_avg.trigger('change'); txt_source.trigger('change'); """) m = int(labels[i].split('/')[0]) d = int(labels[i].split('/')[1]) date_pickers.append( DatePicker(title='Day ' + str(i + 1), min_date=datetime.datetime(2016, 6, 1), max_date=datetime.datetime.now(), value=datetime.datetime( datetime.datetime.now().year, m, d), callback=cb, width=width / 5, height=200)) return column(children=[p, row(children=date_pickers)], sizing_mode='scale_width') else: return p
def Rips_Filter_Bifiltration(filtered_points, radius_range, palette="Viridis256", FilterName="Filter", maxind: int = None, dim: int = None): if maxind is None: maxind = 5 if dim is None: dim = 0 points = filtered_points[:, :2] filter = filtered_points[:, 2] alpha = np.ones(filter.shape) * 0.3 exp_cmap = LinearColorMapper(palette=palette, low=radius_range[0], high=radius_range[1]) source = ColumnDataSource( data=dict(x=points[:, 0], y=points[:, 1], sizes=(radius_range[0] + radius_range[1]) / 4 * np.ones(points.shape[0]), filter=filter, alpha=alpha)) vline = ColumnDataSource( data=dict(c=[radius_range[0]], y=[0], angle=[np.pi / 2])) hline = ColumnDataSource(data=dict(s=[radius_range[0]], x=[0], angle=[0])) filter_plot = figure(title='Filtration', plot_width=360, plot_height=430, min_border=0, toolbar_location=None, match_aspect=True) glyph = Circle(x="x", y="y", radius="sizes", line_color="black", fill_color={ 'field': 'filter', 'transform': exp_cmap }, fill_alpha="alpha", line_width=1, line_alpha="alpha") filter_plot.add_glyph(source, glyph) filter_plot.add_layout( ColorBar(color_mapper=exp_cmap, location=(0, 0), orientation="horizontal"), "below") rips_callback = CustomJS(args=dict(source=source, hline=hline), code=""" var data = source.data; var s = cb_obj.value var sizes = data['sizes'] for (var i = 0; i < sizes.length; i++) { sizes[i] = s/2 } var hdata = hline.data; var step = hdata['s'] step[0] = s hline.change.emit(); source.change.emit(); """) filter_callback = CustomJS(args=dict(source=source, vline=vline), code=""" var data = source.data; var c = cb_obj.value var alpha = data['alpha'] var filter = data['filter'] for (var i = 0; i<filter.length; i++){ if(filter[i]>c){ alpha[i] = 0 } if(filter[i]<=c){ alpha[i] = 0.3 } } var vdata = vline.data; var step = vdata['c'] step[0] = c vline.change.emit(); source.change.emit(); """) rips_slider = Slider(start=radius_range[0], end=radius_range[1], value=(radius_range[0] + radius_range[1]) / 2, step=(radius_range[1] - radius_range[0]) / 100, title="Rips", orientation="vertical", height=300, direction="rtl", margin=(10, 40, 10, 60)) rips_slider.js_on_change('value', rips_callback) filter_slider = Slider(start=radius_range[0], end=radius_range[1], value=radius_range[1], step=(radius_range[1] - radius_range[0]) / 100, title=FilterName, orientation="horizontal", aspect_ratio=10, width_policy="auto", direction="ltr", width=300, margin=(10, 10, 10, 40)) filter_slider.js_on_change('value', filter_callback) # Run Rivet and Landscape Computation # computed_data = Compute_Rivet(filtered_points, resolution=50, dim=dim, RipsMax=radius_range[1]) multi_landscape = multiparameter_landscape( computed_data, grid_step_size=(radius_range[1] - radius_range[0]) / 100, bounds=[[radius_range[0], radius_range[0]], [radius_range[1], radius_range[1]]], maxind=maxind) TOOLTIPS = [(FilterName, "$x"), ("Radius", "$y"), ("Landscape_Value", "@image")] landscape_plots = plot_multiparameter_landscapes( multi_landscape, indices=[1, maxind], TOOLTIPS=TOOLTIPS, x_axis_label=FilterName, y_axis_label="Rips Parameter") for plot in landscape_plots.children: plot.ray(x="c", y="y", length="y", angle="angle", source=vline, color='white', line_width=2, alpha=0.5) plot.ray(x="x", y="s", length="x", angle="angle", source=hline, color='white', line_width=2, alpha=0.5) layout = column(row(rips_slider, column(filter_plot, filter_slider)), row(landscape_plots), sizing_mode="scale_both") return layout
def generate_results_table(yc_results, yc_fastest_lap_data, year_results, year_fastest_lap_data, year_only=False, height=None, include_driver_name=True, include_constructor_name=False): """ Generates a table of results at each race, including quali position, finish position (or reason for DNF), time, gap to leader, fastest lap time and gap to fastest lap (of all drivers), average lap time and gap to fastest average lap time (of all drivers). :param yc_results: YC results :param yc_fastest_lap_data: YC fastest lap data :param year_results: Year results :param year_fastest_lap_data: Year fastest lap data :param year_only: Whether to set the race name row to just the year :param height: Plot height :param include_driver_name: If True, will include a driver name column :param include_constructor_name: If True, will include a constructor name column :return: Table layout, source """ # TODO this might be able to be refactored with yeardriver or year, but it is kind of unique logging.info("Generating results table") source = pd.DataFrame(columns=["race_name", "driver_name", "driver_id ", "race_id", "year", "constructor_name", "quali_pos_str", "finish_pos_str", "time_str", "fastest_lap_time_str", "avg_lap_time_str"]) for idx, results_row in yc_results.sort_values(by=["raceId", "driverId"]).iterrows(): rid = results_row["raceId"] driver_id = results_row["driverId"] constructor_id = results_row["constructorId"] driver_name = get_driver_name(driver_id) constructor_name = get_constructor_name(constructor_id) race_results = year_results[year_results["raceId"] == rid] race_fastest_lap_data = year_fastest_lap_data[year_fastest_lap_data["raceId"] == rid] race_driver_fastest_lap_data = yc_fastest_lap_data[(yc_fastest_lap_data["raceId"] == rid) & (yc_fastest_lap_data["driver_id"] == driver_id)] race_name = get_race_name(rid) grid = results_row["grid"] if grid == -1: quali_pos_str = "DNQ" else: quali_pos_str = int_to_ordinal(grid) status_id = results_row["statusId"] finish_pos_str, finish_pos = result_to_str(results_row["positionOrder"], status_id) time = results_row["milliseconds"] winner = race_results[race_results["positionOrder"] == 1] if winner.shape[0] > 0 and winner["driverId"].values[0] != driver_id \ and not np.isnan(time) and not np.isnan(results_row["position"]): time_gap = millis_to_str(time - winner["milliseconds"].values[0]) time_str = millis_to_str(time) + " (+" + time_gap + ")" if status_id != 1 and get_status_classification(status_id) == "finished": time_str = millis_to_str(time) + " (+" + time_gap + ", " + status.loc[status_id, "status"] + ")" elif finish_pos == 1: time_str = millis_to_str(time) else: time_str = "Not Set" if race_driver_fastest_lap_data.shape[0] > 0: fastest_lap_time = race_driver_fastest_lap_data["fastest_lap_time_millis"].values[0] fastest_lap_time_str = millis_to_str(fastest_lap_time) if race_driver_fastest_lap_data["rank"].values[0] == " 1": fastest_lap_time_str = fastest_lap_time_str + " (Fastest)" else: fastest_time = race_fastest_lap_data[race_fastest_lap_data["rank"] == " 1"]["fastest_lap_time_millis"] if fastest_time.shape[0] > 0 and not np.isnan(fastest_lap_time): fastest_time = fastest_time.values[0] fastest_gap = millis_to_str(fastest_lap_time - fastest_time) fastest_lap_time_str = millis_to_str(fastest_lap_time) + " (+" + fastest_gap + ")" if fastest_lap_time_str == "": fastest_lap_time_str = "Not Set" fastest_avg_idx = race_fastest_lap_data["avg_lap_time_millis"].idxmin() avg_lap_time = race_driver_fastest_lap_data["avg_lap_time_millis"].values[0] if np.isnan(avg_lap_time): avg_lap_time_str = "Not Set" elif race_fastest_lap_data.loc[fastest_avg_idx, "driver_id"] == driver_id or np.isnan(avg_lap_time): avg_lap_time_str = millis_to_str(avg_lap_time) + " (Fastest Avg.)" else: fastest_avg_time = race_fastest_lap_data.loc[fastest_avg_idx, "avg_lap_time_millis"] avg_gap = millis_to_str(avg_lap_time - fastest_avg_time) avg_lap_time_str = millis_to_str(avg_lap_time) + " (+" + avg_gap + ")" else: fastest_lap_time_str = "Not Set" avg_lap_time_str = "Not Set" source = source.append({ "race_name": race_name, "race_id": rid, "driver_name": driver_name, "driver_id": driver_id, "constructor_name": constructor_name, "year": races.loc[rid, "year"], "quali_pos_str": quali_pos_str, "finish_pos_str": finish_pos_str, "time_str": time_str, "fastest_lap_time_str": fastest_lap_time_str, "avg_lap_time_str": avg_lap_time_str }, ignore_index=True) source = source.sort_values(by="year", ascending=False) results_columns = [ TableColumn(field="quali_pos_str", title="Grid Pos.", width=75), TableColumn(field="finish_pos_str", title="Finish Pos.", width=75), TableColumn(field="time_str", title="Time", width=100), TableColumn(field="fastest_lap_time_str", title="Fastest Lap Time", width=75), TableColumn(field="avg_lap_time_str", title="Avg. Lap Time", width=75), ] if include_driver_name: results_columns.insert(0, TableColumn(field="driver_name", title="Driver Name", width=100)) if include_constructor_name: results_columns.insert(0, TableColumn(field="constructor_name", title="Constructor Name", width=100)) if year_only: results_columns.insert(0, TableColumn(field="year", title="Year", width=50)) else: results_columns.insert(0, TableColumn(field="race_name", title="Race Name", width=100)) results_table = DataTable(source=ColumnDataSource(data=source), columns=results_columns, index_position=None, height=28 * yc_results.shape[0] if height is None else height) title = Div(text=f"<h2><b>Results for each race</b></h2><br><i>The fastest lap time and average lap time gaps " f"shown are calculated based on the gap to the fastest of all drivers and fastest average of " f"all drivers in that race respectively.</i>") return column([title, row([results_table], sizing_mode="stretch_width")], sizing_mode="stretch_width"), source
def compare_multiparameter_landscape_samples( Samples: List[List[multiparameter_landscape]], indices=None, TOOLTIPS=None, GroupLabels: List[str] = None, colors: List[str] = None): """ Plots the mean landscapes of each collection to a single axes in range index = [ind_min,ind_max] together with a boxplot comparing the distribution of the functional values yielded by integrating the landscapes over a user specified range :param Samples: List List of lists of multiparameter_landscape objects so Sample[k][i] contains the i^th multiparameter landscape from the k^th Sample Group. All multiparameter landscapes are assumed to have the same bounds as Samples[0][0]. :param indices: The range of indices to be plotted :param TOOLTIPS: A bokeh TOOLTIPS list to control features that can be probed in the plot :param GroupLabels: A list of the names of the Sample Groups :param colors: A list of the colors for the Sample Groups """ for k in range(len(Samples)): if not (Samples[k][0].bounds.lower_left == Samples[0][0].bounds.lower_left and Samples[k][0].bounds.upper_right == Samples[0][0].bounds.upper_right): raise TypeError( 'Inconsistent bounds for landscapes in Sample List') for i in range(len(Samples[k])): if not (Samples[k][i].bounds.lower_left == Samples[0][0].bounds.lower_left and Samples[k][i].bounds.upper_right == Samples[0][0].bounds.upper_right): raise TypeError( 'Inconsistent bounds for landscapes in Sample List') for k in range(len(Samples)): if not (Samples[k][0].weight == Samples[0][0].weight).all(): raise TypeError( 'Inconsistent weights for landscapes in Sample List') for i in range(len(Samples[k])): if not (Samples[k][i].weight == Samples[k][0].weight).all(): raise TypeError( 'Inconsistent weights for landscapes in Sample List') for k in range(len(Samples)): if not Samples[k][0].grid_step_size == Samples[0][0].grid_step_size: raise TypeError( 'Inconsistent grid step size for landscapes in Sample List') for i in range(len(Samples[k])): if not Samples[k][i].grid_step_size == Samples[k][0].grid_step_size: raise TypeError( 'Inconsistent grid step size for landscapes in Sample List' ) if indices is None: indices = [1, Samples[0][0].maximum_landscape_depth] elif type(indices[0]) is int and type(indices[1]) is int and \ (indices[1] <= Samples[0][0].maximum_landscape_depth): indices = indices else: raise TypeError( 'Index range must provide integer values no bigger that the landscape depth' ) if TOOLTIPS is None: TOOLTIPS = [("x", "$x"), ("y", "$y"), ("value", "@image")] if GroupLabels is None: GroupLabels = ['Group ' + str(s + 1) for s in range(len(Samples)) ] * (indices[1] - indices[0] + 1) else: if not len(GroupLabels) == len(Samples): raise TypeError( 'GroupLabels list is not the same length as the sample list') GroupLabels = GroupLabels * (indices[1] - indices[0] + 1) if colors is None: colors = [ 'plum', 'powderblue', 'gold', 'greenyellow', 'mediumblue', 'firebrick' ] else: if not len(colors) == len(Samples): raise TypeError( 'Color list is not the same length as the sample list') bounds = Samples[0][0].bounds grid_step_size = Samples[0][0].grid_step_size weight = Samples[0][0].weight ###################### # Define ColumnDataSources # rectangle_source = ColumnDataSource( data=dict(x=[(bounds.lower_left[0] + bounds.upper_right[0]) / 2], y=[(bounds.lower_left[1] + bounds.upper_right[1]) / 2], width=[bounds.upper_right[0] - bounds.lower_left[0]], height=[bounds.upper_right[1] - bounds.lower_left[1]])) rect = Rect( x='x', y='y', width='width', height='height', fill_alpha=0.2, fill_color='white', line_color='white', ) landscape_properties = ColumnDataSource(data=dict( bounds=[[bounds.lower_left, bounds.upper_right]], x_steps=[ int( round((bounds.upper_right[0] - bounds.lower_left[0]) / grid_step_size * weight[1] + 1)) ], y_steps=[ int( round((bounds.upper_right[1] - bounds.lower_left[1]) / grid_step_size * weight[0] + 1)) ], indices=[indices])) boxplot_source = ColumnDataSource( data=dict(cats=[ "Group " + str(s + 1) + ", k=" + str(k + 1) for k in range(indices[0] - 1, indices[1]) for s in range(len(Samples)) ], colors=[ colors[s] for _ in range(indices[0] - 1, indices[1]) for s in range(len(Samples)) ], q1=[-1] * (len(Samples) * (indices[1] - indices[0] + 1)), q2=[0] * (len(Samples) * (indices[1] - indices[0] + 1)), q3=[1] * (len(Samples) * (indices[1] - indices[0] + 1)), lower=[-2] * (len(Samples) * (indices[1] - indices[0] + 1)), upper=[2] * (len(Samples) * (indices[1] - indices[0] + 1)), labels=GroupLabels)) ###################### # Callback Functions # rotated_samples = [ rotate_stack(stack_landscapes(Samples[s])) for s in range(len(Samples)) ] callback_x = CustomJS(args=dict(rectangle_source=rectangle_source, lp=landscape_properties, bp=boxplot_source, samples=rotated_samples), code=""" function Find_Median(list) { var Size = list.length; list = Array.from(list).sort(function(a, b) { return a - b }); console.log('sorted') console.log(list) var Final_Number = 0; var HalfWay = 0; if (Size % 2 == 0) { HalfWay = Math.round((list.length) / 2)-1; console.log('Halfway index') console.log(HalfWay) var Value1 = list[HalfWay]; var Value2 = list[HalfWay + 1]; console.log('Value1') console.log(Value1) console.log('Value2') console.log(Value2) var Number = Value1 + Value2; Final_Number = Number / 2; console.log('Final_Number') console.log(Final_Number) } else { HalfWay = Math.round(list.length / 2)-1; console.log('Halfway index') console.log(HalfWay) Final_Number = list[HalfWay]; console.log('Final_Number') console.log(Final_Number) } console.log('Final_Number') console.log(Final_Number) return Final_Number; } function BiggerElements(val) { return function(evalue, index, array) { return (evalue >= val); }; } function SmallerElements(val) { return function(evalue, index, array) { return (evalue <= val); }; } var data = rectangle_source.data; var xrange = cb_obj.value data['x'] = [(xrange[0]+xrange[1])/2] data['width'] = [(xrange[1]-xrange[0])] rectangle_source.change.emit(); var bpdata = bp.data; var ylow = data['y'][0] - data['height'][0]/2; var yhigh = data['y'][0] + data['height'][0]/2; var a = Math.round(Math.PI) var bounds = lp.data['bounds'][0]; var x_steps = lp.data['x_steps']; var y_steps = lp.data['y_steps']; var indices = lp.data['indices'][0]; var xmin = Math.round(xrange[0]/ bounds[1][0]* x_steps[0]); var xmax = Math.round(xrange[1]/ bounds[1][0]* x_steps[0]); var ymin = Math.round(ylow/ bounds[1][1]* y_steps[0]); var ymax = Math.round(yhigh/ bounds[1][1]* y_steps[0]); var q1 = bpdata['q1'] var q2 = bpdata['q2'] var q3 = bpdata['q3'] var lower = bpdata['lower'] var upper = bpdata['upper'] var number_of_samples = samples.length console.log("number_of_samples") console.log(number_of_samples) console.log(samples[0]) console.log(samples[0].length) for (var s = 0; s < number_of_samples; s++ ) { for (var k = 0; k < indices[1]-indices[0]+1 ; k++ ) { console.log("Index") console.log(k) console.log('samples[s].length') console.log(samples[s].length) var holder = Array.from(Array(samples[s].length), () => 0) console.log('holder') console.log(holder) for (var l = 0; l < samples[s].length; l++ ) { console.log("Sample") console.log(l) var value = 0 for (var i = xmin; i < xmax; i++) { for (var j = ymin; j < ymax ; j++) { value += samples[s][l][k][j][i] } } console.log('value') console.log(value) holder[l] = value / (x_steps * y_steps) } console.log('holder') console.log(holder) console.log('Median') console.log(Find_Median(holder)) console.log('Median^') q2[number_of_samples*k + s] = Find_Median(holder) q1[number_of_samples*k + s] = Find_Median(holder.filter(SmallerElements(Find_Median(holder)))) q3[number_of_samples*k + s] = Find_Median(holder.filter(BiggerElements(Find_Median(holder)))) lower[number_of_samples*k + s] = Math.min.apply(Math,holder) upper[number_of_samples*k + s] = Math.max.apply(Math,holder) } } console.log('q2') console.log(q2) bp.change.emit() """) callback_y = CustomJS(args=dict(rectangle_source=rectangle_source, lp=landscape_properties, bp=boxplot_source, samples=rotated_samples), code=""" function Find_Median(list) { var Size = list.length; list = Array.from(list).sort(function(a, b) { return a - b }); console.log('sorted') console.log(list) var Final_Number = 0; var HalfWay = 0; if (Size % 2 == 0) { HalfWay = Math.round((list.length) / 2)-1; console.log('Halfway index') console.log(HalfWay) var Value1 = list[HalfWay]; var Value2 = list[HalfWay + 1]; console.log('Value1') console.log(Value1) console.log('Value2') console.log(Value2) var Number = Value1 + Value2; Final_Number = Number / 2; console.log('Final_Number') console.log(Final_Number) } else { HalfWay = Math.round(list.length / 2)-1; console.log('Halfway index') console.log(HalfWay) Final_Number = list[HalfWay]; console.log('Final_Number') console.log(Final_Number) } console.log('Final_Number') console.log(Final_Number) return Final_Number; } function BiggerElements(val) { return function(evalue, index, array) { return (evalue >= val); }; } function SmallerElements(val) { return function(evalue, index, array) { return (evalue <= val); }; } var data = rectangle_source.data; var yrange = cb_obj.value data['y'] = [(yrange[0]+yrange[1])/2] data['height'] = [(yrange[1]-yrange[0])] rectangle_source.change.emit(); var bpdata = bp.data; var bounds = lp.data['bounds'][0]; var x_steps = lp.data['x_steps']; var y_steps = lp.data['y_steps']; var indices = lp.data['indices'][0]; var xlow = data['x'][0] - data['width'][0]/2; var xhigh = data['x'][0] + data['width'][0]/2; var x_steps = lp.data['x_steps']; var y_steps = lp.data['y_steps']; var xmin = Math.round(xlow/ bounds[1][0]* x_steps[0]); var xmax = Math.round(xhigh/ bounds[1][0]* x_steps[0]); var ymin = Math.round(yrange[0]/ bounds[1][1]* y_steps[0]); var ymax = Math.round(yrange[1]/ bounds[1][1]* y_steps[0]); var q1 = bpdata['q1'] var q2 = bpdata['q2'] var q3 = bpdata['q3'] var lower = bpdata['lower'] var upper = bpdata['upper'] var number_of_samples = samples.length console.log("number_of_samples") console.log(number_of_samples) console.log(samples[0]) console.log(samples[0].length) for (var s = 0; s < number_of_samples; s++ ) { for (var k = 0; k < indices[1]-indices[0]+1 ; k++ ) { console.log("Index") console.log(k) console.log('samples[s].length') console.log(samples[s].length) var holder = Array.from(Array(samples[s].length), () => 0) console.log('holder') console.log(holder) for (var l = 0; l < samples[s].length; l++ ) { console.log("Sample") console.log(l) var value = 0 for (var i = xmin; i < xmax; i++) { for (var j = ymin; j < ymax ; j++) { value += samples[s][l][k][j][i] } } console.log('value') console.log(value) holder[l] = value / (x_steps * y_steps) } console.log('holder') console.log(holder) console.log('Median') console.log(Find_Median(holder)) console.log('Median^') q2[number_of_samples*k + s] = Find_Median(holder) q1[number_of_samples*k + s] = Find_Median(holder.filter(SmallerElements(Find_Median(holder)))) q3[number_of_samples*k + s] = Find_Median(holder.filter(BiggerElements(Find_Median(holder)))) lower[number_of_samples*k + s] = Math.min.apply(Math,holder) upper[number_of_samples*k + s] = Math.max.apply(Math,holder) } } console.log('q2') console.log(q2) bp.change.emit() """) ######################### # Widgets and callbacks # x_range_slider = RangeSlider(start=bounds.lower_left[0], end=bounds.upper_right[0], value=(bounds.lower_left[0], bounds.upper_right[0]), step=.1, title="x_range", width=300) y_range_slider = RangeSlider(start=bounds.lower_left[1], end=bounds.upper_right[1], value=(bounds.lower_left[1], bounds.upper_right[1]), step=.1, title="y_range", width=300) x_range_slider.js_on_change('value', callback_x) y_range_slider.js_on_change('value', callback_y) ######################### # Make Plots # mean_landscape_plots = [] for s in range(len(Samples)): mean_landscape = compute_mean_landscape(Samples[s]) row_of_plots = plot_multiparameter_landscapes(mean_landscape, indices, TOOLTIPS=TOOLTIPS) row_of_plots.sizing_mode = "scale_both" mean_landscape_plots.append(row_of_plots) for plot in row_of_plots.children: plot.add_glyph(rectangle_source, rect) plot.plot_height = 250 plot.plot_width = 250 plot.border_fill_color = colors[s] plot.min_border = 15 boxplots = figure(x_range=boxplot_source.data['cats'], height=250) # stems boxplots.segment(source=boxplot_source, x0='cats', y0='upper', x1='cats', y1='q3', color="black") boxplots.segment(source=boxplot_source, x0='cats', y0='lower', x1='cats', y1='q1', color="black") # boxes boxplots.vbar(source=boxplot_source, x='cats', top='q3', bottom='q2', width=0.5, fill_color='colors', line_color='black', legend_group='labels') boxplots.vbar(source=boxplot_source, x='cats', top='q2', bottom='q1', width=0.5, fill_color='colors', line_color='black') # whiskers boxplots.rect(source=boxplot_source, x='cats', y='lower', width=0.2, height=0.000001, color='black') boxplots.rect(source=boxplot_source, x='cats', y='upper', width=0.2, height=0.000001, color='black') boxplots.legend.glyph_width = 50 boxplots.legend.glyph_height = 20 boxplots.legend.label_text_font_size = '10pt' boxplots.xgrid.grid_line_color = None boxplots.sizing_mode = "scale_both" # ########################## # # Layout and Show Plot # sliders = column([x_range_slider, y_range_slider]) DOM = column(column(mean_landscape_plots), sliders, boxplots) return DOM
def update_data(attrname, old, new): slope_angle = float(slope_slider.value) slope = np.tan(slope_angle / 180 * np.pi) intercept = intercept_slider.value x = source.data['x'] y = source.data['y'] error_colors = source.data['color'] # print(slope) # 更新预测信息和残差线 pred = slope * x + intercept error_0s = list(zip(x, x)) error_1s = list(zip(y, pred)) # 更新方差信息 error_index = range(len(X)) error_value = np.power((pred - y), 2) source.data.update(dict(x=x, y=y, pred=pred, error_0s=error_0s, \ error_1s=error_1s, error_index=error_index, error_value=error_value, \ color=error_colors)) for w in [slope_slider, intercept_slider]: w.on_change("value", update_data) # setup layouts and add to documents inputs = column(slope_slider, intercept_slider, height=200) curdoc().add_root(row(plot, column(inputs, var_plot, height=600), width=800))
def plot_returns_stack(rolling_window,factors_to_plot): result_array = np.zeros((1,len(factors_to_plot)+1)) # Initializing the results array factors1 = factors_to_plot + ['Alpha'] X = df[factors_to_plot].values Y = (df['Daily_Returns']-df[factor_riskfree[0]]).values # Calculating Excess Daily returns by subtracting Risk free returns dates = df['Date'].values for i in range(X.shape[0]-rolling_window+1): #Loop to do regression for each time period of rolling window x = X[i:rolling_window+i] # The X variables for regression based on rolling window y = Y[i:rolling_window+i] # The Y variable for regression based on rolling window regressor = LinearRegression().fit(x, y) # Doing the linear regression temp = np.append(regressor.coef_,regressor.intercept_) # Constructing the results of the regression numpy arrray by appending the alpha to the betas result_array = np.vstack((result_array, np.resize(temp,(1,len(factors_to_plot)+1)))) # Appending the Results of regression to result_array result_array = np.delete(result_array, 0, 0) # Deleing the first initialized row of the result_array dates = dates[rolling_window-1:] # Determing the dates of all the days on which rolling window regression is done result_df = pd.DataFrame(result_array.round(decimals=2), index=dates) # Values rounded to make the plots of beta result_df.columns = factors1 # To insert date column in the result_df dataframe df3 = pd.DataFrame(data=list(dates), columns=['int_date']) df3[['str_date']] = df3[['int_date']].applymap(str).applymap(lambda s: "{}-{}-{}".format(s[0:4], s[4:6], s[6:] )) rolling_dates=list(df3['str_date']) # df[['str_date']] = df[['int_date']].applymap(str).applymap(lambda s: "{}/{}/{}".format(s[6:], s[4:6], s[0:4])) dates = np.array(rolling_dates, dtype=np.datetime64) result_df.insert(loc=0, column='Date', value=dates) rolling_ndays = len(dates) # result_df.insert(loc=0, column='Date', value=list(df['str_date'])) betas = result_array[:,0:len(factors_to_plot)] alphas = result_array[:,-1] factor_values = df[factors_to_plot].values[rolling_window-1:,:] returns = (df['Daily_Returns']-df[factor_riskfree[0]]).values[rolling_window-1:] daily_att = (factor_values)*(betas) factor_returns = np.column_stack((daily_att,returns-daily_att.sum(axis=1))) factor_returns=factor_returns.cumsum(axis=0) factor_returns_df = pd.DataFrame(factor_returns, index=dates) # Values rounded to make the plots of beta factor_returns_df.columns = factors1 numlines=len(factors_to_plot) mypalette=Spectral11[:4]+Spectral11[8:] source = ColumnDataSource(factor_returns_df) tooltips=[ ( 'Date', '$x{%F}'), ] f=figure(title = f'Cumulative Returns - Factorwise Rolling: {rolling_window} days window', plot_height=550, plot_width=1500, x_axis_location="above", toolbar_location='above',x_axis_type="datetime", background_fill_color="#efefef", x_range=(dates[(rolling_ndays)//3], dates[((rolling_ndays)*2)//3]), tooltips=tooltips) # select2 = figure(title="Drag the middle and edges of the selection box to change the range above", plot_height=140, plot_width=1500, y_range=f.y_range, x_axis_type="datetime", y_axis_type=None, tools="", toolbar_location=None, background_fill_color="#efefef") f.varea_stack(stackers=factors1, x='index', color=tuple(mypalette[0:numlines+1]), source=factor_returns_df, alpha = 0.85, legend_label=factors1) f.legend.click_policy="hide" f.legend.background_fill_alpha = 0 f.legend.border_line_color = None f.legend.margin = 10 f.legend.padding = 18 f.legend.spacing = 10 f.toolbar.logo = None f.title.text_color = mypalette[-1] f.title.text_alpha = 0.6 f.title.text_font = "antiqua" f.title.text_font_size = "32px" f.title.align = "center" f.yaxis.axis_label = '%age Returns ITD' f.yaxis.axis_label_text_font_size= "18px" f.axis.major_label_text_font_size = '16px' f.legend.label_text_font_size = '16px' range_tool = RangeTool(x_range=f.x_range) range_tool.overlay.fill_color = "navy" range_tool.overlay.fill_alpha = 0.2 select2.varea_stack(stackers=factors1, x='index', color=tuple(mypalette[0:numlines+1]), source=factor_returns_df, alpha = 0.85) select2.ygrid.grid_line_color = None select2.add_tools(range_tool) select2.toolbar.active_multi = range_tool return column(f,select2)
step=0.1) # Set up callbacks def update_data(attrname, old, new): # Get the current slider values mn = mn_values_slider.value # Generate the new curve xtrib = tribs['m_over_n = %s' % mn] #.values ytrib = tribs.elevation #.values desc = tribs['MLE m/n %s' % mn] xms = main_stem['m_over_n = %s' % mn] #.values yms = main_stem.elevation #.values colors = color_maker(tribs, mn) source_ms.data = dict(x=xms, y=yms) source.data = dict(x=xtrib, y=ytrib, c=colors, desc=desc) for mn in [mn_values_slider]: mn.on_change('value', update_data) # Set up layouts and add to document inputs = widgetbox(mn_values_slider) curdoc().add_root(column(inputs, p, width=800)) curdoc().title = "m/n values"
p = figure( tools="pan,wheel_zoom,zoom_in,zoom_out,reset,tap,lasso_select,box_select") 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))
def __init__(self, worker, height=200, **kwargs): self.logger = logging.getLogger(self.__class__.__name__) self.logger.debug("Initialize DataHealthDashboard") self.pairs = self._DEFAULT_PAIRS self.cache = DataHealthCache.instance() self.metric_calulator = MetricsCalculator.instante() self.evl = EventLoopController.instance() self.evl_loop = self.evl.get_loop() self.tiledb = TileDBController.instance() self.datametric_cal_btn = Button(label="Calculate Data Metrics", button_type="success", height=50) self.datametric_cal_btn.on_click(self._datametric_cal_btn_on_click) self.refresh_btn = Button(label="Refresh Charts/Table", button_type="success", height=50) self.refresh_btn.on_click(self._update_data_source) self.from_datepk = DatePicker( title="From Date", min_date=date(2000, 1, 1), max_date=(datetime.now() + timedelta(days=7)).date(), value=(datetime.now() - timedelta(days=30)).date(), height=50) self.to_datepk = DatePicker(title="To Date", min_date=date(2000, 1, 1), max_date=(datetime.now() + timedelta(days=7)).date(), value=date.today(), height=50) self.table_source = ColumnDataSource({ 'ccypair': [pair for pair in self.pairs], 'sample_mean': ['NaN', 'NaN', 'NaN'], 'std_dev': ['NaN', 'NaN', 'NaN'], 'skew': ['NaN', 'NaN', 'NaN'], 'variance': ['NaN', 'NaN', 'NaN'], 'kurtosis': ['NaN', 'NaN', 'NaN'], 't_test': ['NaN', 'NaN', 'NaN'], 'hurst': ['NaN', 'NaN', 'NaN'] }) self.stats_table = DataTable(source=self.table_source, width=1305, height=100, columns=[ TableColumn(field="ccypair", title="Currency Pair", width=65), TableColumn(field="sample_mean", title="Sample Mean", width=145), TableColumn(field="std_dev", title="Std. Deviation", width=135), TableColumn(field="variance", title="Variance", width=135), TableColumn(field="skew", title="Skew", width=120), TableColumn(field="kurtosis", title="Kurtosis", width=120), TableColumn(field="t_test", title="T-Test", width=320), TableColumn(field="hurst", title="Hurst Exponent", width=265), ]) self.stats_table.index_width = 1 ts_data_names = self.cache.ts_data self.ts_source = {} self.figure = {} plots = [] for pair in self.pairs: self.ts_source[pair] = ColumnDataSource( {name: [] for name in ts_data_names}) pair_figure = figure( title=pair + " metrics", x_axis_type="datetime", height=350, x_range=DataRange1d(follow="end", follow_interval=99999999999, range_padding=0), y_range=DataRange1d(follow="end", follow_interval=1, range_padding=0.15), output_backend="webgl", sizing_mode="stretch_width", ) pair_figure.line(source=self.ts_source[pair], x="date", y="logret", color="blue", legend_label='log_ret') pair_figure.line(source=self.ts_source[pair], x="date", y="logret_ema", color="green", legend_label='ema') pair_figure.legend.location = "bottom_right" pair_figure.legend.click_policy = "hide" pair_figure.legend.background_fill_alpha = 0.0 pair_figure.yaxis.axis_label = "Log Return" pair_figure.xaxis.axis_label = "Time" pair_figure.xaxis.major_label_orientation = pi / 4 pair_figure.xaxis.formatter = DatetimeTickFormatter( microseconds=['%fus'], milliseconds=['%3Nms', '%S.%3Ns'], seconds=['%H:%M:%S'], minsec=['%H:%M:%S'], minutes=['%d/%m/%y %H:%M:%S'], hourmin=['%d/%m/%y %H:%M:%S'], hours=['%d/%m/%y %H:%M:%S'], days=['%d/%m/%y %H:%M:%S'], months=['%d/%m/%y %H:%M:%S'], years=['%d/%m/%y %H:%M:%S'], ) self.figure[pair] = pair_figure plots.append(self.figure[pair]) kw = {"sizing_mode": "stretch_width"} self.layout = layout([ row( *[ self.refresh_btn, self.from_datepk, self.to_datepk, self.datametric_cal_btn ], **kw), self.stats_table, column(*plots, **kw) ], sizing_mode='stretch_both') # self.root = row(*plots, **kw) self.root = self.layout
sizeCol="weights", color=['pink', 'blue', 'green']) div = Div(text="") div1 = Div(text="") sdp.click = CustomJS(args={'div': div}, code=""" console.log(`you clicked ${cb_data.word}`) div.text = `you clicked ${cb_data.word}` """) sdp.hover = CustomJS(args={'div': div1}, code=""" console.log(`HOV: ${cb_data.word}`) div.text = `HOVER: ${cb_data.word}` """) div3 = Div(text=""" <pre> sdp = WordCloud2(source=test1,wordCol="names",sizeCol="weights",colors=['pink','blue','green']) div = Div(text="") div1 = Div(text="") sdp.click = CustomJS(args={'div':div},code=''' console.log(`you clicked ${cb_data.word}`) div.text = `you clicked ${cb_data.word}` ''') sdp.hover = CustomJS(args={'div':div1},code=''' console.log(`HOV: ${cb_data.word}`) div.text = `HOVER: ${cb_data.word}` ''') </pre> """) show(column([row([sdp, column([div, div1])]), div3]))
def PlotWidget(*args, **kw): return column(name=kw['title'])
def plot_rolling_beta(rolling_window,factors_to_plot): result_array = np.zeros((1,len(factors_to_plot)+1)) # Initializing the results array factors1 = factors_to_plot + ['Alpha'] X = df[factors_to_plot].values Y = (df['Daily_Returns']-df[factor_riskfree[0]]).values # Calculating Excess Daily returns by subtracting Risk free returns dates = df['Date'].values for i in range(X.shape[0]-rolling_window+1): #Loop to do regression for each time period of rolling window x = X[i:rolling_window+i] # The X variables for regression based on rolling window y = Y[i:rolling_window+i] # The Y variable for regression based on rolling window regressor = LinearRegression().fit(x, y) # Doing the linear regression temp = np.append(regressor.coef_,regressor.intercept_) # Constructing the results of the regression numpy arrray by appending the alpha to the betas result_array = np.vstack((result_array, np.resize(temp,(1,len(factors_to_plot)+1)))) # Appending the Results of regression to result_array result_array = np.delete(result_array, 0, 0) # Deleing the first initialized row of the result_array dates = dates[rolling_window-1:] # Determing the dates of all the days on which rolling window regression is done result_df = pd.DataFrame(result_array.round(decimals=2), index=dates) # Values rounded to make the plots of beta result_df.columns = factors1 # To insert date column in the result_df dataframe df3 = pd.DataFrame(data=list(dates), columns=['int_date']) df3[['str_date']] = df3[['int_date']].applymap(str).applymap(lambda s: "{}-{}-{}".format(s[0:4], s[4:6], s[6:] )) rolling_dates=list(df3['str_date']) # df[['str_date']] = df[['int_date']].applymap(str).applymap(lambda s: "{}/{}/{}".format(s[6:], s[4:6], s[0:4])) dates = np.array(rolling_dates, dtype=np.datetime64) result_df.insert(loc=0, column='Date', value=dates) rolling_ndays = len(dates) mypalette=Spectral11[:4]+Spectral11[8:] numlines=len(factors_to_plot) f = figure(title = f'Rolling Beta of Factors: {rolling_window} days window', plot_height=550, plot_width=1500, toolbar_location='above',x_axis_type="datetime", x_axis_location="above", background_fill_color="#efefef", x_range=(dates[(rolling_ndays)//3], dates[((rolling_ndays)*2)//3])) #tooltips=tooltips,tools="xpan", select1 = figure(title="Drag the middle and edges of the selection box to change the range above", plot_height=140, plot_width=1500, y_range=f.y_range, x_axis_type="datetime", y_axis_type=None, tools="", toolbar_location=None, background_fill_color="#efefef") date = list(result_df['Date']) f.title.text_color = mypalette[-1] f.title.text_alpha = 0.6 f.title.text_font = "antiqua" f.title.text_font_size = "32px" f.title.align = "center" f.yaxis.axis_label = 'Rolling Beta' for i in range(numlines): f.line(x=date, y=list(result_df[factors_to_plot[i]]), legend_label=factors_to_plot[i], color=mypalette[i],line_width=3,name=factors_to_plot[i]) hover_tool = HoverTool( tooltips=[ ( 'Date', '$x{%F}'), ( 'Beta', '@y' ), # use @{ } for field names with spaces ( 'Factor', '$name') ], formatters={ '$x' : 'datetime', # use 'datetime' formatter for '@date' field }, names = factors_to_plot, mode='vline' # display a tooltip whenever the cursor is vertically in line with a glyph ) f.tools.append(hover_tool) f.legend.click_policy="hide" f.legend.background_fill_alpha = 0 f.legend.border_line_color = None f.legend.margin = 10 f.legend.padding = 18 f.legend.spacing = 10 f.toolbar.logo = None f.yaxis.axis_label_text_font_size= "18px" f.axis.major_label_text_font_size = '16px' f.legend.label_text_font_size = '16px' range_tool = RangeTool(x_range=f.x_range) range_tool.overlay.fill_color = "navy" range_tool.overlay.fill_alpha = 0.2 for i in range(numlines): select1.line(x=date, y=list(result_df[factors_to_plot[i]]), color=mypalette[i],line_width=1,name=factors_to_plot[i]) select1.ygrid.grid_line_color = None select1.add_tools(range_tool) select1.toolbar.active_multi = range_tool return column(f,select1)
callback.args["mej"] = M_slider callback.args["vej"] = v_slider callback.args["k"] = k_slider callback.args["T"] = T_slider callback.args["bfield"] = bfield_slider callback.args["pspin"] = pspin_slider button.callback = CustomJS(args=dict(source=source, vej=v_slider, name_v=text, mej=M_slider, myk=k_slider, myt0=T_slider, myb=bfield_slider, myp=pspin_slider), code=javaScript) callback2.args["SNName"] = text text.on_change('value', update_title) # Set up layouts and add to document inputs = widgetbox(text, M_slider, v_slider, k_slider, T_slider, bfield_slider, pspin_slider) layout = row(plot, column(inputs, button)) output_file("Magnetar.html") save(plot) show(layout)
def rolling(*, x: str, y: str, df, avgs: Sequence[Avg] = ['7D', '30D'], legend_label=None, context: Optional[RollingResult] = None, **kwargs) -> RollingResult: # TODO maybe use a special logging handler, so everything logged with warning level gets displayed? errors = [] # todo ugh. the same HPI check would be nice.. tzs = set(df.index.map(lambda x: getattr(x, 'tzinfo', None))) # meh if len(tzs) > 1: errors.append( f'WARNING: a mixture of timezones: {tzs}. You might want to unlocalize() them first.' ) elif len(tzs) == 1: [_tz] = tzs if _tz is not None: # todo not really sure about that.. maybe it's okay, although UTC might be wrong as well errors.append( f'WARNING: detected timezone: {_tz}. You might want to unlocalize() first.' ) # todo should copy df first?? if legend_label is None: legend_label = y # meh... don't think I like it # TODO def test this if context is None: ls = [] plot = date_figure(df=df) ls.append(plot) ctx = RollingResult( layout=column(ls, sizing_mode='stretch_width'), plots=[], figures=[plot], ) else: ctx = context plot = ctx.figure plots = ctx.plots layouts = ctx.layout.children # todo assert datetime index? test it too # todo although in theory it doens't have to be datetimes with the approprivate avgs?? has_x = df.index.notna() has_y = df[y].notna() err = df['error'].notna( ) if 'error' in df.columns else df.index == 'how_to_make_empty_index?' # ^^^ todo a bit ugly... think about this better for_table = ~has_x # case 1 is handled # case 2: set proper error for ones that don't have y df.loc[has_x & ~has_y & ~err, 'error'] = f'{y} is nan/null' # now case 2 and 3 are the same # case 3 case_3 = has_x & ~has_y for_table |= case_3 for_marks = case_3 # case 4, 5 ok = has_x & has_y case_4 = ok & err for_table |= case_4 for_warn = case_4 dfm = df.loc[for_marks] dfe = df.loc[for_table] dfw = df.loc[for_warn] df = df.loc[ok] if len(dfm) > 0: # todo meh.. how to make the position absolute?? some_y = df[y].quantile( 0.8) # to display kinda on top, but not too high if np.isnan(some_y): # otherwise fails during JSON serialization some_y = 0.0 plot.scatter( source=CDS(dfm), x=x, y=some_y, legend_label='errors', line_color='red', fill_color='yellow', # ?? marker='circle_cross', size=10, ) if len(dfe) > 0: errors.append(f'Also encountered {len(dfe)} errors:') from bokeh.models.widgets.markups import Div # first a summary for the most important warnings/errors # todo append later stuff as well, there are some warnings during means for e in errors: layouts.append( Div( text=html.escape(e), style={ 'color': 'red', 'font-weight': 'strong' }, )) if len(dfe) > 0: # todo could even keep the 'value' erorrs and display below too.. but for now it's ok # ok, if it respected newlines, would be perfect # for now this is 'fine'... # todo maybe should display all points, highlight error ones as red (and it sorts anyway so easy to overview?) # todo would be nice to highlight the corresponding points in table/plot from bokeh.models.widgets import DataTable, DateFormatter, TableColumn from bokeh.models.widgets.tables import DateFormatter, NumberFormatter, HTMLTemplateFormatter # didn't work at all?? # from bokeh.models.widgets.tables import ScientificFormatter # todo DataCube?? even more elaborate dfe = dfe.reset_index( ) # todo ugh. otherwise doesn't display the index at all? dfe = dfe.sort_values(by=x) # todo maybe display 'error' as the first col? datefmt = DateFormatter(format="%Y-%m-%d") # todo speed_avg could have less digits (guess by the dispersion or something??) # TODO horrible, but js bits of bokeh compute some complete bullhit for column widths # todo set monospace font?? one_char = 10 # pixels def datatable_columns(df): for c, t in df.dtypes.items(): formatter = None # TODO also use col name.. then won't have to handle nans! width = 15 # in characters # for fixed width types, we can have something kind of reasonable if str(t).startswith('float'): l = df[c].dropna().map(str).str.len().max() width = 4 if np.isnan(l) else l if str(t).startswith('datetime'): formatter = DateFormatter(format='%Y%m%d %H%M%S %Z', nan_format='Nan') width = 15 elif str(t).startswith('timedelta'): # TODO warn if df contains stuff with duration >1D? # without nan_format, it results in NaN:Nan:Nan formatter = DateFormatter(format='%H:%M:%S', nan_format='Nan') width = 8 # if c == 'error': # # meh, but the only easy way to limit and ellipsize it I found # # aaand it still computes width in some weird way, ends up taking too much space # formatter = HTMLTemplateFormatter(template='<div style="text-overflow: ellipsis; overflow: hidden; width: 60ch;"><%= value %></div>') tc = TableColumn( field=c, title=c, **({} if formatter is None else dict(formatter=formatter)), width=width * one_char, ) yield tc # TODO hmm, if we reuse the data source, editing & selection might work? errors_table = DataTable( source=CDS(dfe), columns=list(datatable_columns(dfe)), # todo ugh. handle this properly, was too narrow on the sleep plots editable=True, width=2000, # default ends up in trimmed table content autosize_mode='none', # this might overstretch the parent... # autosize_mode='fit_viewport', # this just makes it respect the parent width # width_policy='fit', ) layouts.append(errors_table) # todo # >>> plot.circle([1,2,3], [4,5,6], name="temp") # >>> plot.select(name="temp") # [GlyphRenderer(id='399d53f5-73e9-44d9-9527-544b761c7705', ...)] if len(dfw) > 0: plot.circle(source=CDS(dfw), x=x, y=y, legend_label='warnings', size=20, color='yellow') # todo warn if unsorted? df = df.sort_index() if len(df) == 0: # add a fake point, so at least plotting doesn't fail... df = pd.DataFrame([{ x: datetime(year=2000, month=1, day=1), y: 0.0, }]).set_index(x) avgs = ['3D' for _ in avgs] # FIXME need to add this to errors as well, or at least title.. # TODO need to add a better placholder, timestamp 0 really messes things up warnings.warn(f'No data points for {df}, empty plot!') if None not in avgs: plots.append( plot.scatter(x=x, y=y, source=CDS(df), legend_label=legend_label, **kwargs)) # only stuff without errors/warnings participates in the avg computation if 'error' in df.columns: # meh df = df[df['error'].isna()] for period in [a for a in avgs if a is not None]: dfy = df[[y]] if str(dfy.index.dtype) == 'object': logging.error( f"{dfy.dtypes}: index type is 'object'. You're likely doing something wrong" ) if 'datetime64' in str(dfy.index.dtype): # you're probably doing something wrong otherwise.. # todo warn too? # check it's a valid period pd.to_timedelta(period) # TODO how to fill the missing values?? # a sequence of consts would be a good test for it # todo why would index be na at this point? probably impossible? dfa = dfy[dfy.index.notna()].rolling(period).mean() # TODO assert x in df?? or rolling wrt to x?? # somehow plot.line works if 'x' is index? but df[x] doesnt.. # todo different style by default? thicker line? not sure.. plots.append( plot.line(x=x, y=y, source=CDS(dfa), legend_label=f'{legend_label} ({period} avg)', **kwargs)) plot.title.text = f'x: {x}, y: {y}' # TODO axis labels instead? return ctx
def product_reviews_over_time_tab(dataset, metadata): heading_div = Div( text="""<br><h3 style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0.5rem; font-family: "Nunito Sans", -apple-system, system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; font-weight: 600; color: rgb(26, 26, 26); font-size: 2rem; text-transform: uppercase; letter-spacing: 3px;">Product Review Timeline</h3><pre>Search a product & visualize its Yearly, Monthly, & Daily review trends. Checkout "Product Reviews Timeline - WITH SLIDER (WIP)" tab for the eventual stage of this vis.</pre><hr>""", width=1000, height=120, style={'text-align': 'center'}) combined_data = dataset.set_index('asin').join(metadata.set_index('Product ID')).reset_index() combined_data.columns = ['asin', 'reviewerID', 'overall', 'unixReviewTime', 'Description', 'price', 'Category'] combined_data['asin'] = combined_data['asin'].astype(str) def get_product_data(product_id): product_data = combined_data[combined_data['asin'] == product_id] product_data['dtReviewTime'] = pd.to_datetime(product_data['unixReviewTime'], unit='s') product_data['reviewYear'] = product_data['dtReviewTime'].dt.strftime('%Y') product_data['reviewMonth'] = product_data['dtReviewTime'].dt.strftime('%Y-%m') product_data['dtReviewTime'] = product_data['dtReviewTime'].dt.strftime('%Y-%m-%d') product_data = product_data.sort_values('dtReviewTime') return product_data top_k = 8 if len(combined_data) > 8 else len(combined_data) # Default selected_product is the most_purchased_product selected_product = combined_data.asin.value_counts().keys()[top_k-1] filtered_data = get_product_data(selected_product) selected_category = filtered_data.head(1).Category.values[0] top_k_products = combined_data.asin.value_counts().head(top_k).keys().tolist() bottom_k_products = combined_data.asin.value_counts().sort_values(ascending=True).head(top_k).keys().tolist() product_details = dict() product_details['asin'] = filtered_data.head(1).asin.values[0] product_details['description'] = filtered_data.head(1).Description.values[0] product_details['category'] = filtered_data.head(1).Category.values[0] review_avg = filtered_data.groupby('Category')['overall'].agg(['mean', 'count']).reset_index() product_details['total_reviews'] = str(review_avg['count'].values[0]) product_details['review_avg'] = str(review_avg['mean'].values[0]) price_avg = filtered_data.groupby('Category')['price'].agg(['mean', 'count']).reset_index() product_details['price_avg'] = str(price_avg['mean'].values[0]) year_wise_reviews = filtered_data.groupby('reviewYear')['overall'].agg(['mean', 'count']).reset_index() year_wise_reviews.columns = ['time', 'average', 'total'] month_wise_reviews = filtered_data.groupby('reviewMonth')['overall'].agg(['mean', 'count']).reset_index() month_wise_reviews.columns = ['time', 'average', 'total'] date_wise_reviews = filtered_data.groupby('dtReviewTime')['overall'].agg(['mean', 'count']).reset_index() date_wise_reviews.columns = ['time', 'average', 'total'] # Default plot is Year Wise Reviews plot_data = year_wise_reviews source = ColumnDataSource( data=dict( time_stamp=list(map(str, plot_data['time'])), total=plot_data.total.tolist(), average=plot_data.average.tolist(), color=getKColors(len(plot_data)))) # Adding hover tool hover = HoverTool(tooltips=[('Time', '@time_stamp'), ('Avg Review', '@average'), ('Total Reviews', '@total')], mode='vline') # Total Reviews Figure p1 = figure(x_range=plot_data.time.tolist(), plot_width=1200, plot_height=300) r1_l = p1.line(source=source, x='time_stamp', y='total', line_width=2) r1_c = p1.circle(source=source, x='time_stamp', y='total', size=15, color="red", alpha=0.5) p1.add_tools(hover) # Formatting axes p1.xaxis.axis_label = "" p1.xaxis.major_label_orientation = math.pi / 2 p1.xaxis.major_label_text_font_size = "10pt" p1.xaxis.axis_label_text_font_size = "0pt" p1.yaxis.axis_label = "Total Reviews" p1.yaxis.formatter = NumeralTickFormatter(format="0") p1.yaxis.major_label_text_font_size = "10pt" p1.yaxis.axis_label_text_font_size = "15pt" ds1_l = r1_l.data_source ds1_c = r1_c.data_source # Average Rating Figure p2 = figure(x_range=plot_data.time.tolist(), plot_width=1200, plot_height=300) r2_l = p2.line(source=source, x='time_stamp', y='average', line_width=2) r2_c = p2.circle(source=source, x='time_stamp', y='average', size=15, color="red", alpha=0.5) p2.add_tools(hover) # Formatting axes p2.xaxis.axis_label = "Time" p2.xaxis.major_label_orientation = math.pi / 2 p2.xaxis.major_label_text_font_size = "10pt" p2.xaxis.axis_label_text_font_size = "15pt" p2.yaxis.axis_label = "Average Rating" p2.yaxis.formatter = NumeralTickFormatter(format="0") p2.yaxis.major_label_text_font_size = "10pt" p2.yaxis.axis_label_text_font_size = "15pt" ds2_l = r2_l.data_source ds2_c = r2_c.data_source radio_button_group = RadioButtonGroup( labels=["Yearly", "Monthly", "Daily"], active=0, width=1200) def get_updated_plot_data_dict(new_plot_data): new_data = dict() if new_plot_data.empty: new_data['x_range'] = [] new_data['time_stamp'] = [] new_data['average'] = [] new_data['total'] = [] new_data['color'] = [] else: new_colors = getKColors(len(new_plot_data)) new_data['x_range'] = new_plot_data.time.tolist() new_data['time_stamp'] = new_plot_data.time.tolist() new_data['average'] = new_plot_data.average.tolist() new_data['total'] = new_plot_data.total.tolist() new_data['color'] = new_colors return new_data def update_plot(attr, old, new): global year_wise_reviews, month_wise_reviews, date_wise_reviews, filtered_data, selected_product try: selected_product except NameError: selected_product = combined_data.asin.value_counts().head(1).index[0] filtered_data = get_product_data(selected_product) new_plot_data = plot_data if radio_button_group.active == 0: try: year_wise_reviews except NameError: year_wise_reviews = None year_wise_reviews = filtered_data.groupby('reviewYear')['overall'].agg(['mean', 'count']).reset_index() year_wise_reviews.columns = ['time', 'average', 'total'] new_plot_data = year_wise_reviews if radio_button_group.active == 1: try: month_wise_reviews except NameError: month_wise_reviews = None month_wise_reviews = filtered_data.groupby('reviewMonth')['overall'].agg( ['mean', 'count']).reset_index() month_wise_reviews.columns = ['time', 'average', 'total'] new_plot_data = month_wise_reviews if radio_button_group.active == 2: try: date_wise_reviews except NameError: date_wise_reviews = None date_wise_reviews = filtered_data.groupby('dtReviewTime')['overall'].agg( ['mean', 'count']).reset_index() date_wise_reviews.columns = ['time', 'average', 'total'] new_plot_data = date_wise_reviews new_data = get_updated_plot_data_dict(new_plot_data) p1.x_range.factors = new_data['x_range'] p2.x_range.factors = new_data['x_range'] ds1_l.data = new_data ds1_c.data = new_data ds2_l.data = new_data ds2_c.data = new_data radio_button_group.on_change('active', update_plot) def generate_div_text(product_attributes): return """<table width="1200px" style='font-family: arial, sans-serif; border-collapse: collapse; width: 100%;'> <tr> <th style='border: 1px solid #dddddd; text-align: left; padding: 8px; align: center;'>Attribute</th> <th style='border: 1px solid #dddddd; text-align: left; padding: 8px; align: center;'>Value</th> </tr> <tr> <td style='border: 1px solid #dddddd; text-align: left; padding: 8px; align: center; background-color: #dddddd'> Product ID </td> <td style='border: 1px solid #dddddd; text-align: left; padding: 8px; align: center; background-color: #dddddd'> """ + product_attributes['asin'] + """ </td> </tr> <tr> <td style='border: 1px solid #dddddd; text-align: left; padding: 8px; align: center;'> Description </td> <td style='border: 1px solid #dddddd; text-align: left; padding: 8px; align: center'> """ + product_attributes['description'] + """ </td> </tr> <tr> <td style='border: 1px solid #dddddd; text-align: left; padding: 8px; align: center; background-color: #dddddd'> Category </td> <td style='border: 1px solid #dddddd; text-align: left; padding: 8px; align: center; background-color: #dddddd'> """ + product_attributes['category'] + """ </td> </tr> <tr> <td style='border: 1px solid #dddddd; text-align: left; padding: 8px; align: center;'> Total Reviews </td> <td style='border: 1px solid #dddddd; text-align: left; padding: 8px; align: center'> """ + str(product_attributes['total_reviews']) + """ </td> </tr> <tr> <td style='border: 1px solid #dddddd; text-align: left; padding: 8px; align: center; background-color: #dddddd'> Average Rating </td> <td style='border: 1px solid #dddddd; text-align: left; padding: 8px; align: center; background-color: #dddddd'> """ + str(product_attributes['review_avg']) + """ </td> </tr> <tr> <td style='border: 1px solid #dddddd; text-align: left; padding: 8px; align: center;'> Average Price </td> <td style='border: 1px solid #dddddd; text-align: left; padding: 8px; align: center'> """ + str(product_attributes['price_avg']) + """ </td> </tr> </table>""" product_details_div = Div(text=generate_div_text(product_details), width=1200, height=300) def update_selection(): if not search_input.value: return global year_wise_reviews, month_wise_reviews, date_wise_reviews, product_details, filtered_data, selected_product selected_product = search_input.value searched_data = get_product_data(search_input.value) filtered_data = searched_data new_data = dict() if searched_data.empty: year_wise_reviews = searched_data month_wise_reviews = searched_data date_wise_reviews = searched_data new_data['x_range'] = [] new_data['time_stamp'] = [] new_data['average'] = [] new_data['total'] = [] new_data['color'] = [] p1.x_range.factors = new_data['x_range'] p2.x_range.factors = new_data['x_range'] product_details_div.text = """<img alt="Sorry! No product found." src="/myapp/static/images/no_results_found.png">""" else: product_details = dict() product_details['asin'] = searched_data.head(1).asin.values[0] product_details['description'] = searched_data.head(1).Description.values[0] product_details['category'] = searched_data.head(1).Category.values[0] updated_review_avg = searched_data.groupby('Category')['overall'].agg(['mean', 'count']).reset_index() product_details['total_reviews'] = str(updated_review_avg['count'].values[0]) product_details['review_avg'] = str(updated_review_avg['mean'].values[0]) updated_price_avg = searched_data.groupby('Category')['price'].agg(['mean', 'count']).reset_index() product_details['price_avg'] = str(updated_price_avg['mean'].values[0]) product_details_div.text = generate_div_text(product_details) year_wise_reviews = searched_data.groupby('reviewYear')['overall'].agg(['mean', 'count']).reset_index() year_wise_reviews.columns = ['time', 'average', 'total'] month_wise_reviews = searched_data.groupby('reviewMonth')['overall'].agg(['mean', 'count']).reset_index() month_wise_reviews.columns = ['time', 'average', 'total'] date_wise_reviews = searched_data.groupby('dtReviewTime')['overall'].agg(['mean', 'count']).reset_index() date_wise_reviews.columns = ['time', 'average', 'total'] if radio_button_group.active == 0: new_plot_data = year_wise_reviews if radio_button_group.active == 1: new_plot_data = month_wise_reviews if radio_button_group.active == 2: new_plot_data = date_wise_reviews new_data = get_updated_plot_data_dict(new_plot_data) p1.x_range.factors = new_data['x_range'] p2.x_range.factors = new_data['x_range'] ds1_l.data = new_data ds1_c.data = new_data ds2_l.data = new_data ds2_c.data = new_data search_input = TextInput(value=selected_product, title="Product ID:") search_button = Button(label="Search by Product Id", button_type="success") search_button.on_click(update_selection) search_category_input = TextInput(value=selected_category, title="Category:") search_category_button = Button(label="Search by Category", button_type="primary") def get_div_text_for_category(): global selected_category selected_category = search_category_input.value category_data = combined_data[combined_data['Category'].str.lower() == str(search_category_input.value).lower()] if category_data.empty: return """<font size="4"><b>Sorry! No products found for <mark><u>\"""" + selected_category + """\"</u></mark> category.</b></font> <br><br>""" top_k_category = 8 if len(category_data) > 8 else len(category_data) top_k_category_products = category_data.asin.value_counts().head(top_k_category).keys().tolist() bottom_k_category_products = category_data.asin.value_counts().sort_values(ascending=True).head(top_k_category).keys().tolist() top_k_category_pid_list = "" temp_category_count = 1 for j in range(len(top_k_category_products)): if temp_category_count % 4 == 0: top_k_category_pid_list += top_k_category_products[j] + """<br>""" temp_category_count = 0 else: top_k_category_pid_list += top_k_category_products[j] + ", " temp_category_count = temp_category_count + 1 bottom_k_category_pid_list = "" temp_category_count = 1 for j in range(len(bottom_k_category_products)): if temp_category_count % 4 == 0: bottom_k_category_pid_list += bottom_k_category_products[j] + """<br>""" temp_category_count = 0 else: bottom_k_category_pid_list += bottom_k_category_products[j] + ", " temp_category_count = temp_category_count + 1 text_data = """<font size="4"><b>Top & Worst performers for <mark><u>\"""" + selected_category + """\"</u></mark> category:</b></font> <br><br>""" + \ """<font color="blue" size="3"><b>Top """ + str(top_k_category) + """ products:</b></font><br>""" + \ top_k_category_pid_list + """<br>""" + \ """<font color="red" size="3"><b>Bottom """ + str(top_k_category) + """ products:</b></font><br>""" + \ bottom_k_category_pid_list return text_data def init_div_text_for_category(): category_data = combined_data[combined_data['Category'].str.lower() == str(search_category_input.value).lower()] top_k_category = 8 if len(category_data) > 8 else len(category_data) top_k_category_products = category_data.asin.value_counts().head(top_k_category).keys().tolist() bottom_k_category_products = category_data.asin.value_counts().sort_values(ascending=True).head(top_k_category).keys().tolist() top_k_category_pid_list = "" temp_category_count = 1 for j in range(len(top_k_category_products)): if temp_category_count % 4 == 0: top_k_category_pid_list += top_k_category_products[j] + """<br>""" temp_category_count = 0 else: top_k_category_pid_list += top_k_category_products[j] + ", " temp_category_count = temp_category_count + 1 bottom_k_category_pid_list = "" temp_category_count = 1 for j in range(len(bottom_k_category_products)): if temp_category_count % 4 == 0: bottom_k_category_pid_list += bottom_k_category_products[j] + """<br>""" temp_category_count = 0 else: bottom_k_category_pid_list += bottom_k_category_products[j] + ", " temp_category_count = temp_category_count + 1 text_data = """<font size="4"><b>Top and Worst performers for <mark><u>\"""" + selected_category + """\"</u></mark> category:</b></font> <br><br>""" + \ """<font color="blue" size="3"><b>Top """ + str(top_k_category) + """ products:</b></font><br>""" + \ top_k_category_pid_list + """<br>""" + \ """<font color="red" size="3"><b>Bottom """ + str(top_k_category) + """ products:</b></font><br>""" + \ bottom_k_category_pid_list return text_data sample_pid_for_category_div = Div(text=init_div_text_for_category(), width=450, height=130) def update_category_div(): if not search_category_input.value: return sample_pid_for_category_div.text = get_div_text_for_category() search_category_button.on_click(update_category_div) top_k_pid_list = "" temp_count = 1 for i in range(len(top_k_products)): # top_k_pid_list += top_k_products[i] + ", " if temp_count % 4 == 0: top_k_pid_list += top_k_products[i] + """<br>""" temp_count = 0 else: top_k_pid_list += top_k_products[i] + ", " temp_count = temp_count + 1 bottom_k_pid_list = "" temp_count = 1 for i in range(len(bottom_k_products)): # bottom_k_pid_list += bottom_k_products[i] + ", " if temp_count % 4 == 0: bottom_k_pid_list += bottom_k_products[i] + """<br>""" temp_count = 0 else: bottom_k_pid_list += bottom_k_products[i] + ", " temp_count = temp_count + 1 pre_text_data = """<font size="4"><b><u>Overall</u> Top & Worst performers:</b></font> <br><br>""" + \ """<font color="blue" size="3"><b>Top """ + str(top_k) + """ :</b></font><br>""" + \ top_k_pid_list + """<br>""" + \ """<font color="red" size="3"><b>Bottom """ + str(top_k) + """ :</b></font><br>""" + \ bottom_k_pid_list sample_product_ids = Div(text=pre_text_data, width=450, height=130) # layout = column(search_input, search_button, product_details_div, radio_button_group, p1, p2) layout = column(heading_div, row(column(search_category_input, search_category_button, sample_pid_for_category_div), column(search_input, search_button, sample_product_ids), product_details_div), radio_button_group, p1, p2) tab = Panel(child=layout, title='Product Reviews Timeline') return tab
def modify_doc(doc): ####### plot tab3 (birds location) ##### fig = figure(title="Birds recording in Lekagul Roadways", x_range=(0, 250), y_range=(0, 200), tools=TOOLS, width=900) fig.xaxis.visible = False fig.yaxis.visible = False # Display the 32-bit RGBA image fig.image_rgba(image=[img], x=0, y=0, dw=200, dh=200) name_birds = birds['English_name'].unique() source = ColumnDataSource(birds) fig.circle('X', 'Y', source=source, size=8, color='colors', fill_alpha=0.7, legend='English_name') fig.asterisk(test_birds[' X'].tolist(), test_birds[' Y'].tolist(), size=20, line_color="black", line_width=3, fill_color="blue", fill_alpha=0.5) rangeslider = RangeSlider(title="Date Range", start=1983, end=2018, value=(1983, 2018), step=1, callback_policy='mouseup') multiselect = MultiSelect(title="Select your species : ", value=list(name_birds), options=list(name_birds)) def callback(attr, old, new): date_tuple = rangeslider.value birds_name = multiselect.value dataset = birds[ (birds['year'] <= date_tuple[1]) & (birds['year'] >= date_tuple[0]) & (birds['English_name'].apply(lambda x: in_name(x, birds_name)))] new_data = ColumnDataSource(dataset) source.data = new_data.data multiselect.on_change('value', callback) rangeslider.on_change('value', callback) inputs = widgetbox(rangeslider, multiselect) ####### main tab ###### fig_1 = figure(title="Birds recording in Lekagul Roadways", x_range=(0, 200), y_range=(0, 200), tools=TOOLS, width=600, height=500) fig_1.xaxis.visible = False fig_1.yaxis.visible = False fig_1.image_rgba(image=[img], x=0, y=0, dw=200, dh=200) source_1 = ColumnDataSource(birds) source_2 = ColumnDataSource(test_birds) fig_1.circle_cross(x=148, y=160, color='black', size=30, fill_alpha=0.3) fig_1.circle('X', 'Y', source=source_1, size=8, color='colors', fill_alpha=0.7) fig_1.asterisk(' X', ' Y', source=source_2, size=20, line_color="black", line_width=3, fill_color="blue", fill_alpha=0.5) radio_button_group_test = RadioButtonGroup(labels=list( test_birds.ID.apply(str)), active=None, width=1300) rangeslider_2 = RangeSlider(title="Date Range", start=1983, end=2018, value=(1983, 2018), step=1, callback_policy='mouseup') button_pred = Button(label='Predicted bird', button_type='danger') def update_1(attr, old, new): test_bird_num = radio_button_group_test.active if test_bird_num is not None: #button_pred.label=str(list_prediction[test_bird_num]) dataset = test_birds[test_birds['ID'] == test_bird_num + 1] new_data = ColumnDataSource(dataset) source_2.data = new_data.data button_pred.label = list_ordered_name[np.argmax( array_pred[test_bird_num, :])] list_map = list( map(lambda x, y: x + ' ------ ' + str(y), list_ordered_name, array_pred[test_bird_num, :])) list_change = [] for name_bird in name_birds: list_change.append( list_map[list_ordered_name.index(name_bird)]) radio_button_group_train._property_values[ 'labels'][:] = list_change plot_amplitude_test = create_signal_plot( list_df_test_signals[test_bird_num], 'test %s' % (test_bird_num + 1)) plot_amplitude_test.x_range = Range1d(0, 60) plot_spectrum_test = create_signal_plot( list_df_test_spectrum[test_bird_num], 'test %s' % (test_bird_num + 1), "Fréquence", "Magnitude", "Freq", "Magnitude") plot_spectrum_test.x_range = Range1d(0, 0.02) signals_plot.children[0] = plot_amplitude_test signals_plot.children[2] = plot_spectrum_test radio_button_group_test.on_change('active', update_1) radio_button_group_train = RadioGroup(labels=list(name_birds), active=0) def update_2(attr, old, new): idx_name_bird = radio_button_group_train.active date_tuple = rangeslider_2.value if idx_name_bird is not None: dataset = birds[(birds['year'] <= date_tuple[1]) & (birds['year'] >= date_tuple[0]) & (birds['English_name'] == name_birds[idx_name_bird])] new_data = ColumnDataSource(dataset) source_1.data = new_data.data if new in range(15): plot_amplitude_test = create_signal_plot( dict_df_signals[name_birds[idx_name_bird]], name_birds[idx_name_bird]) plot_amplitude_test.x_range = Range1d(0, 60) plot_spectrum_test = create_signal_plot( dict_df_spectrum[name_birds[idx_name_bird]], name_birds[idx_name_bird], "Fréquence", "Magnitude", "Freq", "Magnitude") plot_spectrum_test.x_range = Range1d(0, 0.02) signals_plot.children[1] = plot_amplitude_test signals_plot.children[3] = plot_spectrum_test else: pass radio_button_group_train.on_change('active', update_2) rangeslider_2.on_change('value', update_2) plot_amplitude_train = create_signal_plot(dict_df_signals[name_birds[0]], name_birds[0]) plot_amplitude_train.x_range = Range1d(0, 60) plot_amplitude_test = create_signal_plot(list_df_test_signals[0], 'test 1') plot_amplitude_test.x_range = Range1d(0, 60) plot_spectrum_train = create_signal_plot(dict_df_spectrum[name_birds[0]], name_birds[0], "Fréquence", "Magnitude", "Freq", "Magnitude") plot_spectrum_train.x_range = Range1d(0, 0.02) plot_spectrum_test = create_signal_plot(list_df_test_spectrum[0], 'test 1', "Fréquence", "Magnitude", "Freq", "Magnitude") plot_spectrum_test.x_range = Range1d(0, 0.02) signals_plot = column([ plot_amplitude_test, plot_amplitude_train, plot_spectrum_test, plot_spectrum_train ]) row_map_signal = row([ radio_button_group_train, column([fig_1, rangeslider_2]), signals_plot ]) column_main = column([ row([ widgetbox([PreText(text="Prediction : "), radio_button_group_test]), button_pred ]), row_map_signal ]) tab1 = Panel(child=column_main, title="Main view") tab2 = Panel(child=column(inputs, fig), title="Birds location") ##### tab2 : birds call /song evolution birds_call_song = birds.copy() birds_call_song['Vocalization_type'] = birds_call_song[ 'Vocalization_type'].apply(lambda x: x.lower().strip()) birds_call_song.dropna(inplace=True) fig_3 = figure(title="Birds recording in Lekagul Roadways", x_range=(0, 250), y_range=(0, 200), tools=TOOLS, width=900) fig_3.xaxis.visible = False fig_3.yaxis.visible = False fig_3.image_rgba(image=[img], x=0, y=0, dw=200, dh=200) birds_call = birds_call_song[birds_call_song['Vocalization_type'] == 'call'] birds_song = birds_call_song[birds_call_song['Vocalization_type'] == 'song'] birds_call_song = birds_call_song[birds_call_song['Vocalization_type'] == 'call, song'] source_call = ColumnDataSource(birds_call) source_song = ColumnDataSource(birds_song) source_call_song = ColumnDataSource(birds_call_song) fig_3.circle_cross(x=148, y=160, color='black', size=30, fill_alpha=0.3) fig_3.circle('X', 'Y', source=source_call, size=16, color='colors', fill_alpha=0.7, legend='Vocalization_type') fig_3.triangle('X', 'Y', source=source_song, size=16, color='colors', fill_alpha=0.7, legend='Vocalization_type') fig_3.square('X', 'Y', source=source_call_song, size=16, color='colors', fill_alpha=0.7, legend='Vocalization_type') fig_3.asterisk(test_birds[' X'].tolist(), test_birds[' Y'].tolist(), size=20, line_color="black", line_width=3, fill_color="blue", fill_alpha=0.5) slider = Slider(title="Select the year:", start=1983, end=2018, value=2017, step=1) select = Select(title="Select your specie : ", value='Rose-crested Blue Pipit', options=list(name_birds)) stacked_bar = figure(plot_height=250, title="Vocalization type percentage by year", toolbar_location=None) source_stacked_bar = ColumnDataSource( dict_stacked_df_percentage['Rose-crested Blue Pipit']) stacked_bar.vbar_stack(['call', 'song'], x='Year', width=0.9, source=source_stacked_bar, color=['silver', 'lightblue'], legend=[value(x) for x in ['call', 'song']]) stacked_bar.legend.location = "bottom_left" stacked_bar_count = figure(plot_height=250, title="Vocalization type count by year", toolbar_location=None) source_stacked_bar_count = ColumnDataSource( dict_stacked_df_count['Rose-crested Blue Pipit']) stacked_bar_count.vbar_stack(['call', 'song'], x='Year', width=0.9, source=source_stacked_bar_count, color=['silver', 'lightblue'], legend=[value(x) for x in ['call', 'song']]) stacked_bar_count.legend.location = "bottom_left" def callback_call(attr, old, new): year = slider.value birds_name = select.value dataset_call = birds_call[(birds_call['year'] == year) & (birds_call['English_name'] == birds_name)] new_data = ColumnDataSource(dataset_call) source_call.data = new_data.data dataset_song = birds_song[(birds_song['year'] == year) & (birds_song['English_name'] == birds_name)] new_data = ColumnDataSource(dataset_song) source_song.data = new_data.data dataset_call_song = birds_call_song[ (birds_call_song['year'] == year) & (birds_call_song['English_name'] == birds_name)] new_data = ColumnDataSource(dataset_call_song) source_call_song.data = new_data.data new_data = ColumnDataSource(dict_stacked_df_percentage[birds_name]) source_stacked_bar.data = new_data.data new_data = ColumnDataSource(dict_stacked_df_count[birds_name]) source_stacked_bar_count.data = new_data.data select.on_change('value', callback_call) slider.on_change('value', callback_call) tab3 = Panel(child=column( select, row([fig_3, column(stacked_bar, stacked_bar_count)]), slider), title="Birds Evolution") #### regroup the tabs into one dashboard ##### tabs = Tabs(tabs=[tab1, tab3, tab2]) doc.add_root(tabs)
def plot_rolling_alpha(rolling_window,factors_to_plot): result_array = np.zeros((1,len(factors_to_plot)+1)) # Initializing the results array factors1 = factors_to_plot + ['Alpha'] X = df[factors_to_plot].values Y = (df['Daily_Returns']-df[factor_riskfree[0]]).values # Calculating Excess Daily returns by subtracting Risk free returns dates = df['Date'].values for i in range(X.shape[0]-rolling_window+1): #Loop to do regression for each time period of rolling window x = X[i:rolling_window+i] # The X variables for regression based on rolling window y = Y[i:rolling_window+i] # The Y variable for regression based on rolling window regressor = LinearRegression().fit(x, y) # Doing the linear regression temp = np.append(regressor.coef_,regressor.intercept_) # Constructing the results of the regression numpy arrray by appending the alpha to the betas result_array = np.vstack((result_array, np.resize(temp,(1,len(factors_to_plot)+1)))) # Appending the Results of regression to result_array result_array = np.delete(result_array, 0, 0) # Deleing the first initialized row of the result_array dates = dates[rolling_window-1:] # Determing the dates of all the days on which rolling window regression is done result_alpha = pd.DataFrame(result_array, index=dates) # Values are not rounded to make the plots of annual alpha result_alpha.columns = factors1 # To insert date column in the result_df dataframe df3 = pd.DataFrame(data=list(dates), columns=['int_date']) df3[['str_date']] = df3[['int_date']].applymap(str).applymap(lambda s: "{}-{}-{}".format(s[0:4], s[4:6], s[6:] )) rolling_dates=list(df3['str_date']) # df[['str_date']] = df[['int_date']].applymap(str).applymap(lambda s: "{}/{}/{}".format(s[6:], s[4:6], s[0:4])) dates = np.array(rolling_dates, dtype=np.datetime64) rolling_ndays = len(dates) source = ColumnDataSource(data=dict(date=dates, close=list(result_alpha['Alpha'].values*256))) mypalette=Spectral11[:4]+Spectral11[8:] p = figure(title = f'Rolling Annual %Alpha: {rolling_window} days window - Betas: {factors_to_plot}', plot_height=550, plot_width=1500, toolbar_location='above', x_axis_type="datetime", x_axis_location="above", background_fill_color="#efefef", x_range=(dates[(ndays-rolling_window)//3], dates[((ndays-rolling_window)*2)//3])) #, tools="xpan" ,tooltips=tooltips, p.toolbar.logo = None p.line('date', 'close', source=source,line_width=3, legend_label="% ALPHA", name="% ALPHA", color=mypalette[0]) p.legend.background_fill_alpha = 0 p.yaxis.axis_label = '%age Returns' p.yaxis.axis_label_text_font_size= "18px" p.axis.major_label_text_font_size = '16px' p.legend.label_text_font_size = '16px' hover_tool1 = HoverTool( tooltips=[ ( 'Date', '$x{%F}'), ( 'ALPHA', '@close%' ) # use @{ } for field names with spaces @{% ALPHA} ], formatters={ '$x':'datetime', # use 'datetime' formatter for '@date' field }, names = ["% ALPHA"], mode='vline' # display a tooltip whenever the cursor is vertically in line with a glyph ) p.tools.append(hover_tool1) p.title.text_color = mypalette[-1] p.title.text_alpha = 0.6 p.title.text_font = "antiqua" p.title.text_font_size = "22px" p.title.align = "center" select = figure(title="Drag the middle and edges of the selection box to change the range above", plot_height=140, plot_width=1500, y_range=p.y_range, x_axis_type="datetime", y_axis_type=None, tools="", toolbar_location=None, background_fill_color="#efefef") range_tool = RangeTool(x_range=p.x_range) range_tool.overlay.fill_color = "navy" range_tool.overlay.fill_alpha = 0.2 select.line('date', 'close', source=source, color=mypalette[0]) select.ygrid.grid_line_color = None select.add_tools(range_tool) select.toolbar.active_multi = range_tool # rolling_alpha = file_html([p,select], CDN) return column(p,select)
def get_changed_parameters(initial_parameters, plot_width): """ get a bokeh column object with a table of the changed parameters :param initial_parameters: ulog.initial_parameters """ param_names = [] param_values = [] param_defaults = [] param_mins = [] param_maxs = [] param_descriptions = [] default_params = get_default_parameters() for param_name in sorted(initial_parameters): param_value = initial_parameters[param_name] if param_name.startswith('RC') or param_name.startswith('CAL_'): continue try: if param_name in default_params: default_param = default_params[param_name] if default_param['type'] == 'FLOAT': is_default = abs(float(default_param['default']) - float(param_value)) < 0.00001 if 'decimal' in default_param: param_value = round(param_value, int(default_param['decimal'])) else: is_default = int(default_param['default']) == int(param_value) if not is_default: param_names.append(param_name) param_values.append(param_value) param_defaults.append(default_param['default']) param_mins.append(default_param.get('min', '')) param_maxs.append(default_param.get('max', '')) param_descriptions.append(default_param.get('short_desc', '')) else: # not found: add it as if it were changed param_names.append(param_name) param_values.append(param_value) param_defaults.append('') param_mins.append('') param_maxs.append('') param_descriptions.append('(unknown)') except Exception as error: print(type(error), error) param_data = dict( names=param_names, values=param_values, defaults=param_defaults, mins=param_mins, maxs=param_maxs, descriptions=param_descriptions) source = ColumnDataSource(param_data) columns = [ TableColumn(field="names", title="Name", width=int(plot_width*0.2), sortable=False), TableColumn(field="values", title="Value", width=int(plot_width*0.15), sortable=False), TableColumn(field="defaults", title="Default", width=int(plot_width*0.1), sortable=False), TableColumn(field="mins", title="Min", width=int(plot_width*0.075), sortable=False), TableColumn(field="maxs", title="Max", width=int(plot_width*0.075), sortable=False), TableColumn(field="descriptions", title="Description", width=int(plot_width*0.40), sortable=False), ] data_table = DataTable(source=source, columns=columns, width=plot_width, height=300, sortable=False, selectable=False) div = Div(text="""<b>Non-default Parameters</b> (except RC and sensor calibration)""", width=int(plot_width/2)) return column(div, data_table, width=plot_width)
p = fig.circle( x='axis1', y='axis2', fill_color='colors', source=source, fill_alpha=0.8, size=10, line_alpha=0, selection_alpha=1, selection_fill_color='colors', ) fig.add_tools(HoverTool(tooltips=[('Population', '@y')])) p.nonselection_glyph = None plot = column(row(fig, column(multiselect, button)), row(focus, reset, view3d, download_file)) #functions called on pressing each button button.on_click(update) focus.on_click(focus_selected) reset.on_click(reset_points) view3d.on_click(project) download_file.on_click(download) #lasso function is called whenever points are selected source.on_change('selected', lasso) curdoc().add_root(plot)
S3.change.emit(); S4.change.emit(); S2.change.emit(); S5.change.emit(); """) button2 = Button(label="Delete Selected (can't be undone)", button_type="success", callback=callback3) button.js_on_event(events.ButtonClick, ) #slider.js_on_change('value', callback) p1.legend.location = "top_right" p1.legend.click_policy = "hide" layout = row(p1, column(slider, button, button2)) script, div = components(layout) resources = INLINE.render() filename = 'embed_multiple.html' html = template.render(resources=resources, script=script, div=div) with io.open(filename, mode='w', encoding='utf-8') as f: f.write(html) view(filename) #show(layout)
def create_nn_finder_html(distances, text_df, file_path): source = ColumnDataSource(data=dict( ids=range(len(text_df.text)), distances=distances.tolist(), text=text_df.text, display_text=text_df.text, display_ids=range(len(text_df.text)), )) display_source = ColumnDataSource(data=dict( closest_text=[""] * 20, closest_dist=[0] * 20, )) columns = [ TableColumn(field="display_text", title="Text"), ] closest_columns = [ TableColumn(field="closest_text", title="Closest examples"), TableColumn(field="closest_dist", title="Distance", width=20), ] str_search_input = TextInput(value="", title="Search feedback") callback = CustomJS(args=dict(source=source, display_source=display_source, search_text=str_search_input), code=""" const data = source.data; // ################## // First search // ################## const search_text_str = search_text.value.toLowerCase(); const display_texts = []; const display_ids = []; data['text'].map(function(e, i) { const text_val = data['text'][i]; const text_id = data['ids'][i]; if (text_val.toLowerCase().includes(search_text_str)){ display_texts.push(text_val); display_ids.push(text_id); } }); data['display_text'] = display_texts; data['display_ids'] = display_ids; source.change.emit(); // ################## // Then show selected // ################## if(source.selected.indices.length >= 1){ const selected_table_idx = source.selected.indices[0]; if (selected_table_idx >= data['display_ids'].length){ console.log("Empty cell selected") }else{ const selected_idx = data['display_ids'][selected_table_idx]; console.log(selected_idx) const texts = data['text']; const list_of_dist = data['distances']; const selected_dist = list_of_dist[selected_idx]; function indexOfNMin(arr, n) { if (arr.length < n) { return [-1]; } var min_arr = arr.slice(0, n); var min_idxs = [...Array(n).keys()]; for (var i = n; i < arr.length; i++) { max_selected = Math.max(...min_arr); if (arr[i] < max_selected) { var idx_max = min_arr.indexOf(max_selected); min_arr[idx_max] = arr[i]; min_idxs[idx_max] = i; } } return [min_arr, min_idxs]; } const closest_dist_values = indexOfNMin(selected_dist, 20); const closest_dist = [].slice.call(closest_dist_values[0]); const closest_dist_idx = closest_dist_values[1]; function sortWithIndices(inputArray) { const toSort = inputArray.slice(); for (var i = 0; i < toSort.length; i++) { toSort[i] = [toSort[i], i]; } toSort.sort(function(left, right) { return left[0] < right[0] ? -1 : 1; }); var sortIndices = []; for (var j = 0; j < toSort.length; j++) { sortIndices.push(toSort[j][1]); } return sortIndices; } const sorted_closest_dist_idx_idx = sortWithIndices(closest_dist); const sorted_closest_dist_idx = sorted_closest_dist_idx_idx.map(i => closest_dist_idx[i]); const closest_texts = sorted_closest_dist_idx.map(i => texts[i]); const display_data = display_source.data; display_data['closest_text'] = closest_texts; display_data['closest_dist'] = closest_dist.sort(function(a, b){return a - b}).map(i => i.toFixed(3)); display_source.change.emit(); } } """) source.selected.js_on_change('indices', callback) str_search_input.js_on_change('value', callback) data_table = DataTable(source=source, columns=columns, width=600, height=420, selectable=True) closest_data_table = DataTable(source=display_source, columns=closest_columns, width=800, height=800, selectable=False) title = Div(text="""<b>Feedback Finder</b><br><br> The left hand side will allow you to look at ALL feedback for this given app.<br><br> Click on a row to see the closest matches to this row (and the embedding distance of each match) on the right side.<br><br> Try using the search bar to narrow down feedback that you want to find. <br>For example, if you are looking for performance related bug reports, then try typing 'lag' into the search bar, and hitting enter.<br> Then click on one of the results on the left to see other related bits of feedback that do not explicitly mention the word 'lag' on the right.<br><br>""", width=1000, height=180) layout = column( title, row(column(str_search_input, data_table), column(closest_data_table))) # output to static HTML file output_file(f"{file_path}.html") save(layout)
# Update the slider value with one day before current date def animate_update_slider(): # Extract date from slider's current value date = ... # Subtract one day from date and do not exceed the allowed date range day = ... ... timeslider.value = day # Define the callback function of button def animate(): global callback_id if button.label == '► Play': button.label = '❚❚ Pause' callback_id = curdoc().add_periodic_callback(animate_update_slider, 500) else: button.label = '► Play' curdoc().remove_periodic_callback(callback_id) button = Button(label='► Play', width=80, height=40) button.on_click(animate) curdoc().add_root(column(p1, buttons, row(timeslider, button)))
def update(): plot.children[1] = column(create_plots(Estimators))
def __init__(self, worker, height=150, **kwargs): self.worker = worker names = worker.monitor.quantities self.last = 0 self.source = ColumnDataSource({name: [] for name in names}) self.source.data.update(self.get_data()) x_range = DataRange1d(follow='end', follow_interval=20000, range_padding=0) tools = 'reset,xpan,xwheel_zoom' self.cpu = figure(title="CPU", x_axis_type='datetime', height=height, tools=tools, x_range=x_range, **kwargs) self.cpu.line(source=self.source, x='time', y='cpu') self.cpu.yaxis.axis_label = 'Percentage' self.mem = figure(title="Memory", x_axis_type='datetime', height=height, tools=tools, x_range=x_range, **kwargs) self.mem.line(source=self.source, x='time', y='memory') self.mem.yaxis.axis_label = 'Bytes' self.bandwidth = figure(title='Bandwidth', x_axis_type='datetime', height=height, x_range=x_range, tools=tools, **kwargs) self.bandwidth.line(source=self.source, x='time', y='read_bytes', color='red') self.bandwidth.line(source=self.source, x='time', y='write_bytes', color='blue') self.bandwidth.yaxis.axis_label = 'Bytes / second' # self.cpu.yaxis[0].formatter = NumeralTickFormatter(format='0%') self.bandwidth.yaxis[0].formatter = NumeralTickFormatter(format='0.0b') self.mem.yaxis[0].formatter = NumeralTickFormatter(format='0.0b') plots = [self.cpu, self.mem, self.bandwidth] if not WINDOWS: self.num_fds = figure(title='Number of File Descriptors', x_axis_type='datetime', height=height, x_range=x_range, tools=tools, **kwargs) self.num_fds.line(source=self.source, x='time', y='num_fds') plots.append(self.num_fds) if 'sizing_mode' in kwargs: kw = {'sizing_mode': kwargs['sizing_mode']} else: kw = {} if not WINDOWS: self.num_fds.y_range.start = 0 self.mem.y_range.start = 0 self.cpu.y_range.start = 0 self.bandwidth.y_range.start = 0 self.root = column(*plots, **kw) self.worker.monitor.update()
def modify_doc(doc): plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_tools(CustomAction(callback=CustomJS(args=dict(s=source), code=RECORD("data", "s.data")))) button = Button(css_classes=["foo"]) button.js_on_click(CustomJS(args=dict(s=source), code="s.patch({'x': [[1, 100]]})")) doc.add_root(column(button, plot))