Retaining same session in all pages with pandas dataframe and st.session_state

Hello :grinning:,

I have two questions:

  1. I have managed to send the pandas dataframe to the second page dynamically: when the user changes the tickers, the pandas dataframe updates. Is this the correct way to do it?

  2. when I go back to page 1 the page loads again triggering the st.multiselect default selection. How can I retain the tickers selected by the user? example: page 1 loads with the default tickers: GOOG,AAPL user adds another ticker: TSLA and then navigates to page 2, when he returns to page 1 we want to keep his/her selection (all three tickers GOOG,AAPL and TSLA). how can we achieve that?

please see sample code:

page 1:

import pandas as pd
import streamlit as st
import yfinance as yf

default_tickers =  ['GOOG','AAPL']
stocks = ['GOOG','AAPL','TSLA','MSFT','AMZN']

st.write("### Select Stocks:")
multiselection = st.multiselect(options= stocks, label= 'multiselect', \
    default= default_tickers \
    )

start = pd.to_datetime('2021/10/06')
end = pd.to_datetime('2022/10/06')

# Read data 
df = yf.download(multiselection,start,end)['Close']

if 'key' not in st.session_state:
    st.session_state['key'] = df

st.session_state.key = df

def print_df():
    df = st.write(st.session_state.key)
    return df

st.write(print_df())

page 2:

import sys
import path

# directory reach
directory = path.Path(__file__).abspath()
# setting path
sys.path.append(directory.parent)
#from my_modules.hide_head_foot import hide

import streamlit as st
from sessionstate import print_df


df = print_df()

st.write(df)

Theoretically, you should be able to do this by setting a key="something" on the multiselect, but unfortunately there’s a bug that prevents that from working when you switch pages widget state not synced between multiple pages · Issue #4989 · streamlit/streamlit · GitHub

But, you can accomplish what you’re looking for by manually keeping the selected stock options in session state, as well as the stock data. Here’s one way to do it:

page1

import pandas as pd
import streamlit as st
import yfinance as yf

default_tickers = ["GOOG", "AAPL"]
stocks = ["GOOG", "AAPL", "TSLA", "MSFT", "AMZN"]

st.write("### Select Stocks:")

if "stock_options" not in st.session_state:
    st.session_state["stock_options"] = default_tickers

multiselection = st.multiselect(
    options=stocks,
    label="multiselect",
    default=st.session_state["stock_options"],
)

st.session_state["stock_options"] = multiselection

start = pd.to_datetime("2021/10/06")
end = pd.to_datetime("2022/10/06")

# NOTE: This isn't required, but will make the app automatically reuse the data once it's been loaded the first time
@st.experimental_memo
def get_data(stocks, start, end):
    df = yf.download(stocks, start, end)["Close"]
    return df


df = get_data(multiselection, start, end)

st.session_state["key"] = df

st.write(st.session_state["key"])

page2

import streamlit as st

df = st.session_state["key"]

st.write(df)
1 Like

Hey @blackary ,

thank you very much for the workaround! The code works :smiley: .
Is there a way I can get informed when the bug is fixed?

Y.

Yup! You can either add a comment about your use-case if you think it’s different from what’s already been written, or you can hit the Subscribe button on the right

2 Likes