0
votes

I have a script that will plot structure similarity between chemical compounds in a dataset. I want to incorporate 4 bokeh sliders to filter the compounds showing the ones where the slider(s) is true. The problem is that I am new to using bokeh and looking for advice. I have added the sliders to my plot, but am unable to update the plot with the new filters. I want the x and y axis values to remain unchanged. I am wanting to use the slider similar to pandas .loc function in order to filter the dataframe.

Sample data:

SMILES  ChEMBL ID   tsne-1  tsne-2  ROMol    HBA    HBD TPSA    MolWt   FracSP3 logP
0   CS(=O)(=O)Oc1ccc2c(c1)O/C(=C\C=C\c1ccccc1)C2=O  CHEMBL1309068   22.827000   -1.223711   Mol 5   0   69.67   342.056195  0.055556    3.19740
1   Cc1ccccc1N1C(=O)NC(=O)/C(=C/C=C/Nc2ccccc2)C1=O  CHEMBL1517559   -64.257385  -10.908683  Mol 6   2   78.51   347.126991  0.050000    3.13002
2   COC(=O)c1ccc(NC(=O)CSC2=Nc3ccccc3C3CC=NN23)cc1  CHEMBL1478002   -25.157650  11.880555   Mol 7   1   83.36   394.109961  0.200000    3.57880
3   O=C(CSc1ccc(Br)c2cccc(Cl)c12)Nc1ccc(S(=O)(=O)N...   CHEMBL1440953   -49.698872  49.696178   Mol 6   2   88.16   566.914744  0.047619    6.24380
4   C[n+]1ccc(/C=C/c2c[nH]c3ccccc23)cc1.[I-]    CHEMBL1485211   -64.390800  -43.769257  Mol 2   1   19.67   362.027996  0.062500    0.16680

Code example:

source = ColumnDataSource(data=dict(
    x=new_df['tsne-1'],
    y=new_df['tsne-2'],
    desc=new_df['ChEMBL ID'],
    hba=new_df['HBA'],
    hbd=new_df['HBD'],
    tpsa=new_df['TPSA'],
    sp3=new_df['FracSP3'],
    logp=new_df['logP'],
    molwt=new_df['MolWt'],
    svgs=svgs))

mapper1 = linear_cmap(field_name='molwt', palette=Paired[8],low=np.min(molwt), high=np.max(molwt))

s1 = figure(plot_width=500, plot_height=500, title='test')
s1.circle('x', 'y', size=5, source=source, line_color=mapper1,color=mapper1, fill_alpha=1, alpha=0.5)
color_bar = ColorBar(color_mapper=mapper1['transform'], width=8, location=(0,0))
s1.add_layout(color_bar, 'right')

slider1 = Slider(title='MolWt', start=molwt.min(), end=molwt.max(), step=200, value=1)
slider2 = Slider(title='HBA', start=np.min(hba), end=np.max(hba), step=5, value=1)
slider3 = Slider(title='HBD', start=np.min(hbd), end=np.max(hbd), step=5, value=1)
slider4 = Slider(title='TPSA', start=np.min(tpsa), end=np.max(tpsa), step=100, value=1)
    
l1 = column(slider1, slider2, slider3, slider4, s1)
show(l1)

I have tried using a simple update function but it did not work:

def update_slider1(attr, old, new):
    weight = slider.value
    updated_df = new_df[[new_df['MolWt'] <= weight] & [new_df['MolWt'] >= weight-50]] #not working but left in to show desired filtering
    new_data = {
        x:updated_df['tsne-1'], 
        y:updated_df['tsne-2'], 
        desc:updated_df['ChEMBL ID'],
        hba:updated_df['HBA'],
        hbd:updated_df['HBD'],
        tpsa:updated_df['TPSA'],
        sp3:updated_df['FracSP3'],
        logp:updated_df['logP'],
        molwt:updated_df['MolWt'],
        svgs:svgs
    }
    source.data = new_data
slider1.on_change('value',update_slider1)

I believe using CustomJS would work in my case, but I am not sure how to implement it. I have seen examples using CustomJS but I cannot find one similar to my issue.

I am using python 3.6 and bokeh 2.0.2

1

1 Answers

0
votes

Not sure if that's the answer but one thing you can try: weight = slider.value --> you have the value coming from the callback as 'new', no need to pull it from the slider.