Previous and next button move their location

Hi,

I’m using the code of @Charly_Wargnier (A Streamlit app for navigating through inspirational quotes with "Next" and "Previous" buttons. · GitHub) to create previous and next buttons, the problem is when I press next button the graphs move to the top of the application, this is the aspect before of plotting:

After of first run:

And after of press next button:

Now the plot is in the top, before of sider bars.

With respect to the @Charly_Wargnier code, I’ve implement some modifications like:

Almacenar df_graph1 en el estado de la sesión

st.session_state.df_graph1 = df_graph1

Almacenar df_graph2 en el estado de la sesión

st.session_state.df_graph2 = df_graph2

st.session_state.tkstats = tkstats

Almacenar el contador en el estado de la sesión

st.session_state.count = 0

Mostrar la gráfica actual según el contador

display_current_graph(on)

def next_quote(on):
if st.session_state.count + 1 >= max(len(st.session_state.df_graph1), len(st.session_state.df_graph2)):
st.session_state.count = 0
else:
st.session_state.count += 1
display_current_graph(on)

def previous_quote(on):
if st.session_state.count > 0:
st.session_state.count -= 1
else:
st.session_state.count = max(len(st.session_state.df_graph1), len(st.session_state.df_graph2)) - 1
display_current_graph(on)

Mostrar la gráfica actual según el contador

def display_current_graph(on):
quote = st.session_state.df_graph1[st.session_state.count]
quote2 = st.session_state.df_graph2[st.session_state.count]
quote3 = st.session_state.tkstats[st.session_state.count]

plt.style.use('seaborn-darkgrid')
# Crear dos columnas para colocar las gráficas
col1, col2 = st.columns(2)

with col1:
    plt.figure(figsize=(8, 6))
    plt.plot(quote['time'], quote['Cplasma'],color='black')
    plt.xlabel("Time, days")
    plt.ylabel("Cplasma, uM")
    plt.title(f"Plasma concentration vs. time for dose 1 mg/kg {st.session_state.names[st.session_state.count]}")
    st.pyplot(plt)

with col2:
    plt.figure(figsize=(8, 6))
    plt.scatter(quote2['dose'], quote2['Css'],color='black')
    plt.plot(quote2[quote2['dose'] == 1]['dose'], quote2[quote2['dose'] == 1]['Css'], linestyle='--')  # Línea punteada
    plt.plot(quote2['dose'], quote2['Css'], linestyle='--', color='black')  # Línea sólida
    plt.xlabel("Dose")
    plt.ylabel("Css")
    plt.title(f"CSS vs. daily dose of {st.session_state.names[st.session_state.count]}")
    st.pyplot(plt)

any idea???

1 Like

Do you want your graphs to appear at the bottom of the sliders and the other widgets?

1 Like

No, I want the previous and next buttons to stay below the graphs and not move when I press the next button.

1 Like

Hi @PARODBE

I have tried to recreate your issue and solve it here.

Since I did not have your dataset and your code, I just simulated a scenario like yours by creating some random data and plotted it here. It works fine on my local system. Can you try it once on your system please?

Hope this helps.

1 Like

Thank you so much @ElisonSherton !

But it doesn’t work because I have two list of dataframes, for example df_graph1 contains a list of dataframes with different data and same column and df_graph2 is another list of dataframes with different columns of df_graph1. Moreover, when I press next button graphics disappear since I have a button for running this page. Although is true that when I press run pk analysis button again appear graphs for next compound and the same again, again and again. :

After of pressing my button:

Now this is my code:

            if 'count' not in st.session_state:
                st.session_state.count = 0
            
            st.session_state["tkstats"] = tkstats
            st.session_state["df_graph1"] = df_graph1
            st.session_state["df_graph2"] = df_graph2

            # Now render the figures
            df_graph1 = st.session_state.df_graph1[st.session_state.count]
            df_graph2 = st.session_state.df_graph2[st.session_state.count]
            tkstats = st.session_state.tkstats[st.session_state.count]
            names = st.session_state.names[st.session_state.count]
            # fig, ax = plt.subplots(1, 2, figsize = (4,4))
            col1, _, col2 = st.columns([5,1,5])

            with col1:
                plt.figure(figsize=(8, 6))
                plt.plot(df_graph1['time'], df_graph1['Cplasma'],color='black')

                    # plt.plot(df_graph1['time'], df_graph1['Cplasma'],color='black')
                plt.xlabel("Time, days")
                plt.ylabel("Cplasma, uM")
                plt.title(f"Plasma concentration vs. time for dose 1 mg/kg {names}")
                st.pyplot(plt)
            
            with col2:
                plt.figure(figsize=(8, 6))
                plt.scatter(df_graph2['dose'], df_graph2['Css'],color='black')
                plt.plot(df_graph2[df_graph2['dose'] == 1]['dose'], df_graph2[df_graph2['dose'] == 1]['Css'], linestyle='--')  # Línea punteada
                plt.plot(df_graph2['dose'], df_graph2['Css'], linestyle='--', color='black')  # Línea sólida
                plt.xlabel("Dose")
                plt.ylabel("Css")
                plt.title(f"CSS vs. daily dose of {names}")
                st.pyplot(plt)

            # Then render the next and previous buttons
            col1, _, col2 = st.columns([3, 20, 3])
            with col1:
                if st.button("⏮️ Previous", on_click=previous_field):
                    pass

            with col2:
                if st.button("Next ⏭️", on_click=next_field):
                    pass
            
            if on:
                st.markdown('## <span style="color:black">TK Parameters</span>', unsafe_allow_html=True)
                parameters = ['AUC', 'Peak', 'Mean']
                values = tkstats.values[0]
                for parameter, value in zip(parameters, values):
                    st.markdown(f"- **{parameter}:** {value}", unsafe_allow_html=True)
1 Like

What happens when Run PK Analysis button is clicked? Can you explain the process to me?

If possible can you share that code as well?

Can you explain what is the expected behaviour here? Because if you want the graphs to be displayed automatically, then the solution is just to get rid of the Run PK Analysis button. If it is something else can you please explain what exactly is the intended behaviour?

1 Like

Sorry, but I cannot share the code because I want to publish this app, and moreover it’s a combination between R and python code and It gave me many problems between R, rpy2 and streamlit, and it’s possible that for you’ll be the same. So, I think that It’ll be easy if we try to reproduce something similar…

Let me explain the app. It is a multipage app in which in the first pages I show how it works, in the third page I load the data, and in the fourth page I make a pharmacokinetic analysis in which I execute the button “run pk analysis” to make the call to the R package that makes these analyses and through rpy2 I can obtain the information to pass it to python format. Once I have it, it occurred to me to save it from r to python in lists of dataframes to make it simpler, and then press a next button to visualize the graphs, the problem as I say is that when I press the next button the graph moves above the sliders, it really works well, but it bothers me not knowing why it does that. Is it because of resizing?

1 Like

Can you try assigning the cols explicitly i.e.

...
names = st.session_state.names[st.session_state.count]
# fig, ax = plt.subplots(1, 2, figsize = (4,4))
graph_col1, _, graph_col2 = st.columns([5,1,5])
....

# Then render the next and previous buttons
nav_btn_col1, _, nav_btn_col2 = st.columns([3, 20, 3])
....

Just try and see once if this works.

1 Like

only one thing before of trying, if I save image such as: figure=function() and after st.pyplot(figure) this causes that images disappear and I have to rerun…

1 Like

Hi @ElisonSherton,

I’ve tried and if I implement this code:

I get the next issue:

1 Like

Make df_graph1 = st.session_state.df_graph1[st.session_state.count]

Your df_graph1 is a list I presume as you mentioned earlier, same for df_graph2.

1 Like

Where are your sliders defined?

Streamlit renders everything from top to bottom. So make sure to define them above the rendering of figures.

I cannot see it in the code that you have provided right now, but I hope you get what I am trying to say…

1 Like

Yes, I get them above of the figures, look at:

After comes this:

That part calls to one type of dataset for one single compound but if you load an excel file as in this case:

image

After comes the r code and finally the code that I showed you:

Now, I don’t get the previous error but when I press next button graphs disappear again…

1 Like

When you click on next button the Run PK Analysis button gets deselected; because you can only press one button at any given time on the screen.

Hence as your graph display call is nested under if st.button("Run PK Analysis") hence it is not displayed.

1 Like

That is true, and I set it up so that you can modify the parameters of the sliders and when you modify them you make the run and the calculations start. Any ideas?

1 Like

Before this was working with this code:
image

There is not many differences with respect your code…

1 Like

Can you just move the function definitions of next_quote and previous_quote after the definition of display_current_graph?

1 Like

the same, graphs move above of sliders:

That’s the second drug…

1 Like

Can you do one thing, remove the display_current_graph(on) from next_quote and previous_quote and call this function immediately after it’s defined unconditionally?

1 Like

Sure, just to clarify, in this way?

1 Like