Spaces:
Runtime error
Runtime error
Vamsi Thiriveedhi
commited on
Commit
·
d7e211f
1
Parent(s):
2c67485
enh: slider to filter radiomics features values, move violin plots to top
Browse files- filter_data_app.py +40 -27
filter_data_app.py
CHANGED
@@ -39,13 +39,15 @@ def load_data(radiomics_feature='Volume from Voxel Summation'):
|
|
39 |
return df
|
40 |
|
41 |
# Function to filter data based on user input
|
42 |
-
def filter_data(df, filters):
|
43 |
for col, value in filters.items():
|
44 |
if value is not None and col != 'radiomics_feature': # Exclude radiomics_feature from filtering
|
45 |
if col == 'connected_volumes' and value:
|
46 |
df = df.filter((pl.col(col) <= value) & (pl.col(col).is_not_null()))
|
47 |
elif col == 'voxel_num_values' and value:
|
48 |
df = df.filter((pl.col('voxel_num') >= value[0]) & (pl.col('voxel_num') <= value[1]))
|
|
|
|
|
49 |
else:
|
50 |
df = df.filter(pl.col(col) == value)
|
51 |
# Filter based on radiomics feature
|
@@ -94,12 +96,12 @@ def main():
|
|
94 |
st.title("Qualitative Checks of TotalSegmentator Segmentations on NLST")
|
95 |
|
96 |
# Sidebar widgets for navigation and filtering
|
97 |
-
page = st.sidebar.selectbox("Choose a page", ["Summary", "
|
98 |
|
99 |
# Load the data
|
100 |
#df = load_data()
|
101 |
|
102 |
-
if page == "
|
103 |
st.write("Filter the data based on radiomics feature, qualitative checks, bodyPart, and laterality.")
|
104 |
with st.sidebar:
|
105 |
st.title("Filters")
|
@@ -114,7 +116,8 @@ def main():
|
|
114 |
'connected_volumes': None,
|
115 |
'laterality': None,
|
116 |
'radiomics_feature': 'Volume from Voxel Summation', # Default radiomics feature
|
117 |
-
'voxel_num_values': None
|
|
|
118 |
}
|
119 |
|
120 |
filters = st.session_state.filters
|
@@ -129,6 +132,7 @@ def main():
|
|
129 |
'laterality': None,
|
130 |
#'radiomics_feature': 'Volume from Voxel Summation'
|
131 |
'voxel_num_values':None,
|
|
|
132 |
})
|
133 |
st.session_state.filters = filters
|
134 |
|
@@ -185,7 +189,7 @@ def main():
|
|
185 |
filters['bodyPart'] = body_part
|
186 |
|
187 |
# Apply the current filters to update options for other filters
|
188 |
-
filtered_df = filter_data(df, filters)
|
189 |
|
190 |
|
191 |
# Update options for other filters based on the current selection
|
@@ -195,6 +199,7 @@ def main():
|
|
195 |
connected_volumes_options = filtered_df['connected_volumes'].unique().to_list()
|
196 |
laterality_options = [""] + filtered_df['laterality'].unique().to_list()
|
197 |
voxel_num_options = filtered_df.filter(col('voxel_num').is_not_null()).select('voxel_num').unique().to_pandas().iloc[:, 0].tolist()
|
|
|
198 |
|
199 |
laterality = st.selectbox(
|
200 |
"Laterality",
|
@@ -244,9 +249,16 @@ def main():
|
|
244 |
value=(min(voxel_num_options),max(voxel_num_options)),
|
245 |
on_change=lambda: apply_filter('voxel_num_values', st.session_state.voxel_num_values)
|
246 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
247 |
|
248 |
st.session_state.filters = filters
|
249 |
-
filtered_df = filter_data(df, filters)
|
250 |
|
251 |
if laterality:
|
252 |
body_part_df = df.filter((col('bodyPart') == lit(body_part)) & (col('laterality') == lit(laterality)))
|
@@ -278,7 +290,7 @@ def main():
|
|
278 |
start_idx = (page_number - 1) * page_size
|
279 |
end_idx = min(start_idx + page_size, len(filtered_df)) # Ensure end_idx does not go beyond the dataframe length
|
280 |
paginated_df = filtered_df[start_idx:end_idx].to_pandas() # Convert to Pandas DataFrame
|
281 |
-
paginated_df['Viewer Url'] = 'https://viewer.imaging.datacommons.cancer.gov/viewer
|
282 |
|
283 |
# Display the paginated dataframe
|
284 |
st.header("Filtered Data")
|
@@ -288,7 +300,7 @@ def main():
|
|
288 |
paginated_df,
|
289 |
column_config={
|
290 |
"Viewer Url":st.column_config.LinkColumn("StudyInstanceUID",
|
291 |
-
display_text=r"https:\/\/viewer\.imaging\.datacommons\.cancer\.gov\/viewer
|
292 |
),
|
293 |
|
294 |
},
|
@@ -296,25 +308,6 @@ def main():
|
|
296 |
hide_index=True,
|
297 |
use_container_width=True
|
298 |
)
|
299 |
-
st.header("UpSet Plots of Qualitative Checks")
|
300 |
-
# Explanation about the UpSet plot
|
301 |
-
with st.expander("About the UpSet Plot"):
|
302 |
-
st.write("""
|
303 |
-
The UpSet plot is a way to visualize intersections of multiple sets. Each row in the plot represents a different set, and the dots indicate the presence or absence of intersections among these sets. The vertical bars show the size of each intersection, making it easy to see which intersections are most common.
|
304 |
-
""")
|
305 |
-
|
306 |
-
# Create and display the UpSet plot for failed checks
|
307 |
-
st.header("UpSet Plot for Failed Checks")
|
308 |
-
st.write("This plot shows the combinations of checks that failed.")
|
309 |
-
if not filtered_df.is_empty():
|
310 |
-
create_upset_plot_failures(filtered_df)
|
311 |
-
|
312 |
-
# Create and display the UpSet plot for passed checks
|
313 |
-
st.header("UpSet Plot for Passed Checks")
|
314 |
-
st.write("This plot shows the combinations of checks that passed.")
|
315 |
-
if not filtered_df.is_empty():
|
316 |
-
create_upset_plot_passes(filtered_df)
|
317 |
-
|
318 |
# Assuming calculate_std_dev returns a Series
|
319 |
std_dev_before_filtering = calculate_std_dev(body_part_df, radiomics_feature)
|
320 |
std_dev_after_filtering = calculate_std_dev(filtered_df, radiomics_feature)
|
@@ -339,6 +332,26 @@ def main():
|
|
339 |
sns.violinplot(x='Filtering', y=radiomics_feature, data=combined_df, ax=ax)
|
340 |
ax.set_ylabel(f"Standard Deviation of {radiomics_feature}")
|
341 |
st.pyplot(fig2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
342 |
|
343 |
def convert_df(df):
|
344 |
return df.write_csv()
|
|
|
39 |
return df
|
40 |
|
41 |
# Function to filter data based on user input
|
42 |
+
def filter_data(df, filters,radiomics_feature):
|
43 |
for col, value in filters.items():
|
44 |
if value is not None and col != 'radiomics_feature': # Exclude radiomics_feature from filtering
|
45 |
if col == 'connected_volumes' and value:
|
46 |
df = df.filter((pl.col(col) <= value) & (pl.col(col).is_not_null()))
|
47 |
elif col == 'voxel_num_values' and value:
|
48 |
df = df.filter((pl.col('voxel_num') >= value[0]) & (pl.col('voxel_num') <= value[1]))
|
49 |
+
elif col == 'radiomics_feature_values' and value:
|
50 |
+
df = df.filter((pl.col(radiomics_feature) >= value[0]) & (pl.col(radiomics_feature) <= value[1]))
|
51 |
else:
|
52 |
df = df.filter(pl.col(col) == value)
|
53 |
# Filter based on radiomics feature
|
|
|
96 |
st.title("Qualitative Checks of TotalSegmentator Segmentations on NLST")
|
97 |
|
98 |
# Sidebar widgets for navigation and filtering
|
99 |
+
page = st.sidebar.selectbox("Choose a page", ["Summary", "Plots"])
|
100 |
|
101 |
# Load the data
|
102 |
#df = load_data()
|
103 |
|
104 |
+
if page == "Plots":
|
105 |
st.write("Filter the data based on radiomics feature, qualitative checks, bodyPart, and laterality.")
|
106 |
with st.sidebar:
|
107 |
st.title("Filters")
|
|
|
116 |
'connected_volumes': None,
|
117 |
'laterality': None,
|
118 |
'radiomics_feature': 'Volume from Voxel Summation', # Default radiomics feature
|
119 |
+
'voxel_num_values': None,
|
120 |
+
'radiomics_feature_values': None
|
121 |
}
|
122 |
|
123 |
filters = st.session_state.filters
|
|
|
132 |
'laterality': None,
|
133 |
#'radiomics_feature': 'Volume from Voxel Summation'
|
134 |
'voxel_num_values':None,
|
135 |
+
'radiomics_feature_values': None
|
136 |
})
|
137 |
st.session_state.filters = filters
|
138 |
|
|
|
189 |
filters['bodyPart'] = body_part
|
190 |
|
191 |
# Apply the current filters to update options for other filters
|
192 |
+
filtered_df = filter_data(df, filters,radiomics_feature)
|
193 |
|
194 |
|
195 |
# Update options for other filters based on the current selection
|
|
|
199 |
connected_volumes_options = filtered_df['connected_volumes'].unique().to_list()
|
200 |
laterality_options = [""] + filtered_df['laterality'].unique().to_list()
|
201 |
voxel_num_options = filtered_df.filter(col('voxel_num').is_not_null()).select('voxel_num').unique().to_pandas().iloc[:, 0].tolist()
|
202 |
+
radiomics_feature_values = filtered_df.filter(col(radiomics_feature).is_not_null()).select(radiomics_feature).unique().to_pandas().iloc[:, 0].tolist()
|
203 |
|
204 |
laterality = st.selectbox(
|
205 |
"Laterality",
|
|
|
249 |
value=(min(voxel_num_options),max(voxel_num_options)),
|
250 |
on_change=lambda: apply_filter('voxel_num_values', st.session_state.voxel_num_values)
|
251 |
)
|
252 |
+
radiomics_num_values = st.slider(f"{radiomics_feature} Values",
|
253 |
+
min_value=min(radiomics_feature_values),
|
254 |
+
max_value=max(radiomics_feature_values),
|
255 |
+
key='radiomics_feature_values',
|
256 |
+
value=(min(radiomics_feature_values),max(radiomics_feature_values)),
|
257 |
+
on_change=lambda: apply_filter('radiomics_feature_values', st.session_state.radiomics_feature_values)
|
258 |
+
)
|
259 |
|
260 |
st.session_state.filters = filters
|
261 |
+
filtered_df = filter_data(df, filters,radiomics_feature)
|
262 |
|
263 |
if laterality:
|
264 |
body_part_df = df.filter((col('bodyPart') == lit(body_part)) & (col('laterality') == lit(laterality)))
|
|
|
290 |
start_idx = (page_number - 1) * page_size
|
291 |
end_idx = min(start_idx + page_size, len(filtered_df)) # Ensure end_idx does not go beyond the dataframe length
|
292 |
paginated_df = filtered_df[start_idx:end_idx].to_pandas() # Convert to Pandas DataFrame
|
293 |
+
paginated_df['Viewer Url'] = 'https://viewer.imaging.datacommons.cancer.gov/v3/viewer/?StudyInstanceUIDs='+paginated_df['StudyInstanceUID']
|
294 |
|
295 |
# Display the paginated dataframe
|
296 |
st.header("Filtered Data")
|
|
|
300 |
paginated_df,
|
301 |
column_config={
|
302 |
"Viewer Url":st.column_config.LinkColumn("StudyInstanceUID",
|
303 |
+
display_text=r"https:\/\/viewer\.imaging\.datacommons\.cancer\.gov\/v3\/viewer\/\?StudyInstanceUIDs=(.*)"
|
304 |
),
|
305 |
|
306 |
},
|
|
|
308 |
hide_index=True,
|
309 |
use_container_width=True
|
310 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
311 |
# Assuming calculate_std_dev returns a Series
|
312 |
std_dev_before_filtering = calculate_std_dev(body_part_df, radiomics_feature)
|
313 |
std_dev_after_filtering = calculate_std_dev(filtered_df, radiomics_feature)
|
|
|
332 |
sns.violinplot(x='Filtering', y=radiomics_feature, data=combined_df, ax=ax)
|
333 |
ax.set_ylabel(f"Standard Deviation of {radiomics_feature}")
|
334 |
st.pyplot(fig2)
|
335 |
+
|
336 |
+
|
337 |
+
st.header("UpSet Plots of Qualitative Checks")
|
338 |
+
# Explanation about the UpSet plot
|
339 |
+
with st.expander("About the UpSet Plot"):
|
340 |
+
st.write("""
|
341 |
+
The UpSet plot is a way to visualize intersections of multiple sets. Each row in the plot represents a different set, and the dots indicate the presence or absence of intersections among these sets. The vertical bars show the size of each intersection, making it easy to see which intersections are most common.
|
342 |
+
""")
|
343 |
+
|
344 |
+
# Create and display the UpSet plot for failed checks
|
345 |
+
st.header("UpSet Plot for Failed Checks")
|
346 |
+
st.write("This plot shows the combinations of checks that failed.")
|
347 |
+
if not filtered_df.is_empty():
|
348 |
+
create_upset_plot_failures(filtered_df)
|
349 |
+
|
350 |
+
# Create and display the UpSet plot for passed checks
|
351 |
+
st.header("UpSet Plot for Passed Checks")
|
352 |
+
st.write("This plot shows the combinations of checks that passed.")
|
353 |
+
if not filtered_df.is_empty():
|
354 |
+
create_upset_plot_passes(filtered_df)
|
355 |
|
356 |
def convert_df(df):
|
357 |
return df.write_csv()
|