igormolybog commited on
Commit
1d2c72f
·
verified ·
1 Parent(s): bdd9093

streamlit.errors.StreamlitAPIException: The default value 'Galen Sasaki' is not part of the options.

Browse files

Removed manual defaults for filters in session state; each multiselect now simply uses its full options list as the default.

On Clear All Filters, we reset standing, dept, and mark names for re-initialization.

For Faculty selection, we:

Initialize st.session_state.names to the available names on first load or after clear.

Prune it to remain a subset of the dynamically filtered name_opts.

Use that as the default, so you never get a “default not in options” error.

Files changed (1) hide show
  1. app.py +31 -29
app.py CHANGED
@@ -24,46 +24,50 @@ def wrap_labels(labels, width=40):
24
  # Sidebar: Filters
25
  # ---------------------------------------------------
26
  st.sidebar.title("Filters")
27
- # Ensure session state keys exist
28
- if 'standing' not in st.session_state:
29
- st.session_state.standing = sorted(df['Standing'].dropna().astype(str).unique())
30
- if 'dept' not in st.session_state:
31
- st.session_state.dept = sorted(df['Dept Track'].dropna().astype(str).unique())
32
 
33
- clear = st.sidebar.button("Clear All Filters")
34
- if clear:
35
- st.session_state.standing = sorted(df['Standing'].dropna().astype(str).unique())
36
- st.session_state.dept = sorted(df['Dept Track'].dropna().astype(str).unique())
37
 
38
- standing_opts = sorted(df['Standing'].dropna().astype(str).unique())
39
- dept_opts = sorted(df['Dept Track'].dropna().astype(str).unique())
 
 
 
 
40
 
 
41
  standing_sel = st.sidebar.multiselect(
42
  "Filter by Standing:",
43
- options=standing_opts,
44
- default=st.session_state.standing,
45
  key='standing'
46
  )
47
  dept_sel = st.sidebar.multiselect(
48
  "Filter by Dept Track:",
49
- options=dept_opts,
50
- default=st.session_state.dept,
51
  key='dept'
52
  )
53
 
54
- # Auto-filter names based on filters
55
  mask = (
56
  df['Standing'].astype(str).isin(standing_sel) &
57
  df['Dept Track'].astype(str).isin(dept_sel)
58
  )
59
- name_options = sorted(df.loc[mask, 'Name'].astype(str).unique())
60
 
61
- if 'names' not in st.session_state or clear:
62
- st.session_state.names = name_options
 
 
 
 
63
 
 
64
  name_sel = st.sidebar.multiselect(
65
  "Select Faculty:",
66
- options=name_options,
67
  default=st.session_state.names,
68
  key='names'
69
  )
@@ -73,7 +77,7 @@ name_sel = st.sidebar.multiselect(
73
  # ---------------------------------------------------
74
  st.title("Faculty Heatmap Explorer")
75
 
76
- # 1) Heatmap display
77
  if not name_sel:
78
  st.warning("No faculty selected — please choose at least one.")
79
  fig = px.imshow(
@@ -89,9 +93,9 @@ else:
89
  sum_df = mat if sum_df is None else sum_df.add(mat, fill_value=0)
90
  avg_df = sum_df.div(len(name_sel))
91
 
92
- # Wrap y labels (rows)
93
  wrapped_y = wrap_labels(list(avg_df.index), width=40)
94
- wrapped_x = list(avg_df.columns) # x labels usually short
95
 
96
  fig = px.imshow(
97
  avg_df.values,
@@ -104,11 +108,10 @@ else:
104
  fig.update_yaxes(autorange='reversed')
105
  st.plotly_chart(fig, use_container_width=True)
106
 
107
- # 2) Click-to-list values
108
  st.subheader("Cell Details")
109
  events = plotly_events(fig, click_event=True, key="heatmap")
110
  if events:
111
- # Determine original row & col from pointNumber
112
  n_cols = avg_df.shape[1]
113
  pt = events[0]
114
  pt_num = pt.get('pointNumber', None)
@@ -118,11 +121,9 @@ else:
118
  y_lab = avg_df.index[row_idx]
119
  x_lab = avg_df.columns[col_idx]
120
  else:
121
- # fallback: use string labels (unlikely)
122
- y_lab_wrapped = pt['y']
123
  x_lab = pt['x']
124
- # map back wrapped to original
125
- y_lab = avg_df.index[wrapped_y.index(y_lab_wrapped)]
126
 
127
  # Gather non-zero values
128
  records = []
@@ -138,3 +139,4 @@ else:
138
  st.info("No non-zero values for this cell.")
139
  else:
140
  st.write("Click on a heatmap cell to list faculty and their values.")
 
 
24
  # Sidebar: Filters
25
  # ---------------------------------------------------
26
  st.sidebar.title("Filters")
 
 
 
 
 
27
 
28
+ # Base options
29
+ def_opts = sorted(df['Dept Track'].dropna().astype(str).unique())
30
+ def_stand = sorted(df['Standing'].dropna().astype(str).unique())
 
31
 
32
+ # Clear filters button
33
+ if st.sidebar.button("Clear All Filters"):
34
+ st.session_state.standing = def_stand
35
+ st.session_state.dept = def_opts
36
+ # We'll reinitialize names below
37
+ st.session_state.names = None
38
 
39
+ # Multiselects for filters, store in session_state
40
  standing_sel = st.sidebar.multiselect(
41
  "Filter by Standing:",
42
+ options=def_stand,
43
+ default=def_stand,
44
  key='standing'
45
  )
46
  dept_sel = st.sidebar.multiselect(
47
  "Filter by Dept Track:",
48
+ options=def_opts,
49
+ default=def_opts,
50
  key='dept'
51
  )
52
 
53
+ # Determine available names based on current filters
54
  mask = (
55
  df['Standing'].astype(str).isin(standing_sel) &
56
  df['Dept Track'].astype(str).isin(dept_sel)
57
  )
58
+ name_opts = sorted(df.loc[mask, 'Name'].astype(str).unique())
59
 
60
+ # Initialize or clean session_state.names
61
+ if 'names' not in st.session_state or st.session_state.names is None:
62
+ st.session_state.names = name_opts.copy()
63
+ else:
64
+ # drop any names no longer in options
65
+ st.session_state.names = [n for n in st.session_state.names if n in name_opts]
66
 
67
+ # Faculty selection
68
  name_sel = st.sidebar.multiselect(
69
  "Select Faculty:",
70
+ options=name_opts,
71
  default=st.session_state.names,
72
  key='names'
73
  )
 
77
  # ---------------------------------------------------
78
  st.title("Faculty Heatmap Explorer")
79
 
80
+ # Heatmap
81
  if not name_sel:
82
  st.warning("No faculty selected — please choose at least one.")
83
  fig = px.imshow(
 
93
  sum_df = mat if sum_df is None else sum_df.add(mat, fill_value=0)
94
  avg_df = sum_df.div(len(name_sel))
95
 
96
+ # Wrap labels
97
  wrapped_y = wrap_labels(list(avg_df.index), width=40)
98
+ wrapped_x = list(avg_df.columns)
99
 
100
  fig = px.imshow(
101
  avg_df.values,
 
108
  fig.update_yaxes(autorange='reversed')
109
  st.plotly_chart(fig, use_container_width=True)
110
 
111
+ # Cell details
112
  st.subheader("Cell Details")
113
  events = plotly_events(fig, click_event=True, key="heatmap")
114
  if events:
 
115
  n_cols = avg_df.shape[1]
116
  pt = events[0]
117
  pt_num = pt.get('pointNumber', None)
 
121
  y_lab = avg_df.index[row_idx]
122
  x_lab = avg_df.columns[col_idx]
123
  else:
124
+ y_wrapped = pt['y']
 
125
  x_lab = pt['x']
126
+ y_lab = avg_df.index[wrapped_y.index(y_wrapped)]
 
127
 
128
  # Gather non-zero values
129
  records = []
 
139
  st.info("No non-zero values for this cell.")
140
  else:
141
  st.write("Click on a heatmap cell to list faculty and their values.")
142
+