diff --git a/Macrophages/Macrophages_multiome.py b/Macrophages/Macrophages_multiome.py
new file mode 100644
index 0000000..065f30d
--- /dev/null
+++ b/Macrophages/Macrophages_multiome.py
@@ -0,0 +1,746 @@
+import pandas as pd
+import numpy as np
+import matplotlib.pyplot as plt
+import re
+import math
+import os
+import seaborn as sns
+from sklearn.preprocessing import StandardScaler
+from pathlib import Path
+import scipy.stats as stats
+from scipy.stats import f_oneway
+from statsmodels.stats.multitest import multipletests
+
+# file read path
+file_read_path = r'C:\Users\jymbc\Desktop\python files for SMAD\SMAD_online\data'
+
+# read raw protein files
+df_lfq = pd.read_csv(f'{file_read_path}/all_proteins_after_SSnormalization.csv',index_col=0)
+
+
+def get_co_index(list1, list2):
+ set1 = set(list1)
+ set2 = set(list2)
+ intersection = set1 & set2
+ return list(intersection)
+
+def knn_imputer(df, neighbors=6):
+ '''apply KNN imputation to a dataset'''
+ from sklearn.impute import KNNImputer
+
+ # Initialize the KNNImputer
+ imputer = KNNImputer(n_neighbors=neighbors)
+
+ imputed_df = pd.DataFrame(imputer.fit_transform(df), columns=df.columns, index=df.index)
+ return imputed_df
+
+
+def iterative_imputer(df, maxiteration=10, randomstates=0):
+ from sklearn.impute import IterativeImputer
+
+ # Initialize the IterativeImputer
+ imputer = IterativeImputer(max_iter=maxiteration, random_state=randomstates)
+
+ # Create a new DataFrame with the imputed values
+ imputed_df = pd.DataFrame(imputer.fit_transform(df), columns=df.columns, index=df.index)
+ return imputed_df
+
+
+def standardscaler(df):
+ # # Initialize the StandardScaler
+ scaler = StandardScaler()
+ # Fit and transform the data according to rows
+ scaled_data = scaler.fit_transform(df)
+ scaled_df = pd.DataFrame(scaled_data, index=df.index, columns=df.columns)
+ return scaled_df
+
+
+def calculate_mean(df):
+ # Calculate mean values for each group of columns
+ mean_T1 = df.iloc[:, 0:6].mean(axis=1)
+ mean_T2 = df.iloc[:, 6:12].mean(axis=1)
+ mean_T3 = df.iloc[:, 12:18].mean(axis=1)
+ mean_T4 = df.iloc[:, 18:24].mean(axis=1)
+ # Create a new DataFrame with the calculated means
+ new_df = pd.DataFrame({
+ 'T1': mean_T1,
+ 'T2': mean_T2,
+ 'T3': mean_T3,
+ 'T4': mean_T4
+ })
+ return new_df
+
+def filter_row_missings(df, number):
+ '''Filter protein features and keep proteins with less than "number" missing values, protein features as index.'''
+ # Using isna() to count missing values and keep rows with missing values less than "number"
+ df_filtered = df[df.isna().sum(axis=1) <= number]
+ return df_filtered
+
+def filter_column_missings(df, value):
+ '''Filter samples and keep samples with more than "value" protein identifications, samples as columns.'''
+ # Using notna() to count non-missing values and keep columns with non-missing values more than "value"
+ df_filtered = df.loc[:, df.notna().sum(axis=0) >= value]
+ return df_filtered
+
+# function for oneway_ANOVA analysis
+def oneway_ANOVA_Ttest(result):
+ pval = []
+ for i in range(len(result)):
+ aa = result.iloc[i, :6].tolist()
+ bb = result.iloc[i, 6:12].tolist()
+ cc = result.iloc[i, 12:18].tolist()
+ dd = result.iloc[i, 18:24].tolist()
+ p_value_anova = f_oneway(aa, bb, cc, dd)[1]
+ p_value_ttest = stats.ttest_ind(aa, dd)[1] # ttest between irradiation and control
+ pval.append([result.index[i], p_value_anova, p_value_ttest])
+ fl = pd.DataFrame(pval)
+ fl.columns = ['protein', 'p_value_anova', 'p_value_ttest']
+ return (fl)
+
+# 按行进行标准归一化
+def standardscaler_row(df):
+ scaler = StandardScaler()
+ proname = df.T.columns
+ k = df.T
+ dfdf_pro = scaler.fit_transform(k)
+ # 按行进行标准化后的 dataframe
+ dfpro_stdbyrow = pd.DataFrame(dfdf_pro.T, index=df.index, columns=df.columns)
+ return dfpro_stdbyrow
+
+# set four treatments
+treatment=['Con']*6 + ['LPS']*6 + ['IL_4']*6 + ['IRD']*6
+
+def getdf(protein_name = '1/sp|B2RXS4|PLXB2_MOUSE',df = df_lfq):
+ df_protein_pro = df.loc[protein_name].to_frame()
+ df_protein_pro['treatment'] = treatment
+ df_protein_pro
+ return(df_protein_pro)
+
+import plotly.express as px
+
+def plot_interactive_scatter_box_protein(protein_name='1/sp|B2RXS4|PLXB2_MOUSE', dfdf=df_lfq):
+ df = getdf(protein_name, df=dfdf)
+ # Ensure 'treatment' is treated as a categorical variable
+ # df['treatment'] = df['treatment'].astype('category')
+
+ fig = px.box(df, x='treatment', y=protein_name, points="all",
+ title='Boxplot of protein dysregulation in macrophages',
+ hover_data=['treatment'])
+
+ fig.update_layout(
+ yaxis_title="Score",
+ width=600,
+ height=550,
+ title={'font': {'size': 16, 'family': 'Arial'}},
+ xaxis_title={'font': {'size': 16, 'family': 'Arial'}},
+ # yaxis_title={'font': {'size': 14, 'family': 'Arial'}},
+ font={'size': 12, 'family': 'Arial'},
+ legend_title={'font': {'size': 14}},
+ legend={'font': {'size': 14}},
+ # xaxis={'categoryorder': 'category ascending'}
+ )
+ return fig
+
+# read significantly dysregulated metabolites
+
+df_meta_ori = pd.read_csv(f'{file_read_path}/metabolome_dysregu_sig_macro_withnames.csv',index_col=0)
+df_meta = df_meta_ori.iloc[:,:-1]
+
+def get_medf(metabolite_name = 'His-Pro ',df = df_meta):
+ df_metabolite_pro = df.loc[metabolite_name].to_frame()
+ df_metabolite_pro['treatment'] = treatment
+ df_metabolite_pro
+ return(df_metabolite_pro)
+
+def plot_interactive_scatter_box_metabolite(metabolite_name='His-Pro ', dfdf=df_meta):
+ df = get_medf(metabolite_name, df=dfdf)
+ fig = px.box(df, x='treatment', y=metabolite_name, points="all",
+ title='Boxplot of metabolite dysregulation in macrophages', hover_data=['treatment'])
+
+ fig.update_layout(
+ yaxis_title="Score",
+ width=600,
+ height=550,
+ title={'font': {'size': 16, 'family': 'Arial'}},
+ xaxis_title={'font': {'size': 16, 'family': 'Arial'}},
+ # yaxis_title={'font': {'size': 14, 'family': 'Arial'}},
+ font={'size': 14, 'family': 'Arial'},
+ legend_title={'font': {'size': 14}},
+ legend={'font': {'size': 14}}
+ )
+ return fig
+
+# read significantly dysregulated multiome dataset
+df_mean_multi_clustered = pd.read_csv(f'{file_read_path}/df_multi_macrophages_mean_with6clusters.csv',index_col=0)
+
+def get_Kmeans(df, molecular_name):
+ kmeans_value = int(df.loc[molecular_name, 'kmeans'])
+ return kmeans_value
+
+# get co-regulated molecules dataframe
+def select_df_of_same_cluster(df, molecular_name):
+ """
+ Filters the DataFrame based on the kmeans value of the selected molecular name.
+ Parameters:
+ - df: The DataFrame to filter.
+ - molecular_name: The name of the molecule to select.
+ Returns:
+ - filtered_df: The filtered DataFrame.
+ """
+ try:
+ # Check if the molecule exists in the DataFrame
+ if molecular_name in df.index:
+ kmeans_value = df.loc[molecular_name, 'kmeans']
+ filtered_df = df[df['kmeans'] == kmeans_value].iloc[:, :4] # Select first 4 columns
+ return filtered_df
+ else:
+ return pd.DataFrame() # Return an empty DataFrame if molecule not found
+ except Exception as e:
+ # General exception handling
+ print(f"An error occurred: {e}")
+ return pd.DataFrame()
+
+# select_df_of_same_cluster(df_mean_multi_clustered, '1/sp|B2RXS4|PLXB2_MOUSE')
+
+def plot_corr_heatmap_selected_molecules(molecular_name):
+ if molecular_name is not None:
+ tar_df = select_df_of_same_cluster(df_mean_multi_clustered, molecular_name).T
+ if not tar_df.empty:
+ # Assuming that the DataFrame has numerical values suitable for a heatmap
+ heatmap_fig = px.imshow(
+ tar_df,
+ text_auto=True, # Automatically display correlation values on the heatmap
+ aspect="auto",
+ color_continuous_scale='RdBu_r', # Red-Blue color scale for better visualization of positive and negative correlations
+ zmin=-1.5, # Minimum value for the color scale
+ zmax=1.5, # Maximum value for the color scale
+ labels=dict(x="Molecule", y="Treatment", color="Z-score"),
+ x=tar_df.columns,
+ y=tar_df.index,
+ title=""
+ )
+ # Update layout for better aesthetics
+ heatmap_fig.update_layout(
+ width=1400,
+ height=400,
+ margin=dict(l=100, r=100, t=100, b=100),
+ xaxis_title=" ",
+ yaxis_title=" ",
+ title_x=0.5, # Center the title
+ font={'size': 16, 'family': 'Arial'},
+ )
+ heatmap_fig.update_xaxes(showticklabels=False)
+ return heatmap_fig
+ # Return an empty figure if no data is available
+ return {}
+
+def process_data_for_table(molecular_name):
+ """
+ Helper function to process the DataFrame for the DataTable.
+ """
+ filtered_df = select_df_of_same_cluster(df_mean_multi_clustered, molecular_name)
+ if not filtered_df.empty:
+ # Reset the index to convert it into a column
+ reset_df = filtered_df.reset_index()
+ # Optionally, rename the index column for clarity
+ reset_df.rename(columns={'index': 'Index'}, inplace=True)
+ # Convert DataFrame to dictionary format for DataTable
+ data = reset_df.to_dict('records')
+ # Define table columns including the new index column
+ columns = [{"name": col, "id": col} for col in reset_df.columns]
+ return columns, data, ""
+ else:
+ return [], [], f"Selected {molecular_name} is not significantly dysregulated in all treatments!!!"
+
+
+def extract_unique_gene_names(gene_list):
+ """
+ Extract unique gene names from a list of input strings, ensuring the output list is the same length as the input list.
+
+ Parameters:
+ gene_list (list): List of strings containing multiple gene entries.
+
+ Returns:
+ list: List of gene names extracted from the input strings, maintaining the same length as the input list.
+ """
+ gene_names = set()
+ result_genes = []
+ pattern = re.compile(r'\|([A-Za-z0-9]+)_[A-Za-z]+\b')
+
+ for entry in gene_list:
+ # Find all matches of the pattern in the current string
+ matches = pattern.findall(entry)
+ selected_gene = None
+ if matches:
+ for gene in matches:
+ if gene not in gene_names:
+ gene_names.add(gene)
+ selected_gene = gene
+ break
+ # If no new gene is found, select the first gene in the list
+ if not selected_gene:
+ selected_gene = matches[0]
+ else:
+ # If no matches are found, keep the original input string
+ selected_gene = entry
+ result_genes.append(selected_gene)
+
+ return result_genes
+
+# get gene to pathway reflection
+dfdf = df_mean_multi_clustered.copy()
+dfdf.index = extract_unique_gene_names(df_mean_multi_clustered.index)
+gene_value_dict = dfdf.iloc[:,:4].to_dict(orient='index')
+meta_gene = dfdf.iloc[-73:,:]
+# list(meta_gene[meta_gene['kmeans']==0].index)
+
+import networkx as nx
+import plotly.graph_objs as go
+import ast
+
+def plot_network_figure(df, gene_value_dict):
+ # creat a nx graph
+ G = nx.Graph()
+ # add nodes
+ pathways = df['Term'].tolist()
+ G.add_nodes_from(pathways, type='pathway')
+ # add nodes and edge
+ for _, row in df.iterrows():
+ pathway = row['Term']
+ genes = row['Genes']
+ for gene in genes:
+ values = gene_value_dict.get(gene, {'Con': 0, 'LPS': 0, 'IL_4': 0, 'IRD': 0})
+ G.add_node(gene, type='gene') # 添加基因节点
+ G.add_edge(gene, pathway) # 添加基因与通路之间的边
+
+ # 定位节点(使用 spring 布局)
+ pos = nx.spring_layout(G, k=0.7, seed=42) # 增大 k 值以增大节点间距
+ # 提取边的坐标
+ edge_x = []
+ edge_y = []
+ for edge in G.edges():
+ x0, y0 = pos[edge[0]]
+ x1, y1 = pos[edge[1]]
+ edge_x.extend([x0, x1, None])
+ edge_y.extend([y0, y1, None])
+
+ edge_trace = go.Scatter(
+ x=edge_x, y=edge_y,
+ line=dict(width=2, color='#888'),
+ hoverinfo='none',
+ mode='lines'
+ )
+ # 提取节点的坐标、颜色和标签
+ node_x = []
+ node_y = []
+ node_color = []
+ node_labels = []
+ node_size = []
+ node_hovertext = []
+ for node, data in G.nodes(data=True):
+ x, y = pos[node]
+ node_x.append(x)
+ node_y.append(y)
+ if data['type'] == 'gene':
+ # 获取基因的值
+ values = gene_value_dict.get(node, {'Con': 0, 'LPS': 0, 'IL_4': 0, 'IRD': 0})
+ # 构建悬停信息
+ hover_text = f"Gene: {node}
"
+ for condition, value in values.items():
+ hover_text += f"{condition}: {value}
"
+ node_labels.append(node) # 仅添加基因名称作为标签
+ node_hovertext.append(hover_text) # 添加详细的悬停信息
+ node_color.append('blue') # 设置基因节点颜色
+ node_size.append(10) # 设置基因节点较小的大小
+ else:
+ node_labels.append(node)
+ node_hovertext.append(f"Pathway: {node}")
+ node_color.append('orange') # node color
+ node_size.append(30) # nodesize
+
+ # 创建节点 Trace
+ node_trace = go.Scatter(
+ x=node_x, y=node_y,
+ mode='markers+text',
+ hoverinfo='text',
+ text=node_labels, # show gene or pathways
+ hovertext=node_hovertext, # show Z-scores, hovertext
+ textposition="bottom center",
+ textfont=dict(
+ family="Arial",
+ size=14,
+ color="black"
+ ),
+ marker=dict(
+ color=node_color,
+ size=node_size,
+ opacity=1,
+ line=dict(width=1)
+ )
+ )
+ # 创建 Plotly 图形
+ fig = go.Figure(data=[edge_trace, node_trace],
+ layout=go.Layout(
+ title='
Pathway Network',
+ titlefont_size=16,
+ width=500, # set width 1200
+ height=500, # set height 800
+ showlegend=False,
+ hovermode='closest',
+ margin=dict(b=20, l=5, r=5, t=40),
+ annotations=[dict(
+ text="",
+ showarrow=False,
+ xref="paper", yref="paper")],
+ xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
+ yaxis=dict(showgrid=False, zeroline=False, showticklabels=False))
+ )
+
+ return fig
+
+
+def load_cluster_data(file_path=f'{file_read_path}\Protein_KEGG_enriched_results_clustered_Macrophage.xlsx',
+ cluster_number=0):
+ sheet_name = f'Cluster_{cluster_number}'
+ # Read the sheet corresponding to the cluster number
+ cluster_df = pd.read_excel(file_path, sheet_name=sheet_name)
+
+ # Select 'Term' and 'Genes' columns
+ select_out_df = cluster_df.loc[:, ['Term', 'Genes']]
+ # Convert 'Genes' column to a list using ast.literal_eval
+ select_out_df['Genes'] = select_out_df['Genes'].apply(lambda x: ast.literal_eval(x) if isinstance(x, str) else x)
+
+ return select_out_df
+
+# test files
+# select_df = load_cluster_data(file_path = f'{file_read_path}\Protein_KEGG_enriched_results_clustered_Macrophage.xlsx',
+# cluster_number = get_Kmeans(df_mean_multi_clustered, '1/sp|O08529|CAN2_MOUSE'))
+#
+# # print(select_df['Genes'].apply(type))
+# df_only = select_df.iloc[:5,:]
+# # df
+#
+# tsttt = df_only.copy()
+#
+# tsttt.loc[len(tsttt)] = ['Metabolites', list(meta_gene[meta_gene['kmeans']==get_Kmeans(df_mean_multi_clustered, '1/sp|O08529|CAN2_MOUSE')].index)]
+
+# tsttt
+
+# plot_network_figure(tsttt.iloc[[5]],gene_value_dict)
+
+
+import dash
+from dash import Dash, dcc, html
+from dash.dependencies import Input, Output
+import plotly.express as px
+import threading
+from dash import dash_table
+
+# Initialize Dash app
+app = Dash(__name__)
+
+# Determine valid molecular names present in both df_lfq and df_mean_multi_clustered
+valid_proteins = df_lfq.index.intersection(df_mean_multi_clustered.index)
+valid_metabolites = df_meta.index.intersection(df_mean_multi_clustered.index)
+
+# Define the layout with tabs
+app.layout = html.Div([
+ html.H1("Protein and Metabolome Dysregulation on Macrophages"),
+ dcc.Tabs(id='tabs', value='tab-1', children=[
+ dcc.Tab(label='Protein Scatter-Box Plot', value='tab-1'),
+ dcc.Tab(label='Metabolite Scatter-Box Plot', value='tab-2'),
+ ]),
+ html.Div(id='tabs-content')
+])
+
+
+# Callback to render the content of each tab
+@app.callback(Output('tabs-content', 'children'),
+ Input('tabs', 'value'))
+def render_content(tab):
+ if tab == 'tab-1':
+ return html.Div([
+ # First Row: Scatter Plot and DataTable side by side
+ html.Div([
+ # Left side: Scatter Plot
+ html.Div([
+ html.H2("Protein Scatter Plot with Boxplots"),
+ html.Label("Select protein:"),
+ dcc.Dropdown(
+ id='protein-dropdown',
+ options=[{'label': protein, 'value': protein} for protein in df_lfq.index],
+ value=df_lfq.index[0] if len(df_lfq.index) > 0 else None,
+ style={'width': '80%'}
+ ),
+ dcc.Graph(id='scatter-box-plot-protein')
+ ], style={'width': '45%', 'display': 'inline-block', 'verticalAlign': 'top'}),
+
+ # Right side: DataTable and Message
+ html.Div([
+ html.H3("Co-regulated molecules"),
+
+ # Message Div
+ html.Div(
+ id='protein-message',
+ children="", # Initially empty
+ style={'color': 'red', 'marginBottom': '10px'}
+ ),
+
+ # DataTable
+ dash_table.DataTable(
+ id='protein-data-table',
+ columns=[], # Columns will be populated by callback
+ data=[], # Data will be populated by callback
+ page_size=15, # Display 15 rows per page
+ style_table={'overflowX': 'auto'},
+ style_cell={
+ 'textAlign': 'left',
+ 'padding': '5px'
+ },
+ style_header={
+ 'backgroundColor': 'rgb(230, 230, 230)',
+ 'fontWeight': 'bold'
+ },
+ sort_action='native', # Enable sorting
+ filter_action='native' # Enable filtering
+ )
+ ], style={'width': '45%', 'display': 'inline-block', 'paddingLeft': '2%'})
+ ], style={'display': 'flex', 'flexDirection': 'row', 'justifyContent': 'space-between'}),
+
+ # Second Row: Heatmap spanning full width
+ html.Div([
+ dcc.Graph(
+ id='protein-heatmap',
+ config={'displayModeBar': False}, # Optional: Hide the mode bar
+ style={'marginTop': '40px'} # Add top margin for spacing
+ )
+ ], style={'width': '80%', 'paddingTop': '20px'}),
+
+ # Third Row: Network plot spanning full width
+ html.Div([
+ html.Div([
+ dcc.Graph(
+ id='protein-network-plot-1',
+ config={'displayModeBar': False},
+ style={'marginTop': '40px'}
+ )
+ ], style={'width': '45%', 'display': 'inline-block'}),
+
+ html.Div([
+ dcc.Graph(
+ id='protein-network-plot-2',
+ config={'displayModeBar': False},
+ style={'marginTop': '40px'}
+ )
+ ], style={'width': '45%', 'display': 'inline-block', 'paddingLeft': '5%'})
+ ], style={'width': '80%', 'paddingTop': '20px'})
+ ])
+ elif tab == 'tab-2':
+ return html.Div([
+ # First Row: Scatter Plot and DataTable side by side
+ html.Div([
+ # Left side: Scatter Plot
+ html.Div([
+ html.H2("Metabolite Scatter Plot with Boxplots"),
+ html.Label("Select metabolite:"),
+ dcc.Dropdown(
+ id='metabolite-dropdown',
+ options=[{'label': metabolite, 'value': metabolite} for metabolite in df_meta.index],
+ value=df_meta.index[0] if len(df_meta.index) > 0 else None,
+ style={'width': '80%'}
+ ),
+ dcc.Graph(id='scatter-box-plot-metabolite')
+ ], style={'width': '50%', 'display': 'inline-block', 'verticalAlign': 'top'}),
+
+ # Right side: DataTable and Message
+ html.Div([
+ html.H3("Co-regulated molecules"),
+
+ # Message Div
+ html.Div(
+ id='metabolite-message',
+ children="", # Initially empty
+ style={'color': 'red', 'marginBottom': '10px'}
+ ),
+
+ # DataTable
+ dash_table.DataTable(
+ id='metabolite-data-table',
+ columns=[], # Columns will be populated by callback
+ data=[], # Data will be populated by callback
+ page_size=15, # Display 15 rows per page
+ style_table={'overflowX': 'auto'},
+ style_cell={
+ 'textAlign': 'left',
+ 'padding': '5px'
+ },
+ style_header={
+ 'backgroundColor': 'rgb(230, 230, 230)',
+ 'fontWeight': 'bold'
+ },
+ sort_action='native', # Enable sorting
+ filter_action='native' # Enable filtering
+ )
+ ], style={'width': '38%', 'display': 'inline-block', 'paddingLeft': '2%'})
+ ], style={'display': 'flex', 'flexDirection': 'row', 'justifyContent': 'space-between'}),
+
+ # Second Row: Heatmap spanning full width
+ html.Div([
+ dcc.Graph(
+ id='metabolite-heatmap',
+ config={'displayModeBar': False}, # Optional: Hide the mode bar
+ style={'marginTop': '40px'} # Add top margin for spacing
+ )
+ ], style={'width': '100%', 'paddingTop': '20px'}),
+
+ # Third Row: Network Plots spanning full width
+ html.Div([
+ # First Network Plot
+ html.Div([
+ dcc.Graph(
+ id='metabolite-network-plot-1',
+ config={'displayModeBar': False},
+ style={'marginTop': '40px'}
+ )
+ ], style={'width': '45%', 'display': 'inline-block'}),
+
+ # Second Network Plot
+ html.Div([
+ dcc.Graph(
+ id='metabolite-network-plot-2',
+ config={'displayModeBar': False},
+ style={'marginTop': '40px'}
+ )
+ ], style={'width': '40%', 'display': 'inline-block', 'paddingLeft': '5%'})
+ ], style={'width': '100%', 'paddingTop': '20px'})
+ ])
+
+
+# Callback to update the protein scatter-box plot
+@app.callback(
+ Output('scatter-box-plot-protein', 'figure'),
+ [Input('protein-dropdown', 'value')]
+)
+def update_scatterbox_pro_plot(protein_name):
+ if protein_name is not None:
+ return plot_interactive_scatter_box_protein(protein_name=protein_name, dfdf=df_lfq)
+ else:
+ # Return an empty figure or a placeholder
+ return {}
+
+
+# Callback to update the metabolite scatter-box plot
+@app.callback(
+ Output('scatter-box-plot-metabolite', 'figure'),
+ [Input('metabolite-dropdown', 'value')]
+)
+def update_scatterbox_meta_plot(selected_metabolite):
+ if selected_metabolite is not None:
+ return plot_interactive_scatter_box_metabolite(metabolite_name=selected_metabolite, dfdf=df_meta)
+ else:
+ # Return an empty figure or a placeholder
+ return {}
+
+
+# Callback to update the protein DataTable and Message
+@app.callback(
+ [Output('protein-data-table', 'columns'),
+ Output('protein-data-table', 'data'),
+ Output('protein-message', 'children')],
+ [Input('protein-dropdown', 'value')]
+)
+def update_protein_data_table(protein_name):
+ if protein_name is not None:
+ return process_data_for_table(protein_name)
+ else:
+ return [], [], ""
+
+
+# Callback to update the metabolite DataTable and Message
+@app.callback(
+ [Output('metabolite-data-table', 'columns'),
+ Output('metabolite-data-table', 'data'),
+ Output('metabolite-message', 'children')],
+ [Input('metabolite-dropdown', 'value')]
+)
+def update_metabolite_data_table(metabolite_name):
+ if metabolite_name is not None:
+ return process_data_for_table(metabolite_name)
+ else:
+ return [], [], ""
+
+# Callback to update the Protein Heatmap
+@app.callback(
+ Output('protein-heatmap', 'figure'),
+ [Input('protein-dropdown', 'value')]
+)
+def update_protein_heatmap(protein_name):
+ if protein_name is not None:
+ heatmap_fig = plot_corr_heatmap_selected_molecules(protein_name)
+ return heatmap_fig
+ else:
+ # Return an empty figure or a placeholder
+ return {}
+
+
+# Callback to update the Protein Network Plot
+@app.callback(
+ [Output('protein-network-plot-1', 'figure'),
+ Output('protein-network-plot-2', 'figure')],
+ [Input('protein-dropdown', 'value')]
+)
+
+def update_protein_network_plot(protein_name):
+ if protein_name is not None:
+ file_path = f'{file_read_path}\Protein_KEGG_enriched_results_clustered_Macrophage.xlsx'
+ select_df_for_pro_network = load_cluster_data(file_path, cluster_number = get_Kmeans(df_mean_multi_clustered, protein_name)).iloc[:5,:]
+ mol_network = select_df_for_pro_network.copy()
+ mol_network.loc[len(mol_network)] = ['Metabolites', list(meta_gene[meta_gene['kmeans']==get_Kmeans(df_mean_multi_clustered, protein_name)].index)]
+ select_df_for_meta_network = mol_network.iloc[[5]]
+ network_fig1 = plot_network_figure(select_df_for_pro_network,gene_value_dict)
+ network_fig2 = plot_network_figure(select_df_for_meta_network,gene_value_dict)
+ return network_fig1,network_fig2
+ else:
+ # Return an empty figure or a placeholder
+ return {}
+
+# Callback to update the Metabolite Heatmap
+@app.callback(
+ Output('metabolite-heatmap', 'figure'),
+ [Input('metabolite-dropdown', 'value')]
+)
+def update_metabolite_heatmap(metabolite_name):
+ if metabolite_name is not None:
+ heatmap_fig = plot_corr_heatmap_selected_molecules(metabolite_name)
+ return heatmap_fig
+ else:
+ # Return an empty figure or a placeholder
+ return {}
+
+# Callback to update the Metabolite Network Plots
+@app.callback(
+ [Output('metabolite-network-plot-1', 'figure'),
+ Output('metabolite-network-plot-2', 'figure')],
+ [Input('metabolite-dropdown', 'value')]
+)
+
+def update_metabolite_network_plot(metabolite_name):
+ if metabolite_name is not None:
+ file_path = f'{file_read_path}\Protein_KEGG_enriched_results_clustered_Macrophage.xlsx'
+ select_df_for_pro_network = load_cluster_data(file_path, cluster_number = get_Kmeans(df_mean_multi_clustered, metabolite_name)).iloc[:5,:]
+ mol_network = select_df_for_pro_network.copy()
+ mol_network.loc[len(mol_network)] = ['Metabolites', list(meta_gene[meta_gene['kmeans']==get_Kmeans(df_mean_multi_clustered, metabolite_name)].index)]
+ select_df_for_meta_network = mol_network.iloc[[5]]
+ network_fig1 = plot_network_figure(select_df_for_pro_network,gene_value_dict)
+ network_fig2 = plot_network_figure(select_df_for_meta_network,gene_value_dict)
+ return network_fig1,network_fig2
+ else:
+ # Return an empty figure or a placeholder
+ return {}
+
+# Expose the server variable for deployments
+server = app.server
+# Run the Dash app
+if __name__ == '__main__':
+ app.run_server(debug=False, port=8053)
+
diff --git a/Macrophages/read.txt b/Macrophages/read.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/Macrophages/read.txt
@@ -0,0 +1 @@
+