import streamlit as st
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import logging
from scipy import stats
from typing import Optional, List
from streamlit_option_menu import option_menu
import spmetatme.plotting as pl
import io
from datetime import datetime
from .utils import display_plot_with_download, display_formatted_table
logger = logging.getLogger(__name__)
def render_differential_reactions(metabolic_adata):
"""Replicated original render_differential_reactions."""
st.markdown("
Differential Metabolic Reactions Analysis
", unsafe_allow_html=True)
tab1, tab2, tab3, tab4 = st.tabs([
"Pathway-Specific Reactions",
"All Differential Reactions",
"Pathways by Variance",
"Differential Pathways"
])
with tab1:
if 'subsystems' not in metabolic_adata.var.columns:
st.error("Pathway information (subsystems) not found in data")
else:
available_pathways = sorted(metabolic_adata.var['subsystems'].unique().tolist())
col1, col2, col3 = st.columns(3)
with col1:
selected_pathway = st.selectbox("Select pathway:", options=available_pathways, key="tab1_path_sel", help="Select a metabolic pathway for differential reaction analysis.")
with col2:
top_n = st.slider("Top N reactions", 5, 20, 10, key="tab1_top_n", help="Filter the number of top significant reactions to display.")
with col3:
row_cluster = st.checkbox("Cluster rows", value=True, key="tab1_cluster")
try:
with st.spinner(f"Analyzing {selected_pathway}..."):
df = pl.plot_differential_reactions_by_pathway_heatmap(
metabolic_adata, selected_pathway, row_cluster=row_cluster, return_marker_df=True, top_n=top_n
)
fig = plt.gcf()
col_p, col_t = st.columns([1.5, 1], gap="small")
with col_p:
display_plot_with_download(fig, f"{selected_pathway.replace(' ', '_')}_Heatmap")
with col_t:
if df is not None:
display_formatted_table(df, "Differential Reactions")
csv = df.to_csv(index=False)
st.download_button("Download CSV", data=csv, file_name=f"{selected_pathway}.csv", mime="text/csv", icon=":material/download:")
except Exception as e:
st.error(f"Error: {e}")
with tab2:
col1, col2 = st.columns(2)
with col1:
top_n = st.slider("Top N reactions:", 5, 20, 10, key="tab2_top_n", help="Number of differentially active reactions to display across all pathways.")
with col2:
row_cluster = st.checkbox("Cluster rows", value=False, key="tab2_cluster")
try:
with st.spinner("Analyzing..."):
df = pl.plot_differential_reactions_heatmap(metabolic_adata, top_n=top_n, row_cluster=row_cluster, return_marker_df=True)
fig = plt.gcf()
col_p, col_t = st.columns([1.5, 1], gap="small")
with col_p: display_plot_with_download(fig, "Diff_Reactions_Heatmap")
with col_t:
if df is not None:
display_formatted_table(df, "Differential Reactions")
except Exception as e:
st.error(f"Error: {e}")
with tab3:
col1, col2 = st.columns(2)
with col1: top_n = st.slider("Top N pathways", 5, 20, 10, key="tab3_top_n", help="Filter top pathways based on the selected metric.")
with col2: sort_by = st.selectbox("Sort by", ["variance", "mean"], key="tab3_sort", help="Metric to rank pathways.")
try:
with st.spinner("Analyzing..."):
df = pl.plot_pathways_flux_heatmap(metabolic_adata, group_key="domain", pathway_key="subsystems", top_n=top_n, sort_by=sort_by)
fig = plt.gcf()
col_p, col_t = st.columns([1.5, 1], gap="small")
with col_p: display_plot_with_download(fig, "Pathways_Var")
with col_t:
if df is not None:
display_formatted_table(df, "Pathways Data")
except Exception as e:
st.error(f"Error: {e}")
with tab4:
col1, col2 = st.columns(2)
with col1:
top_n = st.slider("Top N pathways", 5, 20, 10, key="tab4_top_n", help="Filter top pathways.")
with col2:
row_cluster = st.checkbox("Cluster rows", value=True, key="tab4_cluster")
try:
with st.spinner("Analyzing..."):
df = pl.plot_differential_pathways_heatmap(metabolic_adata, row_cluster=row_cluster, top_n=top_n, return_marker_df= True)
fig = plt.gcf()
col_p, col_t = st.columns([1.5, 1], gap="small")
with col_p: display_plot_with_download(fig, "Pathways_Var")
with col_t:
if df is not None:
display_formatted_table(df, "Differential Pathways")
csv = df.to_csv(index=False)
st.download_button("Download CSV", data=csv, file_name=f"Pathways_Diff.csv", mime="text/csv", icon=":material/download:")
except Exception as e:
st.error(f"Error: {e}")