Randomizing Order of Appearance in App


I am building an app which shows user various graphs. Each of these graphs is bound to a selectbox, which the user chooses an option from to determine the slope of the line shown on the corresponding graph. Is there a way to make it so that the graphs I have show up in random order only the first time that I load the page? My current code is copied below, but it has two issues: 1) The selectboxes all show up at the end, instead of above their corresponding graph, and 2) the page reloads and the graphs reshuffle each time the user chooses something from the dropdown menu, but I only want them to be randomly generated once and then stay consistent.

slot1 = st.empty()
slot2 = st.empty()
slot3 = st.empty()
states = ["ny", "flor", "tex"]

# We want to display them in a random order for each user
i = 1
options = ["actual", "less_steep_1", "less_steep_2", "less_steep_3", 
                      "less_steep_4", "less_steep_5", "steeper_1", "steeper_2", 
                      "steeper_3", "steeper_4", "steeper_5"]
full_names = {"ny" : "New York", "flor" : "Florida", "tex" : "Texas"}

def display_chart(state_trendlines_df, type, slot):
  test = state_trendlines_df[state_trendlines_df["Type"] == type]
  test["image_url"] = test["image_url"].fillna("") #necessary because dataframe gets messed up when exporting
  base = create_base_log_layer(test, 'Day', 'Confirmed')
  img = create_image_layer(test, 'Day', 'Confirmed', 'image_url')
  slot.altair_chart(base + img)

for state in states:
  generated_trendlines = pd.read_csv("data/{state_name}_generated_trendlines.csv".format(state_name=state))
  if i == 1:
    selectbox1 = record(st.selectbox, "Log Scale (Before)")
    type = selectbox1('Select an option for {full_state_name}.'.format(full_state_name=full_names[state]), options=options)
    display_chart(generated_trendlines, type, slot1)
    i += 1
  elif i == 2:
    selectbox2 = record(st.selectbox, "Log Scale (Before)")
    type = selectbox2('Select an option for {full_state_name}.'.format(full_state_name=full_names[state]), options=options)
    display_chart(generated_trendlines, type, slot2)
    i += 1
  elif i == 3:
    selectbox3 = record(st.selectbox, "Log Scale (Before)")
    type = selectbox3('Select an option for {full_state_name}.'.format(full_state_name=full_names[state]), options=options)
    display_chart(generated_trendlines, type, slot3)
    i += 1

To implement behaviors that depend on the run, you are going to need to use the sessionstate method to be able to track whether the page has yet been run for the users session.

OR you could use the get/set query parameters to transition from an initial configuration to the next. After the first run, the app would set the query parameters which would then affect how the app runs a second time by reading the parameters with get and acting accordingly. You could even have some kind of “default” random parameters and when the slider is changed the parameters in the URL get updated.

1 Like