Selection Option for Streamlit
eereenah-fast opened this issue · comments
Hello, thanks a lot for sharing your project!
The README
says that the checkbox option is relevant only in the context of Jupyter Notebook. Is there no way of extracting the selection through Streamlit?
Thank you in advance and apologies for the trivial question.
Hi @eereenah-fast,
I haven't tested myself but you could try adding the following to your streamlit code:
if st.button("Show selection"):
st.text(str(mols2grid.selection))
Could you please try and tell me if it works?
Thank you for the quick reply!
Here is the code snippet:
mg = mols2grid.MolGrid(df_result, smiles_col="SMILES")
display = mg.display(subset=["SMILES", "img", "Reward", "Energy"],
tooltip=["Mol_ID", "SMILES"], selection=True,
n_cols=n_cols)
raw_html = display._repr_html_()
components.html(raw_html, width=None, height=600, scrolling=True)
if st.button('Show Selection'):
st.text(str(mols2grid.selection))
This is the result:
From what I've read Streamlit doesn't allow running an ipython kernel (which mols2grid uses to communicate the selections from the JavaScript side to the Python side) so I'm afraid its not possible for now :/
One option would be for me to add a button directly on the grid to copy the selection to the clipboard though. I'll see what I can do, maybe for the next update!
Thanks a lot @cbouy! :))
@eereenah-fast try out the new mols2grid version 0.1.0
and tell me if it works for your needs!
Hi @cbouy,
Saving SMILES/copying to clipboard partially solves my problem, thank you for the update!:) mols2grid has been incredibly helpful.
Does mols2grid.get_selection()
still work only in the context of IPython kernel?
I wanted to extract the selected molecules as a dataframe (I can do that by saving the SMILES but I was wondering if there was a more elegant way).
Yes it needs a kernel to make get_selection
work unfortunately.
However if you copy the selection to the clipboard, you may then be able to do something like this (untested code so there's likely some things to fix in here):
import tkinter
from ast import literal_eval
# get clipboard data as string
r = tkinter.Tk()
sel = r.clipboard_get()
r.withdraw()
r.update()
r.destroy()
# convert to dict
sel = literal_eval(sel)
# get corresponding dataframe content
index = list(sel.keys())
subset = df.iloc[index]
Just put it within a st.button
to print the content of subset
like in my first reply and it should do what you're looking for.
I used pyperclip instead. Works like a charm!
Thanks!
@eereenah-fast Sorry to re-open, but can you share the code you used to dynamically fetch the selection dictionary? I've been trying for a few days & can't get it to work...
Just figured it out! For posterity:
row1_1, row1_2 = st.columns((2,3))
if st.button('Show Selection'):
clipboard = pyperclip.paste()
selection = literal_eval(clipboard)
key = list(selection.keys())
for key in index:
specific_smiles = selection[key]
with row1_2:
image_holder = st.empty()
mol = Chem.MolFromSmiles(specific_smiles)
im=Draw.MolToImage(mol)
image_holder.image(im)