How to display selectbox inline

I am working on a streamlit app to let users accept or reject the NER tags generated from a model. I want the selectbox to be displayed next to the tags within the text, as shown in the screenshot below:

Any advice on how to implement this using st.selectbox() would be greatly appreciated.

That is way beyon the standard layout capabilities that streamlit offers. I gues you could create a custom component, though.

1 Like

If you are not looking for that exact same look, you could cycle through columns while writing pairs of st.markdown and st.selectbox in a couple of nested columns. Here’s an example using stanza:

Check it out at Community Cloud here

Code:
import streamlit as st
import stanza
from itertools import cycle
from collections import namedtuple

st.set_page_config(layout="wide")

## Coloring settings
Color = namedtuple("Color", ["bg", "c"])
formatting = {
    "B" : Color(bg="#FF000050", c="red"),
    "O" : Color(bg="#EE82EE50", c="violet"),
    "I" : Color(bg="#FFA50050", c="orange"),
    "E" : Color(bg="#0000FF50", c="blue"),
    "S" : Color(bg="#00FF0050", c="green"),
}

def color_tag(token):
    """
    Returns a colored token text and NER
    """
    first_letter = token.ner[0]
    colors = formatting.get(first_letter, None)

    if colors:
        return f"""<mark style="background-color: {colors.bg};">{token.text}</mark><br> :{colors.c}[{token.ner}]"""
    else:
        return f"""{token.text}\n{token.ner}"""

@st.cache_data
def process_text(text:str):
    nlp = stanza.Pipeline(lang='en', processors='tokenize,ner')
    doc = nlp(text)
    return doc

"## πŸ’¬ Text analysis tokenization and NER"

with st.form("Submit text for analysis:"):
    
    text = st.text_area(
        "Input text:", 
        value="Chris Manning teaches at Stanford University. He lives in the Bay Area.",
        max_chars=1_000)
    
    submit_button = st.form_submit_button("Submit")

doc = process_text(text)
options = ["Undecided", "Decided"]

if submit_button:
    
    "****"
    "### πŸ“— Results:"

    for i, sentence in enumerate(doc.sentences, start=1):
        
        with st.expander(f"Sentence {i}: **{sentence.text}**"):

            main_cols = st.columns(3)
            cycle_cols = cycle(main_cols)

            for col, (j, token) in zip(cycle_cols, enumerate(sentence.tokens)):
                with col:
                    cols = st.columns([1,1.5])
                    with cols[0]: 
                        st.markdown(color_tag(token), unsafe_allow_html=True)
                    with cols[1]: st.selectbox(f"Selectbox_{i},{j}", options=options, label_visibility="collapsed")
1 Like

Hi edsaac, thank you very much for sharing a working example of presenting a tag and select box in two columns. The end-users prefer the look in my screenshot because it allows them to easily read the whole sentence and determine whether to accept or reject the tag.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.