def make_candlesticks_cs(price: pd.DataFrame) -> Figure: TOOLTIPS = [ ("index", "$index"), ("(x,y)", "($x, $y)"), ("open", "@Open"), ("close", "@Close") ] # have to fix y-range here as we are adding extra_y_range later p: Figure = figure( x_axis_type="datetime", tools=TOOLS, plot_width=1000, tooltips=TOOLTIPS, title = "ETH prices", height=400, y_range=(150, price.High.max() * 1.1)) p.grid.grid_line_alpha = 0.7 # this is the basic bokeh data container # even when we pass dataframe, CDS is created under the covers cds = ColumnDataSource(price) # line segment glyphs p.segment("Date", "High", "Date", "Low", color="black", source=cds) # green bar glyphs # you can't pass a mix of data source and iterable values, i.e. df + cds not gonna fly inc_view = CDSView(source=cds, filters=[BooleanFilter(price.Close > price.Open)]) p.vbar("Date", w, "Open", "Close", fill_color="#06982d", line_color="black", source=cds, view=inc_view) # red bar glyphs dec_view = CDSView(source=cds, filters=[BooleanFilter(price.Open > price.Close)]) p.vbar("Date", w, "Open", "Close", fill_color="#ae1325", line_color="black", source=cds, view=dec_view) return p
def get_expenses_table(selected_month=None, category=None): table_columns = [ TableColumn(field='Date', title='Date', formatter=DateFormatter()), TableColumn(field='Description', title='Description'), TableColumn(field='Category', title='Category'), TableColumn(field='Subcategory', title='Subcategory'), TableColumn(field='Cost', title='Cost') ] # which month is currently selected? subset data according to selection if selected_month is None: month_filter = [True] * len(expenses_source.data['Date']) else: source_datetimes = pd.DatetimeIndex(expenses_source.data['Date']) month_filter = [ date.month == selected_month for date in source_datetimes ] month_filter = BooleanFilter(month_filter) # filter for current category if category is None: category_filter = [True] * len(expenses_source.data['Category']) else: category_filter = [ cat == category for cat in expenses_source.data['Category'] ] category_filter = BooleanFilter(category_filter) view = CDSView(source=expenses_source, filters=[month_filter, category_filter]) return DataTable(source=expenses_source, columns=table_columns, view=view, sizing_mode='stretch_both')
def render(**figure_kwargs): figure = Figure(**figure_kwargs) figure.segment(source=onesource, legend_label="OHLC H/L", x0='datetime', x1='datetime', y0='low', y1='high', line_width=1, color='black') updown = [ o < c for o, c in zip(onesource.data['open'], onesource.data['close']) ] figure.vbar( legend_label="OHLC Up", source=onesource, view=CDSView(source=onesource, filters=[BooleanFilter(updown)]), width=(onesource.data['datetime'][1] - onesource.data['datetime'][0]) / 2, x='datetime', bottom='open', top='close', fill_color="#D5E1DD", line_color="black", ) figure.vbar( legend_label="OHLC Down", source=onesource, view=CDSView(source=onesource, filters=[BooleanFilter([not b for b in updown])]), width=(onesource.data['datetime'][1] - onesource.data['datetime'][0]) / 2, x='datetime', top='open', bottom='close', fill_color="#F2583E", line_color="black", ) # point of calling super.__call__() ?? Legend ?? figure.legend.location = "top_left" figure.legend.click_policy = "hide" return figure
def update_bird(attr, old, new): bird = self.select.value bird_aou = int( species[species['english_common_name'] == bird]['aou']) yr = self.slider.value new_bird_df = bird_lookup(bird_aou)[[ 'countrynum', 'statenum', 'route', 'longitude', 'latitude', 'speciestotal', 'routename', 'english_common_name', 'year', 'species_size' ]] print(bird, yr) self.bird_source.data = ColumnDataSource(new_bird_df).data self.booleans = [ True if int(x) == yr else False for x in self.bird_source.data['year'] ] self.view1.filters = [BooleanFilter(booleans)] try: #table_source.data = ColumnDataSource(bird_table_data(yr)).data #wiki_page = wikipedia.page(bird) #image_summary.text = wiki_page.html() self.Elevated.title.text = 'Sightings of ' + str( bird) + ', %d' % yr #data_table.visible = True except: #wiki_page = wikipedia.page(bird) #image_summary.text = wiki_page.html() self.Elevated.title.text = 'Sightings of ' + str( bird) + ', %d' % yr
def make_div_plot(data, symbol=''): data['formatted_ex_date'] = \ [x.strftime("%Y-%m-%d") for x in data.index] source = ColumnDataSource(data) booleans = [not np.isnan(amount) for amount in source.data['div_amount']] div_view = CDSView(source=source, filters=[BooleanFilter(booleans)]) plot = figure( x_axis_type='datetime', plot_height=500, plot_width=1000, ) div_circle = plot.circle( x='index', y='div_amount', source=source, view=div_view, name='Divident Amount', size=7.5, color='maroon', ) hover = HoverTool( renderers=[div_circle], tooltips=[("ex_date", "@formatted_ex_date"), ("amount", "@div_amount")], ) plot.add_tools(hover) plot.title.text = f"{symbol.upper()} Dividend History" if symbol else "Dividend History" plot.legend.location = "top_left" plot.xaxis.axis_label = 'Date' plot.yaxis.axis_label = 'Dividend Amount' plot.ygrid.band_fill_color = "olive" plot.ygrid.band_fill_alpha = 0.1 return plot
def cb_trigger_callback(attr, old, new): data = doc.get_model_by_name('tsne_glyphs').data_source.data filter_bool = [(float(x) in new) for x in data['color']] ds = doc.get_model_by_name('tsne_glyphs').data_source doc.get_model_by_name('tsne_glyphs').view = CDSView( source=ds, filters=[BooleanFilter(filter_bool)])
def update_plot(attrname, old, new): mask = [True] * len(gdf) for key, filter in filter_list.items(): if filter.toggle_.active: mask = mask & (gdf[key] >= filter.slider_.value[0]) & ( gdf[key] <= filter.slider_.value[1]) test_view.filters[0] = BooleanFilter(booleans=mask)
def update_filter(self): """Get mask to filter record by current number of hours for display.""" current_time = dt.datetime.now(self.tz).replace(tzinfo=None) time_filter = (current_time - self.data["datetime"]) < pd.Timedelta(hours=self.hrs) self.data_view.filters = [BooleanFilter(time_filter.values)] return time_filter
def callback_point_view(event): booleans = [ True if frame == im_num[-1] else False for frame in point_labels.data['frame'] ] view = CDSView(source=point_labels, filters=[BooleanFilter(booleans)]) renderer.view = view
def update_filter(self): priority_filter = [] for priority in self.map_data.categories['priority']: priority_filter.append(self.priority_toggles[priority].active) view = CDSView(source=self.table_source, filters=[BooleanFilter(priority_filter)]) self.table.view = view for priority in self.map_data.priorities: self.priority_groups[priority].visible = self.priority_toggles[priority].active self.priority_groups_rect[priority].visible = self.priority_toggles[priority].active
def update_plot(attr, old, new): circle = p.select({"name": "circle"}) src_heatmap.data["total"] = [ i[radio_button.active + 3] for i in src_heatmap.data["aggr_delta_after_eti"] ] booleans = [ True if total > -0.5 and total < 0.5 else False for total in src_heatmap.data["total"] ] circle.view.filters[0] = BooleanFilter(booleans)
def plot_stock_price(stock): p = figure(plot_width=W_PLOT, plot_height=H_PLOT, tools=TOOLS, title="Stock price", toolbar_location='above') inc = stock.data['Close'] > stock.data['Open'] dec = stock.data['Open'] > stock.data['Close'] view_inc = CDSView(source=stock, filters=[BooleanFilter(inc)]) view_dec = CDSView(source=stock, filters=[BooleanFilter(dec)]) # map dataframe indices to date strings and use as label overrides p.xaxis.major_label_overrides = {i+int(stock.data['index'][0]): date.strftime('%b %d') for i, date in enumerate(pd.to_datetime(stock.data["Date"]))} p.xaxis.bounds = (stock.data['index'][0], stock.data['index'][-1]) p.segment(x0='index', x1='index', y0='Low', y1='High', color=RED, source=stock, view=view_inc) p.segment(x0='index', x1='index', y0='Low', y1='High', color=GREEN, source=stock, view=view_dec) p.vbar(x='index', width=VBAR_WIDTH, top='Open', bottom='Close', fill_color=BLUE, line_color=BLUE,source=stock,view=view_inc, name="price") p.vbar(x='index', width=VBAR_WIDTH, top='Open', bottom='Close', fill_color=RED, line_color=RED,source=stock,view=view_dec, name="price") p.legend.location = "top_left" p.legend.border_line_alpha = 0 p.legend.background_fill_alpha = 0 p.legend.click_policy = "mute" p.yaxis.formatter = NumeralTickFormatter(format='$ 0,0[.]000') p.x_range.range_padding = 0.05 p.xaxis.ticker.desired_num_ticks = 40 p.xaxis.major_label_orientation = 3.14/4 # Select specific tool for the plot price_hover = p.select(dict(type=HoverTool)) # Choose, which glyphs are active by glyph name price_hover.names = ["price"] # Creating tooltips price_hover.tooltips = [("Datetime", "@Date{%Y-%m-%d}"), ("Open", "@Open{$0,0.00}"), ("Close", "@Close{$0,0.00}"),("Volume", "@Volume{($ 0.00 a)}")] price_hover.formatters={"Date": 'datetime'} return p
def plot_with_slider(dataframe, country_name, y_axis_name): """" this function takes a dataframe, y-axis name and country as a parameter, creates a plot with a slider and returns the plot. """ # create a figure object with width and height plot = figure(x_axis_type="datetime", width=1000, height=400, sizing_mode='fixed') # creating columnDataSource object, for the dataframes source = ColumnDataSource(dataframe) # initialize the min and max value of the date init_value = (dataframe['Date'].min(), dataframe['Date'].max()) # configuring date range slider with start date end date and value date_range_slider = DateRangeSlider(start=init_value[0], end=init_value[1], value=init_value) date_filter = BooleanFilter(booleans=[True] * dataframe.shape[0]) # not use scientific numbers on Y-axis plot.yaxis.formatter = BasicTickFormatter(use_scientific=False) # whenever a slider value updates. The date range sliders, value changes. date_range_slider.js_on_change( "value", CustomJS(args=dict(f=date_filter, cases_source=source), code="""\ const [start, end] = cb_obj.value; f.booleans = Array.from(cases_source.data['Date']).map(d => (d >= start && d <= end)); // Needed because of https://github.com/bokeh/bokeh/issues/7273 cases_source.change.emit(); """)) # add a circle renderer using the source's two columns. plot.circle(x='Date', y=country_name, source=source, view=CDSView(source=source, filters=[date_filter]), color='Pink', line_width=0.5) # name and field pairs for the Hover tool tooltips = [('Date', '@Date{%F}'), (country_name, "$y{int}")] # formatting scheme of date column formatters = {'@Date': 'datetime'} # create a Hover tool for the figure with the tooltips and specify the formatting scheme plot.add_tools( HoverTool(tooltips=tooltips, formatters=formatters, mode='vline')) plot.title.text_color = "midnightblue" plot.title.text_font_size = "25px" plot.toolbar.active_drag = None plot.toolbar_location = None plot.xaxis.axis_label = 'Date' plot.yaxis.axis_label = y_axis_name return column(plot, date_range_slider)
def plot_stock_price(stock): p = figure(plot_width=W_PLOT, plot_height=H_PLOT, tools=TOOLS, title="Stock price", toolbar_location='above') inc = stock.data['close'] > stock.data['open'] dec = stock.data['open'] > stock.data['close'] view_inc = CDSView(source=stock, filters=[BooleanFilter(inc)]) view_dec = CDSView(source=stock, filters=[BooleanFilter(dec)]) # p.segment(x0='index', x1='index', y0='Low', y1='High', # color=RED, source=stock, view=view_inc) # p.segment(x0='index', x1='index', y0='Low', y1='High', # color=GREEN, source=stock, view=view_dec) p.vbar(x='index', width=VBAR_WIDTH, top='open', bottom='close', fill_color=BLUE, line_color=BLUE, source=stock, view=view_inc, name="price") p.vbar(x='index', width=VBAR_WIDTH, top='open', bottom='close', fill_color=RED, line_color=RED, source=stock, view=view_dec, name="price") p.legend.location = "top_left" p.legend.border_line_alpha = 0 p.legend.background_fill_alpha = 0 p.legend.click_policy = "mute" return p
def make_wind_plot(src): TOOLS = "pan,wheel_zoom,box_select,lasso_select,reset,save,box_zoom" p = figure( width=2 * 900, height=900, title='Layer travel time from ' + file1_name + ' to ' + file2_name, y_axis_label='Time in minutes', x_axis_label='Height from sea level -2600m (approx Paranal) in meters', tools=TOOLS) mypalette = [ '#e41a1c', '#377eb8', '#4daf4a', '#984ea3', '#ff7f00', '#525252', '#a65628', '#f781bf', '#999999' ] legend = [] for i, date_time in enumerate(np.unique(src.data['datetime'])): boolean = np.zeros((len(src.data['datetime'])), dtype=bool) filter_bool = np.where(src.data['datetime'] == date_time) colors = np.unique(src.data['color_line'][filter_bool]).tolist()[0] boolean[filter_bool] = True view = CDSView(source=src, filters=[BooleanFilter(boolean)]) p.line(x='height_over_sea_level -2600m', y='time_predicted', line_width=2, view=view, source=src, color=colors) legend.append( LegendItem(label=src.data['datetime'][boolean][0], renderers=[p.renderers[i]])) legend1 = Legend(items=legend, location='top_right') p.add_layout(legend1) print(src.data['max_corr_lag'].shape) hline = Span(location=src.data['max_corr_lag'][0], dimension='width', line_color='black', line_width=1.5, line_dash='dashed') p.add_layout(hline) for i, h in enumerate([500, 1000, 2000, 4000, 8000, 16000]): vline = Span(location=h, dimension='height', line_color=mypalette[i], line_width=2.5, line_dash='dashed') p.add_layout(vline) return p
def make_price_plot(data, symbol='', add_div=True): source = ColumnDataSource(data) plot = figure( x_axis_type='datetime', plot_height=500, plot_width=1000, ) price_line = plot.line(x='index', y='ohlc_avg', source=source, legend='OHLC AVG', muted_alpha=0.2, name='price') price_hover = HoverTool(renderers=[price_line], mode='vline', tooltips=[ ("open: ", "@open"), ("close: ", "@close"), ("high: ", "@high"), ("low: ", "@low"), ]) plot.add_tools(price_hover) if 'div_amount' in data.columns and add_div: booleans = [ not np.isnan(amount) for amount in source.data['div_amount'] ] div_view = CDSView(source=source, filters=[BooleanFilter(booleans)]) dividend = plot.circle(x='index', y='ohlc_avg', source=source, view=div_view, color='maroon', legend='Dividend', muted_alpha=0.2, size=5, name='div') dividend_hover = HoverTool(renderers=[dividend], tooltips=[ ("dividend amount: ", "@div_amount"), ]) plot.add_tools(dividend_hover) plot.title.text = f"{symbol.upper()} Price" if symbol else "Price" plot.legend.location = "top_left" plot.xaxis.axis_label = 'Date' plot.yaxis.axis_label = 'Price' plot.ygrid.band_fill_color = "olive" plot.ygrid.band_fill_alpha = 0.1 plot.legend.click_policy = "mute" return plot
def dot_marker(p, source, col_name, color): circle_filter = [ True if val != 0 else False for val in source.data[col_name] ] circle_view = CDSView(source=source, filters=[BooleanFilter(circle_filter)]) p.circle(name=col_name, x='DATA', y=col_name, size=10, source=source, color=color, view=circle_view) return p
def plot_stock_price (stock): p = figure (plot_width=W_PLOT, plot_height=H_PLOT, tools=TOOLS, title="Stock price", toolbar_location='above') inc = stock.data['Close'] > stock.data['Open'] dec = stock.data['Open'] > stock.data['Close'] view_inc = CDSView (source=stock, filters=[BooleanFilter (inc)]) view_dec = CDSView (source=stock, filters=[BooleanFilter (dec)]) p.segment (x0='index', x1='index', y0='Low', y1='High', color=RED, source=stock, view=view_inc) p.segment (x0='index', x1='index', y0='Low', y1='High', color=GREEN, source=stock, view=view_dec) p.vbar (x='index', width=VBAR_WIDTH, top='Open', bottom='Close', fill_color=BLUE, line_color=BLUE, source=stock, view=view_inc, name="price") p.vbar (x='index', width=VBAR_WIDTH, top='Open', bottom='Close', fill_color=RED, line_color=RED, source=stock, view=view_dec, name="price") p.legend.location = "top_left" p.legend.border_line_alpha = 0 p.legend.background_fill_alpha = 0 p.legend.click_policy = "mute" # map dataframe indices to date strings and use as label overrides p.xaxis.major_label_overrides = { i + int (stock.data['index'][0]): date.strftime ('%b %d') for i, date in enumerate (pd.to_datetime (stock.data["Date"])) } p.xaxis.bounds = (stock.data['index'][0], stock.data['index'][-1]) # Add more ticks in the plot p.x_range.range_padding = 0.05 p.xaxis.ticker.desired_num_ticks = 40 p.xaxis.major_label_orientation = 3.14 / 4 p.yaxis.formatter = NumeralTickFormatter (format='$ 0,0[.]000') return p
def update_year(attr, old, new): yr = self.slider.value print(yr) self.booleans = [ True if int(x) == yr else False for x in bird_source.data['year'] ] self.view1.filters = [BooleanFilter(self.booleans)] try: #table_source.data = ColumnDataSource(bird_table_data(yr)).data # view = CDSView(source = all_source, filters=[BooleanFilter(booleans)]) self.Elevated.title.text = 'Sightings of ' + str( select.value) + ', %d' % yr #data_table.visible = True except: #table_source.data = ColumnDataSource(None).data self.Elevated.title.text = 'No Sightings of ' + str( select.value) + ', %d' % yr
def bokeh_view(self, ignore_filters=False): """ because we need a new view for each document request... ignore filters allow some glyph renderer not supporting filters to ignore them rendering everything instead of breaking... """ if ignore_filters or self.filter is None: view = CDSView( source=self.model.source) # defaults to complete view. else: boolfilter = [ self.filter(r) for r in self.model.data.itertuples() ] # TODO : This should be recreated at everytick ?!?! # TODO : model iterable on rows ? view = CDSView(source=self.model.source, filters=[BooleanFilter(boolfilter)]) return view
def create_figure(): active = {} for w in sort_widgets: active[w.name] = converters[w.name][w.active] key = '{} {} {}'.format(active['Model'], active['Dataset'], active['Filter']) xrange = sorts[key] alpha_dict = {'Support vector machine': 1.0, 'Random forest': 0.1} color_dict = {'Split': Dark2[5][0], 'Mixed': Dark2[5][1], 'Reverse split': Dark2[5][2], 'US': Dark2[5][3], 'UK': Dark2[5][4]} shape_dict = {'Complete': 'circle', 'Complete filtered': 'diamond', 'Filtered': 'square'} visible_models = [modelboxes.labels[x] for x in modelboxes.active] visible_datasets = [datasetboxes.labels[x] for x in datasetboxes.active] visible_filters = [filterboxes.labels[x] for x in filterboxes.active] height = 600 + (22*(len(visible_models) * len(visible_datasets) * len(visible_filters))) p = figure(x_range=FactorRange(factors=xrange), x_axis_label='Kmer', y_axis_label='Score', plot_width=900, plot_height=height, output_backend='webgl') p.xaxis.major_label_orientation = 3.1415/4 legend = [] for model in visible_models: for dataset in visible_datasets: for f in visible_filters: curr_filter = [GroupFilter(column_name='Model', group=model), GroupFilter(column_name='Dataset', group=dataset), GroupFilter(column_name='Filter', group=f), bools = [True if k in xrange else False for k in source.data['Kmer']] BooleanFilter(bools)] view = CDSView(source=source, filters=curr_filter) alpha = alpha_dict[model] color = color_dict[dataset] shape = shape_dict[f] size=10 glyph = p.scatter(x='Kmer', y='Score', source=source, view=view, color=color, fill_alpha=alpha, size=size, marker=shape) legend.append(("{} {} {}".format(model, dataset, f), [glyph])) p.add_layout(Legend(items=legend), 'below') return p
def get_layout(): """Create layout and app elements.""" data_scr = ColumnDataSource({ "x": np.random.normal(size=(10, )), "y": np.random.normal(size=(10, )) }) columns = [ TableColumn(field="x", title="First"), TableColumn(field="y", title="Second") ] full_table = DataTable(columns=columns, source=data_scr) mask = [True for el in data_scr.data["y"]] data_view = CDSView(source=data_scr, filters=[BooleanFilter(mask)]) filtered_table = DataTable(columns=columns, source=data_scr, view=data_view) lt = layout([[full_table], [filtered_table]]) return data_scr, filtered_table, lt
def draw_heatmap(self, xaxis, source, genes): cds = ColumnDataSource(source) TOOLTIPS = [ ("Sample", "@Sample"), ("Gene", "@Gene"), ("Foldchange", "@mean"), ] p = figure(x_range=xaxis, y_range=FactorRange(factors=genes), frame_width=self._width * len(self._samples), frame_height=self._height * len(self._genes), tooltips=TOOLTIPS) self._heatmap_plot = p p.xaxis.visible = False p.min_border_left = MIN_BORDER_LEFT for gene in genes: view = CDSView( source=cds, filters=[BooleanFilter([x == gene for x in source["Gene"]])]) color = linear_cmap('mean', Viridis256, low=0, high=self._maxvalues.get(gene, 1)) self._linear_color_mapper = color["transform"] p.rect(x='Sample', y='Gene', width=1, height=1, color=color, source=cds, view=view) return p
def periodic_callback(): """Update view.""" mask = np.random.randint(0, 2, (10, ), dtype=bool) view = CDSView(source=data_scr, filters=[BooleanFilter(mask)]) filtered_table.view = view
def plot_stock_price_bar(df, ticker, features): stock = ColumnDataSource(df) p = figure( plot_width=W_PLOT, plot_height=H_PLOT, tools=TOOLS, title=f'Alpha-Vantage Real-Time Stock Price - Bar Chart - {ticker}', x_axis_label='date', y_axis_label='price') p.grid.grid_line_alpha = 0.3 inc = df['Close'] > stock.data['Open'] dec = stock.data['Open'] > stock.data['Close'] view_inc = CDSView(source=stock, filters=[BooleanFilter(inc)]) view_dec = CDSView(source=stock, filters=[BooleanFilter(dec)]) p.segment(x0='index', x1='index', y0='Low', y1='High', color=RED, source=stock, view=view_inc) p.segment(x0='index', x1='index', y0='Low', y1='High', color=GREEN, source=stock, view=view_dec) p.vbar(x='index', width=VBAR_WIDTH, top='Open', bottom='Close', fill_color=BLUE, line_color=BLUE, source=stock, view=view_inc, name="price") p.vbar(x='index', width=VBAR_WIDTH, top='Open', bottom='Close', fill_color=RED, line_color=RED, source=stock, view=view_dec, name="price") # map dataframe indices to date strings and use as label overrides p.xaxis.major_label_overrides = { i + int(stock.data['index'][0]): date.strftime('%b %d') for i, date in enumerate(pd.to_datetime(stock.data["Date"])) } p.xaxis.bounds = (stock.data['index'][0], stock.data['index'][-1]) # Add more ticks in the plot p.x_range.range_padding = 0.05 p.xaxis[ 0].ticker.desired_num_ticks = 40 # ticker is not the same stock ticker but a bokeh axis term p.xaxis.major_label_orientation = 3.14 / 4 # Select specific tool for the plot price_hover = p.select(dict(type=HoverTool)) # Choose, which glyphs are active by glyph name price_hover.names = ['price'] # Creating tooltips price_hover.tooltips = [('Datetime', '@Date{%F}'), ('Open', '@Open{$0,0.00}'), ('Close', '@Close{$0,0.00}'), ('Volume', '@Volume{($0.00 a)}')] price_hover.formatters = {'@Date': 'datetime'} return p
from bokeh.layouts import gridplot from bokeh.models import ColumnDataSource, CDSView, BooleanFilter from bokeh.plotting import figure, show source = ColumnDataSource(data=dict(x=[1, 2, 3, 4, 5], y=[1, 2, 3, 4, 5])) booleans = [True if y_val > 2 else False for y_val in source.data['y']] view = CDSView(source=source, filters=[BooleanFilter(booleans)]) tools = ["box_select", "hover", "reset"] p = figure(plot_height=300, plot_width=300, tools=tools) p.circle(x="x", y="y", size=10, hover_color="red", source=source) p_filtered = figure(plot_height=300, plot_width=300, tools=tools, x_range=p.x_range, y_range=p.y_range) p_filtered.circle(x="x", y="y", size=10, hover_color="red", source=source, view=view) show(gridplot([[p, p_filtered]]))
from bokeh.layouts import gridplot from bokeh.models import BooleanFilter, CDSView, ColumnDataSource from bokeh.plotting import figure, output_file, show output_file("linked_selection_subsets.html") x = list(range(-20, 21)) y0 = [abs(xx) for xx in x] y1 = [xx**2 for xx in x] # create a column data source for the plots to share source = ColumnDataSource(data=dict(x=x, y0=y0, y1=y1)) # create a view of the source for one plot to use view = CDSView(filters=[ BooleanFilter([True if y > 250 or y < 100 else False for y in y1]) ]) TOOLS = "box_select,lasso_select,hover,help" # create a new plot and add a renderer left = figure(tools=TOOLS, width=300, height=300, title=None) left.circle('x', 'y0', size=10, hover_color="firebrick", source=source) # create another new plot, add a renderer that uses the view of the data source right = figure(tools=TOOLS, width=300, height=300, title=None) right.circle('x', 'y1', size=10, hover_color="firebrick", source=source,
def modify_doc(doc): im_num = [ 0, ] images = [ np.pad(im, ((max_height - im.shape[0], 0), (0, max_width - im.shape[1])), 'constant') for im in ims ] plot, source = bootcamp_utils.viz.bokeh_imshow(images[im_num[-1]], return_im=True) source = source.data_source booleans = [ True if frame == im_num[-1] else False for frame in point_labels.data['frame'] ] view = CDSView(source=point_labels, filters=[BooleanFilter(booleans)]) renderer = plot.scatter(x='x', y='y', source=point_labels, view=view, color=point_tool_color, size=point_size) columns = [ TableColumn(field="x", title="x"), TableColumn(field="y", title="y"), TableColumn(field='frame', title='frame') ] table = DataTable(source=point_labels, columns=columns, editable=True, height=table_height) draw_tool = PointDrawTool(renderers=[renderer], empty_value=im_num[-1]) plot.add_tools(draw_tool) plot.add_tools(CrosshairTool(line_alpha=crosshair_tool_alpha)) plot.toolbar.active_tap = draw_tool def update_image(new_ind): _, data = bootcamp_utils.viz.bokeh_imshow(images[new_ind], return_im=True) data = data.data_source source.data = data.data def callback_point_view(event): booleans = [ True if frame == im_num[-1] else False for frame in point_labels.data['frame'] ] view = CDSView(source=point_labels, filters=[BooleanFilter(booleans)]) renderer.view = view def callback_slider(attr, old, new): update_image(new) im_num.append(int(new)) draw_tool.empty_value = im_num[-1] callback_point_view('tap') def callback_button(direction): new = im_num[-1] + direction if (((len(images) - 1) < new and direction == 1) or (new == -1 and direction == -1)): return None update_image(new) im_num.append(new) draw_tool.empty_value = im_num[-1] callback_point_view('tap') slider = Slider(start=0, end=len(images), value=0, step=1, title="Frame Number") slider.on_change('value', callback_slider) button_back = Button(label='back', button_type="success") button_back.on_click(partial(callback_button, direction=-1)) button_forward = Button(label='forward', button_type="success") button_forward.on_click(partial(callback_button, direction=1)) plot.on_event('tap', callback_point_view) doc.add_root( column(row(slider), plot, row(button_back, button_forward), table))
def plot_multi_hail_hist( hist_data: Dict[str, hl.Struct], title: str = "Plot", log: bool = False, fill_color: Dict[str, str] = None, outlier_fill_color: Dict[str, str] = None, line_color: str = "#033649", hover_mode: str = "mouse", hide_zeros: bool = False, alpha: float = None, ) -> bokeh.plotting.Figure: """ Plot multiple histograms on the same plot. Each histogram can (and should) come straight from ht.aggregate(hl.agg.hist(ht.data, start, end, bins)) Example usage: .. code-block:: python plot_multi_hail_hist(ht.aggregate(hl.agg.group_by(ht.pop, hl.agg.hist(ht.data, start, end, bins)))) :param hist_data: Data to plot :param title: Plot title :param log: Whether the y-axis should be log :param fill_color: Color to fill the histogram bars that fall within the hist boundaries :param outlier_fill_color: Color to fill the histogram bars that fall outside the hist boundaries :param line_color: Color of the lines around the histogram bars :param hover_mode: Hover mode; one of 'mouse' (default), 'vline' or 'hline' :param hide_zeros: Remove hist bars with 0 count :param alpha: Alpha value (if None, then 1.0/len(hist_data) is used) :return: Histogram plot """ low = int(log) if alpha is None: alpha = 1.0 / len(hist_data) if fill_color is None: color_palette = d3["Category10"][max(3, len(hist_data))] fill_color = { hist_name: color_palette[i] for i, hist_name in enumerate(hist_data.keys()) } if outlier_fill_color is None: outlier_fill_color = fill_color p = (figure(title=title, y_axis_type="log", tools=TOOLS) if log else figure(title=title, tools=TOOLS)) hists = [] for label, hist in hist_data.items(): data = {} distance = abs(hist.bin_edges[0] - hist.bin_edges[1]) data["top"] = [x + low for x in hist.bin_freq] data["left"] = hist.bin_edges[:-1] data["right"] = hist.bin_edges[1:] data["color"] = [fill_color[label]] * len(hist.bin_freq) if hist.n_smaller > 0: data["top"].insert(0, hist.n_smaller + low) data["left"].insert(0, hist.bin_edges[0] - distance) data["right"].insert(0, hist.bin_edges[0]) data["color"].insert(0, outlier_fill_color[label]) if hist.n_larger > 0: data["top"].append(hist.n_larger + low) data["left"].append(hist.bin_edges[-1]) data["right"].append(hist.bin_edges[-1] + distance) data["color"].append(outlier_fill_color[label]) data["bottom"] = [low] * len(data["top"]) data["label"] = [label] * len(data["top"]) hist_source = ColumnDataSource(data) # pylint: disable=unsubscriptable-object hide_zeros_filter = BooleanFilter( [top > 0 for top in hist_source.data["top"]]) view = (CDSView(source=hist_source, filters=[hide_zeros_filter]) if hide_zeros else CDSView(source=hist_source)) hists.append(( label, [ p.quad( top="top", bottom="bottom", left="left", right="right", source=hist_source, view=view, fill_color="color", alpha=alpha, line_color=line_color, ) ], )) tooltips = [("bin", "$index"), ("bin_edges", "(@left, @right)"), ("freq", "@top")] if len(hist_data) > 1: tooltips.insert(0, ("label", "@label")) p.add_layout( Legend( items=hists, location=(0, 0), orientation="horizontal", click_policy="hide", ), "above", ) p.select_one(HoverTool).tooltips = tooltips p.select_one(HoverTool).mode = hover_mode num_data_points = sum([sum(x.bin_freq) for x in hist_data.values()]) p.add_layout(Title(text=f"({num_data_points:,} data points)"), "above") return p
def figures_chisq_simple(init_group, df_chisq): df_chisq["case_ma07"] = df_chisq["case_ma07"] / 1000 df_chisq["threshold_min_eps"] = df_chisq["threshold_min_eps"] / 1000 df_chisq["threshold_max_eps"] = df_chisq["threshold_max_eps"] / 1000 source = ColumnDataSource(df_chisq) gf = GroupFilter(column_name='CountryProv', group=init_group) view1 = CDSView(source=source, filters=[gf]) booleans = [ True if float(case_detrended) >= 0 else False for case_detrended in source.data['case_detrended'] ] t1_view = CDSView(source=source, filters=[gf, BooleanFilter(booleans)]) booleans = [ True if float(case_detrended) < 0 else False for case_detrended in source.data['case_detrended'] ] t2_view = CDSView(source=source, filters=[gf, BooleanFilter(booleans)]) p_b1_tooltip = [ ("Date", "@Date{%F}"), ("Thresholds Min", "@threshold_min_eps"), ("Thresholds Max", "@threshold_max_eps"), ("Positive Cases", "@case_ma07"), ] p_b2_tooltip = [ ("Date", "@Date{%F}"), ("Detrended Cases", "@case_detrended"), ] p_formatters = {'@Date': 'datetime'} plot_size_and_tools = { 'tools': ['box_select', 'reset', 'help', 'box_zoom'], 'x_axis_type': 'datetime' } # FIXME couldnt do p_a1.line below, so using hack of varea p_b1 = figure(title="Positive cases", **plot_size_and_tools) c_b1b = p_b1.varea(x='Date', y1='threshold_min_eps', y2='threshold_max_eps', source=source, color='grey', view=view1, legend_label="Range of 14-day expectation") c_b1a = p_b1.circle(x='Date', y='case_ma07', source=source, color='red', view=view1, legend_label="7-day average") p_b2 = figure( title="7-day moving average cases minus thresholds -> Excess cases", **plot_size_and_tools) c_b2a = p_b2.scatter(x='Date', y='case_detrended', source=source, color='#73b2ff', legend_label="Above Threshold", view=t2_view) c_b2a = p_b2.scatter(x='Date', y='case_detrended', source=source, color='#ff7f7f', legend_label="Below Threshold", view=t1_view) editplotcolors(p_b1) editplotcolors(p_b2) p_b1.xaxis.axis_label = 'Date' p_b1.yaxis.axis_label = 'Positive Cases (in thousands)' p_b2.xaxis.axis_label = 'Date' p_b2.yaxis.axis_label = 'Detrended Number of Cases' p_b2.x_range = p_b1.x_range p_b1.add_tools(HoverTool(tooltips=p_b1_tooltip, formatters=p_formatters)) p_b2.add_tools(HoverTool(tooltips=p_b2_tooltip, formatters=p_formatters)) p_b1.legend.location = 'top_left' p_b1.legend.background_fill_alpha = 0.8 p_b1.legend.background_fill_color = "#262626" p_b1.legend.border_line_alpha = 0 p_b1.legend.label_text_color = "whitesmoke" p_b2.legend.background_fill_alpha = 0.8 p_b2.legend.background_fill_color = "#262626" p_b2.legend.border_line_alpha = 0 p_b2.legend.label_text_color = "whitesmoke" p_b2.legend.location = 'bottom_left' return source, c_b1b, p_b1, p_b2