Hi everyone,
I am trying to make a data app with multiselect for visualizing data. I want to show a grouped bar chart with three parameters for the clients selected in the multiselect option. However, No matter whichever client I select the graph is shown in the same order as the original data i.e even if I select the 7th client in the multiselect, I still get the graph for the first row in the data frame.
Here’s the code:
DATA_URL= 'C:\\Users\\DELL\\Documents\\soj_data.xlsx'
#@st.cache(persist =True)
def load_data():
data1 = pd.read_excel(DATA_URL)
return data
data = load_data()
st.markdown('### Client Selection, Offers and Joinings')
clients= data['Client']
clients1=clients.to_list()
options=st.multiselect('Client List',clients1)
st.write(data)
selections=data['selections']
offers=data['offers']
joinings=data['joinings']
fig1 = go.Figure()
fig1.add_trace(go.Bar(
x=options,
y=selections,
name='Selections',
marker_color='indianred'
))
fig1.add_trace(go.Bar(
x=options,
y=offers,
name='Offers',
marker_color='lightsalmon'
))
fig1.add_trace(go.Bar(
x=options,
y=joinings,
name='joinings',
marker_color='indianred'
))
# Here we modify the tickangle of the xaxis, resulting in rotated labels.
fig1.update_layout(barmode='group', xaxis_tickangle=-45)
st.plotly_chart(fig1)
Can someone please help me out with this?
Thanks
1 Like
Hello @ira_bajpai,
From what I can see, you’re not slicing the original data correctly based on what options are chosen using the multiselect. Using data I have, I made some corrections your code and it filters the original data as desired.
data = load_data()
st.markdown("### Client Selection, Offers and Joinings")
events = data["event"]
# in the line below, the 'unique()' needs to be specified
# to prevent duplicates being shown in the multiselect
events_list = events.copy().unique().tolist()[-10:] # showing the last 10 events only
options = st.multiselect("Events List", events_list)
st.write(options)
if not options:
filtered_data = data.copy()
else:
filtered_data = data.loc[data["event"].isin(options)]
st.dataframe(filtered_data, width=1000, height=500)
# from this point, only the filtered data is used
comments = filtered_data["comments"]
duration = filtered_data["duration"]
views = filtered_data["views"]
Full Data
Filtered Data
I believe modifying your code as above will get you the desired results.
Cheers.
1 Like
Hi @Outsiders17711 ,
Thankyou It is working fine now, I am still not able to understand exactly what’s happening here, can you please explain?
1 Like
Hello @ira_bajpai, I’m glad I was able to help. I will do my best to explain:
Your aim is to filter the original data based on specific clients’ in the data['Client']
column. Then you do some plots using the selected clients’ and the ['selections']
, ['offers']
and ['joinings']
columns.
There were three mistakes in your code:
- You didn’t filter the original data based on the selected
options
. The lines below might as well not be in your code as they had no effect on the output of the app.
clients= data['Client']
clients1=clients.to_list()
options=st.multiselect('Client List',clients1)
- In the subsequent lines, you still referred to the original data containing all the clients’. Rather, you should be referring to a smaller dataframe that contains only the clients’ chosen in the multiselect. So again, the multiselect is not having any effect on the output of the app.
selections=data['selections']
offers=data['offers']
joinings=data['joinings']
- Finally, when you were plotting, you passed in
x=options,
which will not be compatible with the y=selections,
, y=offers,
and y=joinings,
. Those y
values will contain all the available clients’ in the original data which will be bigger than the smaller number of clients’ contained in options
.
In summary, if you intend to work with a smaller subset of a dataframe, you need to first create a new dataframe containing the smaller subset of data and perfrom any subsequent operations on the new, smaller dataframe.
You did not create a smaller, subset dataframe and you kept referring to the full data which means the multiselect has no effect on your program. I hope that helps.
Cheers.
3 Likes
@Outsiders17711 This is very detailed, Thank you so much for explaining so well.
Cheers
1 Like