slider.js_on_change( 'value', sliderCallback(source_sample, depth_sample, slider, slider_af, syngroup, unique_longitudinal_muts)) syngroup.js_on_change( 'active', sliderCallback(source_sample, depth_sample, slider, slider_af, syngroup, unique_longitudinal_muts)) ose.js_on_change( 'value', sliderCallback2(source_sample, depth_sample, slider, slider_af, syngroup, ose, unique_longitudinal_muts)) # When mousing over Bokeh plot, allele frequency updated to user input. if (user_af != -123): slider_af.value = user_af ## g.js_on_event(events.PlotEvent, sliderCallback(source_sample, depth_sample, slider, slider_af, syngroup)) genome_plot.js_on_event( events.MouseEnter, sliderCallback(source_sample, depth_sample, slider, slider_af, syngroup, unique_longitudinal_muts)) # Creates labels with read information reads_info = (reads.loc[reads['Sample'] == name.strip()]) div = Div(text="""<font size="2" color="gray"><b>Total reads: </b>""" + str(reads_info.iloc[0]["Total"]) + """<br><b>Total reads mapped: </b>""" + str(reads_info.iloc[0]["Mapped"]) + """<br><b>Percentage of reads mapped: </b> """ + str(reads_info.iloc[0]["Percentage"]) + """</font>""", width=300,
def interactive_hist(adata, keys=['n_counts', 'n_genes'], bins='auto', max_bins=100, groups=None, fill_alpha=0.4, palette=None, display_all=True, tools='pan, reset, wheel_zoom, save', legend_loc='top_right', plot_width=None, plot_height=None, save=None, *args, **kwargs): """Utility function to plot distributions with variable number of bins. Params -------- adata: AnnData object annotated data object keys: list(str), optional (default: `['n_counts', 'n_genes']`) keys in `adata.obs` or `adata.var` where the distibutions are stored bins: int; str, optional (default: `auto`) number of bins used for plotting or str from numpy.histogram max_bins: int, optional (default: `1000`) maximum number of bins possible groups: list(str), (default: `None`) keys in `adata.obs.obs_keys()`, groups by all possible combinations of values, e.g. for 3 plates and 2 time points, we would create total of 6 groups fill_alpha: float[0.0, 1.0], (default: `0.4`) alpha channel of the fill color palette: list(str), optional (default: `None`) palette to use display_all: bool, optional (default: `True`) display the statistics for all data tools: str, optional (default: `'pan,reset, wheel_zoom, save'`) palette of interactive tools for the user legend_loc: str, (default: `'top_right'`) position of the legend legend_loc: str, default(`'top_left'`) position of the legend plot_width: int, optional (default: `None`) width of the plot plot_height: int, optional (default: `None`) height of the plot save: Union[os.PathLike, Str, NoneType], optional (default: `None`) path where to save the plot *args, **kwargs: arguments, keyword arguments addition argument to bokeh.models.figure Returns -------- None """ if max_bins < 1: raise ValueError(f'`max_bins` must >= 1') palette = Set1[9] + Set2[8] + Set3[12] if palette is None else palette # check the input for key in keys: if key not in adata.obs.keys() and \ key not in adata.var.keys() and \ key not in adata.var_names: raise ValueError(f'The key `{key}` does not exist in `adata.obs`, `adata.var` or `adata.var_names`.') def _create_adata_groups(): if groups is None: return [adata], [('all',)] combs = list(product(*[set(adata.obs[g]) for g in groups])) adatas= [adata[reduce(lambda l, r: l & r, (adata.obs[k] == v for k, v in zip(groups, vals)), True)] for vals in combs] + [adata] if display_all: combs += [('all',)] adatas += [adata] return adatas, combs # group_v_combs contains the value combinations ad_gs = _create_adata_groups() cols = [] for key in keys: callbacks = [] fig = figure(*args, tools=tools, **kwargs) slider = Slider(start=1, end=max_bins, value=0, step=1, title='Bins') plots = [] for j, (ad, group_vs) in enumerate(filter(lambda ad_g: ad_g[0].n_obs > 0, zip(*ad_gs))): if key in ad.obs.keys(): orig = ad.obs[key] hist, edges = np.histogram(orig, density=True, bins=bins) elif key in ad.var.keys(): orig = ad.var[key] hist, edges = np.histogram(orig, density=True, bins=bins) else: orig = ad[:, key].X hist, edges = np.histogram(orig, density=True, bins=bins) slider.value = len(hist) # case when automatic bins max_bins = max(max_bins, slider.value) # original data, used for recalculation of histogram in JS code orig = ColumnDataSource(data=dict(values=orig)) # data that we update in JS code source = ColumnDataSource(data=dict(hist=hist, l_edges=edges[:-1], r_edges=edges[1:])) legend = ', '.join(': '.join(map(str, gv)) for gv in zip(groups, group_vs)) \ if groups is not None else 'all' p = fig.quad(source=source, top='hist', bottom=0, left='l_edges', right='r_edges', fill_color=palette[j], legend_label=legend if legend_loc is not None else None, muted_alpha=0, line_color="#555555", fill_alpha=fill_alpha) # create callback and slider callback = CustomJS(args=dict(source=source, orig=orig), code=_inter_hist_js_code) callback.args['bins'] = slider callbacks.append(callback) # add the current plot so that we can set it # visible/invisible in JS code plots.append(p) slider.end = max_bins # slider now updates all values slider.js_on_change('value', *callbacks) button = Button(label='Toggle', button_type='primary') button.callback = CustomJS( args={'plots': plots}, code=''' for (var i = 0; i < plots.length; i++) { plots[i].muted = !plots[i].muted; } ''' ) if legend_loc is not None: fig.legend.location = legend_loc fig.legend.click_policy = 'mute' fig.xaxis.axis_label = key fig.yaxis.axis_label = 'normalized frequency' _set_plot_wh(fig, plot_width, plot_height) cols.append(column(slider, button, fig)) if _bokeh_version > (1, 0, 4): from bokeh.layouts import grid plot = grid(children=cols, ncols=2) else: cols = list(map(list, np.array_split(cols, np.ceil(len(cols) / 2)))) plot = layout(children=cols, sizing_mode='fixed', ncols=2) if save is not None: save = save if str(save).endswith('.html') else str(save) + '.html' bokeh_save(plot, save) else: show(plot)
days_from_death = days_from_death[index] rate = rate[index] return ([days_from_death, rate, time]) text1 = Select(title='Sate1', options=list(covid_states.keys())) text2 = Select(title='Param', options=['Positive', 'Active', 'Deaths']) inf_time = Slider(title="Days Spent Infecting Others", value=10.0, start=2, end=20, step=1) text1.value = 'California' text2.value = 'Active' inf_time.value = 12 state = text1.value param = text2.value infection_time = inf_time.value days_from_death, y, time = transform(state, param, infection_time) pred, forcast, forcast_L, forcast_U, y_new, confi = gam_results( days_from_death, y, covid_states[state], 'Active', infection_time) for_dates = time.iloc[-1] + pd.to_timedelta(np.arange(10), unit='d') plot = figure(plot_height=400, plot_width=900, title="Active Infections", tools="crosshair,pan,reset,save,wheel_zoom", x_axis_type="datetime")