Cross filtering on the dashboard

I am working on creating the Streamlit dashboard. I was able to filter the data based on the single filters.
However I want to have cross filters. For example. I have a customer dashboard.
I want to filter it based on the gender, location etc… at the same time based on the requirement.

If user only wants to filter on the gender, user will click on gender’s male bar, other graphs will return the data only related to male users. Along with that if user wants to filter by location, user will click on the location in that case other graphs will show the data only related to that location.

This kind of cross-filtering is possible with Streamlit?

Absolutely @AdiH, cross-filtering is indeed possible with Streamlit! :raised_hands:

Here is a general approach for cross-filtering using Pandas for data manipulation:

import streamlit as st
import pandas as pd
import plotly

# Load your data (replace with your actual data source)
data = pd.DataFrame({
    'Gender': ['Male', 'Female', 'Male', 'Female', 'Male'],
    'Location': ['NY', 'CA', 'TX', 'NY', 'CA'],
    'Age': [25, 30, 35, 40, 45],
})

gender_filter = st.multiselect('Select Gender', options=list(data['Gender'].unique()), default=list(data['Gender'].unique()))
location_filter = st.multiselect('Select Location', options=list(data['Location'].unique()), default=list(data['Location'].unique()))

filtered_data = data[data['Gender'].isin(gender_filter) & data['Location'].isin(location_filter)]

st.write(filtered_data)

import plotly.express as px
fig = px.bar(filtered_data, x='Location', y='Age', color='Gender')
st.plotly_chart(fig)

I hope that helps! :slight_smile:

Charly

Okay, I couldn’t refrain myself from deploying a quick demo for you! :wink:

Export-1694176602369

Is this what you were after?

Best wishes,
Charly

1 Like

Thanks, Charly, for the quick update and special thanks for the demo.
However, I want a little bit different.
On the click bar, I want to perform this operation. For example, in the demo if the dark blue bar indicates male then on the click of that I want to show the records.

I don’t want this separate filter like you have shown on the top.

Something similar to this as shown in this Tableau dashboard.
https://public.tableau.com/app/profile/sql.liek/viz/shared/S8HPRNM5P
When you click on the age range circle it change the other charts on the screen

Here is an article from my medium about Drill-Downs and Cross filtering in Streamlit using Altair.

6 Likes

Thank you for sharing that, @CarlosSerrano - fantastic article! :raised_hands:

@AdiH for more in-depth info, I also recommend watching @andfanilo’s YT video:

I hope you find it helpful.

Best,
Charly

1 Like

Thanks a lot, Charly and Carlos.
This will help as a starting point for our further implementation.

One more help if any of you can do is, is there any reference code or document to create a Tornado chart in the Streamlit

2 Likes

Glad this helps, @AdiH! :raised_hands:

One more help if any of you can do is, is there any reference code or document to create a Tornado chart in Streamlit?

Sure thing! Here is a simple example that shows you how to create a Tornado chart in Streamlit — this example uses Plotly.

Export-1694420147268

Code:

import streamlit as st
import plotly.graph_objects as go

st.title("Tornado Chart")

variables = ['Variable 1', 'Variable 2', 'Variable 3']
base_case = [100, 200, 300]
low_case = [50, 150, 250]
high_case = [150, 250, 350]

trace1 = go.Bar(
    y=variables,
    x=[base - low for base, low in zip(base_case, low_case)],
    orientation='h',
    name='Low Case',
    text=[f'Low Case: {low}' for low in low_case],
    marker=dict(color='red')
)

trace2 = go.Bar(
    y=variables,
    x=[high - base for high, base in zip(high_case, base_case)],
    orientation='h',
    name='High Case',
    text=[f'High Case: {high}' for high in high_case],
    marker=dict(color='green')
)

layout = go.Layout(
    title='Tornado Chart',
    barmode='relative',
    bargap=0.1,
    bargroupgap=0.1,
    xaxis=dict(title='Value'),
    yaxis=dict(title='Variable'),
)

fig = go.Figure(data=[trace1, trace2], layout=layout)

st.plotly_chart(fig)

I hope this helps. Let me know if you have any questions.

Best wishes,
Charly

1 Like

Thanks, Charly, for all the help and code snippets provided.

I have one more question based on the solutions provided for the Interaction and Tornado implementation. In both the use cases, we are using a plotly.
As you may already know Ploty is already connected with Dash, they are from the same group.
Do you have any comparisons or use cases where Streamlit will be more useful over Dash?

As per my knowledge, Dash also provides similar features that Streamlit provides.

You’re welcome, @AdiH! I’m glad to hear that you found this useful! :hugs:

When it comes to choosing between Dash and Streamlit, I would recommend trying out both to formulate your own opinion. I have to admit, my experience with Dash is pretty limited, so I don’t feel equipped to offer a comprehensive review. That said, it’s definitely a renowned framework and worth exploring.

To help you in making an informed decision, there are numerous comparison articles available online that you might find helpful.

Happy reading!

Best,
Charly

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