I am having a hard time understanding how to order my streamlit app. There is a select_slider
bar that is used to filter a dataframe and a plotly_event
which displays a chart from the filtered dataframe. I want to link the select_slider
and plotly_event
together but don’t know how to structure my app.
plotly_event
is an interactive object that allows me to click a point on the line chart and record its position within the chart. I am storing information from the clicks using st.session_state
.
When I move the slider, I would like to reload plotly_event
such that there is no cached information from the previous click event on the previous chart. Right now I am stuck because I cannot make the chart until I have the filtered dataframe. I have looked at the select_slider
documentation and on_change
seems close to what I want.
import pandas as pd
import numpy as np
import streamlit as st
import plotly.express as px
from streamlit.state.session_state import SessionState
from streamlit_plotly_events import plotly_events
def df_filter(df):
sel_slider = st.select_slider("Choose a water year",
options = pd.date_range('1894-09-30','2020-09-30', freq = 'A-SEP'),
)
start_date = sel_slider + pd.DateOffset(years=0)
end_date = sel_slider + pd.DateOffset(years=1)
filtered_df = df.loc[(df.date> start_date) & (df.date <= end_date), :]
filtered_df.flow = filtered_df.flow.astype(float)
return filtered_df, end_date.year
if __name__ == '__main__':
st.session_state.count = 0
df = pd.DataFrame(data = {'date':pd.date_range('1983-09-30', '2020-08-01', freq='D'),
'flow':np.random.random(pd.date_range('1983-09-30', '2020-08-01', freq='D').shape)})
filtered_df, end_date = df_filter(df)
fig = px.line(data_frame = filtered_df, x = 'date', y = 'flow')
plot_name_holder = st.empty()
clickedPoint = plotly_events(fig, key=f"line{st.session_state.count}")
if len(clickedPoint) == 1:
st.session_state[str(end_date)] = clickedPoint[0]['x']
plot_name_holder.write(f"Clicked Point: {end_date}, {clickedPoint[0]['x']}")
st.session_state.count +=1