I just see the definition of a function. How do you call it? How does the input for
LLok change? How is
I just see the definition of a function. How do you call it? How does the input for
Buttons do not remember their state. They will return
True on the page load resulting from their click, then go back to
False as soon as the user interacts with anything else. Since you put
plotLL(LLok) inside the conditional coming direct from a button, it will go away as soon as the user clicks on anything else.
A couple of recommendations:
I’m not sure how big your csv file is, but as a good habit, I recommend caching your
def list_events(csv_file) function so you aren’t actually re-reading the data each time.
@st.experimental_memo def list_events(csv_file): evl=pd.read_csv(csv_file, sep",",engine='python') return evl.columns[1:].values.tolist() evl_list = list_events('test.csv')
There are several different solutions and ways to restructure this. You could put your inputs into a form so that clicking them won’t rerun the page, but you’d still have the same problem if there are other things on the page a user could interact with.
As a minimal alteration try taking that image information and storing it in session state instead.
At the top of your app, initialize a place in session state to store your image:
if 'image' not in st.session_state: st.session_state.image = None
plotLL function, save the image to session state instead of displaying directly within the function. Change the line
st.session_state.image = image
The at the bottom below the Calculate, make it display the image after executing the function and pulled from session state (which will only get updated with a new click of the Calculate button.
if st.button('Calculate'): plotLL(LLok) if st.session_state.image is not None: st.image(st.session_state.image)
Thank you very much for the help and recommendations.
They do if you use streamlit extras! https://extras.streamlit.app/Stateful%20Button
This is true!
I have continued with my App but I have a new problem, I don’t want the image displayed with the plotLLL function to disappear from the screen when I simply select an option from the checkbox or selectbox, because before I click on the calculate button, the image disappears.
#Libraries from time import time from PIL import Image import matplotlib.pyplot as plt import plotly.figure_factory as ff import streamlit as st from astropy import constants as const from H0live import * if 'image' not in st.session_state: st.session_state.image = None ########################################### title= 'Latest Standard Siren Measurement' st.set_page_config(page_title=r'$H_Website$', initial_sidebar_state= 'expanded',layout="centered") sb = st.sidebar #add LOGO. c1, c2 = st.columns([3, 6]) c1.image('https://yt3.ggpht.com/dsz-32urUxdYKd8a6A2cnmOAo7zCXBtKFXGm_eRjRdYFkqc3IWnKhpAkjY62ATQCLVqLyH7POQ=s900-c-k-c0x00ffffff-no-rj') st.title(title) @st.experimental_memo def list_events(csv_file): ev1=pd.read_csv(csv_file,sep=",",engine='python') return ev1.columns[1:].values.tolist() evl_list = list_events('test.csv') #Menu. Separate events from counterparties ev1_list=list_events('test.csv') LLo= for i in range(len(ev1_list)): if ev1_list[i][0:8] not in LLo: LLo.append(ev1_list[i][0:8]) ctp= for i in range(len(ev1_list)): if ev1_list[i][9:12] not in ctp: ctp.append(ev1_list[i][9:12]) LLok= sb.header("Events") for i in range(len(LLo)): default_value=LLo LLok.append(st.sidebar.checkbox(LLo[i],value=default_value)) stb_list= for i in range(len(LLok)): ctp_list= for x in range(len(ctp)): if LLo[i]+"_"+ctp[x] in ev1_list: ctp_list.append(ctp[x]) stb_list.append(st.selectbox("Counterpart "+str(i+1),ctp_list,key=str(i+1),label_visibility="collapsed")) #To select the desired prior prior_list=['uniform', 'log'] choice = st.selectbox("Priors",prior_list) #H0live action choice_list1= for i in range(len(LLok)): if LLok[i]==True: choice_list1.append(LLo[i]+"_"+stb_list[i]) def plotLL(choice_list1): if choice== 'uniform' or 'log': h0c= H0live(choice_list1, choice) if st.button("Calculate")==True : plotLL(choice_list1) if st.session_state.image is not None: st.image(st.session_state.image) #For the graph # Sidebar sb.header("Related information") sb.markdown("About gravitational wave events: [GraceDB](https://gracedb.ligo.org/api/events/)") sb.markdown( "What is LIGO?: [LIGO](https://www.ligo.org/about.php)") sb.markdown( "How can GW be used to estimate H0? : [Measuring the Expansion of the Universe with Gravitational Waves](https://www.ligo.org/science/Publication-GW170817Hubble/)")
This is what it looks like after clicking the calculate button.
And this is what it looks like when I simply remove an option from the checkbox:
I’ve a page that is structured like this
There are more or less shown 600+ couples of rows that are similar. For a certain condition (depending on the values of the rows) I’m creating a radio button for some couples. I’m ending up with more or less 400 radio buttons. Apart of the fact that the loading of the page is very slow, but every time I click the radio button of a certain couple streamlit reloads the entire page (note that the radio button doesn’t influence the page, so it’s reloading exactly the same page) and it takes ~1 minutes for every radio button and this makes this page unuasble for a user…
Any suggest on how to avoid this? Code snippet here:
Is there a way maybe to cache only the st.write at line 212? This would avoid 80% of the useless reloading of the page. Thanks for helping
Hello! I need some help. I have built a multipage app on streamlit. All the pages load fast except for the homepage. After I have gone to the other pages, I’ve noticed that the homepage reloads entirely when I return to it. Any idea how to fix this? My homepage only has one button which says “logout”
This is really expected behavior from streamlit , when user changes selection on the app ,it triggers re-run . Use st.cache_data for better experience
Hope that you found the solution for your issue. In case that you did not here is some proposal:
As I understood reason why your radio button is takes to much to load is due to data from df (dataframe) that is above your radio buttons. And the second df is also above the second group of radio buttons. So, the time to load those data for df is too long so it also maybe took time to load your button. You could init your df at the place you init it, but to load data at the bottom of the code, so everything else is already init.
Hope that helps!
Hello all, new first post. I think I found a way around this myself working on an app for my company.
Below is a deliberate long running process, 5 seconds that’s executed as part of a page load when you click a button, this also sets a state meaning once the process is done the state of the page is established and all interaction with the website won’t need to do that again.
This works with the exception of a F5 to refresh the page.
My loaded process currently take ~ 480 seconds, I only want this to occur once for each user session that hits our websites. Hopefully I can reduce this…But this certainly lets us move forward knowing there is a load timer, I just added a load timer for any new user that logs into the website.
import streamlit as st # Bring in streamlit for UI/app interface import time def longproc(): for x in range(5): time.sleep(1) x = x +1 peace = st.empty() if 'key' not in st.session_state: with peace: if(st.button("Set Key")): longproc() st.session_state['key'] = 'value' if 'key' in st.session_state: peace.empty() st.write(st.session_state.key) if(st.button("Set New")): st.write("new")
Refreshing the page stars a new session. If you want state persist across sessions, use caching.
I think Streamlit is Awesome, but it needs some features in order to fix this too much rendering and execution bottle necks problem (The caching is a temporal solution I think, there are a lot of objects the caching do not fit well).
- A setup function (only runs first time)
- Rerun widgets calculating its dependency, like modern web apps, this means only re runs the widgets with has a change, that affects its rendering directly or indirectly.
- Or avoiding some widgets to not update its content, only skip in case of some pre calback function bool given by the user.
- Cookies User session caching, I mean to reload the session thread associated with browser data, and reconnect to the corresponding thread and memory session data (sure you have to close multiple tabs open it if you activate)
- Global lock to keep some big processed at a first startup, no first user connection, and keep some processed data, stored in memory or disk.
Maybe a good approach is to program the interface or views, and in other files or the same, the behaviours or interactions between every widgets.
And I know, its not easy, but its needed to have a robust and useful modern web app, I think.
Although I am not very familiar with how to implement it, I support change
Perfect thank you! I’ve been flat out with other work, but tested the @st.cache_data and that has prevented the F5 issue.
import streamlit as st # Bring in streamlit for UI/app interface import time @st.cache_data def longproc(): for x in range(5): time.sleep(1) x = x +1 peace = st.empty() if 'key' not in st.session_state: with peace: if(st.button("Set Key")): longproc() st.session_state['key'] = 'value' if 'key' in st.session_state: peace.empty() st.write(st.session_state.key) if(st.button("Set New")): st.write("new")