Horizontal Stacked Bar Chart


Hi, i am new at Streamlit and i need your help. I want a stacked bar chart from my DataFrame. My DataFrame looks like this

and the Chart like this

Steps to reproduce

Code snippet:

ser1 = pd.melt(df_selection_day, id_vars=['Datum'], value_vars=['HasFrontAndRearDetect','HasOnlyFrontDetect','HasOnlyRearDetect'], value_name='detect')

bar_chart = alt.Chart(ser1).mark_bar().encode(y="Datum", x='detect')

st.altair_chart(bar_chart, use_container_width=True)

The first problem i had that i was not able to add more than one column to the x Axis. So i used pd.melt to make my DataFrame from wide to long. That works but unfortunatly when i hover over the bar only the value_name=‘detect’ will show

i would like to have it in this way

in this screenshot i only used 1 Value

bar_chart = alt.Chart(ser1).mark_bar().encode(y="Datum", x='HasFrontAndRearDetect')

and i am also not able to set a color for these 3 Values i need.

Can some of you show me how to get a stacked bar chart with different colors and when i hover over the chart to see the name of the Value?

Thanks a lot


Hi @Michael_Faske, welcome to the forum!

It sounds like this is more of an Altair question than a Streamlit question, so you might have better luck posting somewhere more generally than this forum.

Have you tried adding “color” and “tooltip” arguments to the chart, like in this example? Simple Scatter Plot with Tooltips — Altair 4.2.0 documentation

If that doesn’t work, and it appears to be a streamlit issue, could you please post a complete minimal reproducible script that shows the issue?

Hey @blackary ,

thanks for your answer. Meanwhile i found a solution for my problem.

I used the piviot function to reorder my Dataframe

df_selection_long_day = df_calc_byDay.set_index('Datum')
df_selection_long_day = df_calc_byDay.pivot(index="Datum", columns='Direction', values=['HasFrontAndRearDetect','HasOnlyFrontDetect','HasOnlyRearDetect']).reset_index()

and created the Chart

bar_chart_day =alt.Chart(df_selection_long_day).transform_fold(['HasFrontAndRearDetect','HasOnlyFrontDetect','HasOnlyRearDetect']).mark_bar(clip=True).encode(

    x=alt.X('value:Q',stack='zero' , scale=alt.Scale(domain=(80,100))),

Works great :slight_smile:

1 Like