Skip to content

Commit

Permalink
- New: added result Table after plotting the network of Taxa-Function…
Browse files Browse the repository at this point in the history
…s and Co-Expression.
  • Loading branch information
byemaxx committed Oct 31, 2024
1 parent 69d896a commit e076ceb
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 25 deletions.
7 changes: 3 additions & 4 deletions Docs/ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# Version: 1.116.1
## Date: 2024-10-28
# Version: 1.117.0
## Date: 2024-10-31
### Changes:
- Fix: Fixed the bug of when plot the heatmap of taxa-funcs with t-ststistic and f-statistic, the value still selected as p-value.
- Change: Updated the cookbook.
- New: added result Table after plotting the network of Taxa-Functions and Co-Expression.

# Version: 1.116.0
## Date: 2024-10-18
Expand Down
12 changes: 9 additions & 3 deletions metax/gui/main_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -5170,15 +5170,19 @@ def plot_co_expr(self, plot_type = 'network'):
elif plot_type == 'network':
try:
self.show_message('Co-expression network is plotting...\n\n It may take a long time! Please wait...')
pic = NetworkPlot(self.tfa,
pic, corr_df = NetworkPlot(self.tfa,
show_labels=show_labels,
rename_taxa=rename_taxa,
font_size=font_size,
theme=self.html_theme,
**self.tf_link_net_params_dict
).plot_co_expression_network(df_type= df_type, corr_method=corr_method,
corr_threshold=corr_threshold, sample_list=sample_list, width=width, height=height, focus_list=focus_list, plot_list_only=plot_list_only)
corr_threshold=corr_threshold, sample_list=sample_list,
width=width, height=height, focus_list=focus_list,
plot_list_only=plot_list_only)
self.save_and_show_js_plot(pic, 'co-expression network')
self.update_table_dict(f'co-expression_network({df_type})', corr_df)

except ValueError as e:
if 'sample_list should have at least 2' in str(e):
QMessageBox.warning(self.MainWindow, 'Error', "At least 2 samples are required!")
Expand Down Expand Up @@ -5409,7 +5413,7 @@ def plot_network(self):
try:
self.show_message('Plotting network...')
list_only_no_link = self.checkBox_tf_link_net_plot_list_only_no_link.isChecked()
pic = NetworkPlot(
pic, network_df = NetworkPlot(
self.tfa,
show_labels=show_labels,
rename_taxa=rename_taxa,
Expand All @@ -5425,6 +5429,8 @@ def plot_network(self):
list_only_no_link=list_only_no_link,
)
self.save_and_show_js_plot(pic, 'taxa-func link Network')
self.update_table_dict('taxa-func_network', network_df)

except Exception as e:
error_message = traceback.format_exc()
self.logger.write_log(f'plot_network error: {error_message}', 'e')
Expand Down
70 changes: 54 additions & 16 deletions metax/taxafunc_ploter/network_plot.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from pyecharts import options as opts
from pyecharts.charts import Graph
import pandas as pd
import numpy as np
from typing import Tuple

class NetworkPlot:
def __init__(self, tfobj,
Expand Down Expand Up @@ -60,7 +62,7 @@ def __init__(self, tfobj,
self.show_sub_title = show_sub_title


def modify_focus_list(self, focus_list):
def modify_focus_list(self, focus_list, return_taxa_functions_separately = True):
'''
Split the taxa-func item into taxa and function if it's in the focus_list
'''
Expand All @@ -71,8 +73,12 @@ def modify_focus_list(self, focus_list):
taxa = i.split(' <')[0].split('|')[-1]
func = i.split(' <')[1][:-1]
# i = taxa.split('|')[-1] + ' <' + func + '>'
new_focus_list.append(taxa)
new_focus_list.append(func)
if return_taxa_functions_separately:
new_focus_list.append(taxa)
new_focus_list.append(func)
else:
taxa_func = taxa + ' <' + func + '>'
new_focus_list.append(taxa_func)
else: # taxa item
i = i.split('|')[-1]
new_focus_list.append(i)
Expand All @@ -99,12 +105,13 @@ def create_nodes_links(
- sample_list (list, optional): Specifies which samples to include. If None, all samples are used.
- focus_list (list, optional): List of taxa and functions to highlight in the network.
- plot_list_only (bool, optional): If True, only items and theri linked items in focus_list are plotted.
- strict_list (bool, optional): If True, only items in focus_list are plotted.
- list_only_no_link (bool, optional): If True, only items in focus_list are plotted, not including the links of the focus items.
Returns:
- nodes (list): Information about each node for the graph, including name and size.
- links (list): Information about links between nodes.
- categories (list): Categories for nodes, used for coloring in the graph.
- cytoscape_df (DataFrame): DataFrame containing nodes and links for Cytoscape export.
"""
df = self.tfa.taxa_func_df.copy()
if self.rename_taxa:
Expand All @@ -120,6 +127,16 @@ def create_nodes_links(
print("No sample list provided, using all samples")

df = df.loc[~(df==0).all(axis=1)]

# create network_df for export to cytoscape
network_df = self.tfa.BasicStats.get_stats_mean_df_by_group(df)
network_df['sum'] = network_df.sum(axis=1)
network_df.reset_index(inplace=True)
network_df.columns = ['taxa', 'function'] + network_df.columns.tolist()[2:]
network_df['focus_taxa'] = network_df['taxa'].apply(lambda x: 'Y' if x in focus_list else 'N')
network_df['focus_func'] = network_df['function'].apply(lambda x: 'Y' if x in focus_list else 'N')
# Done creating network_df

df['sum'] = df.sum(axis=1)
df.reset_index(inplace=True)
colname = df.columns.tolist()
Expand All @@ -143,8 +160,7 @@ def create_nodes_links(
df_func['taxa'] = ""
# concatenate the uncovered taxa and functions
df = pd.concat([df_coverd, df_taxa, df_func])



else:
df = df.loc[df['taxa'].isin(focus_list) | df['function'].isin(focus_list)]
print(f"New df shape: {df.shape}")
Expand Down Expand Up @@ -190,7 +206,6 @@ def normalize(value):
{"name": "Focus_Function", "itemStyle": {"normal": {"color": self.func_focus_color}}},
]

return nodes, links, categories

else:
nodes = [{"name": taxon, "category": 0, "symbolSize": normalize(taxa_sum[taxon]), "value": taxa_sum[taxon], "symbol": self.taxa_shape} for taxon in taxa] + \
Expand All @@ -202,7 +217,7 @@ def normalize(value):
{"name": "Function", "itemStyle": {"normal": {"color": self.func_color}}},
]

return nodes, links, categories
return nodes, links, categories, network_df

def plot_tflink_network(
self,
Expand All @@ -212,7 +227,7 @@ def plot_tflink_network(
focus_list: list = None,
plot_list_only: bool = False,
list_only_no_link: bool = False,
):
) -> Tuple[Graph, pd.DataFrame]:
"""
Creates a network graph of taxa and functions using Pyecharts.
Expand All @@ -224,10 +239,11 @@ def plot_tflink_network(
- height (int, optional): Height of the graph in pixels.
- focus_list (list, optional): List of taxa and functions to highlight.
- plot_list_only (bool, optional): If True, only plots items in focus_list and their linked items.
- strict_list_only (bool, optional): If True, only plots items in focus_list.
- list_only_no_link (bool, optional): If True, only plots items in focus_list, not including the links of the focus items.
Returns:
- A Pyecharts Graph object that can be displayed in Jupyter notebooks or web pages.
- A DataFrame containing nodes and links for export to Cytoscape.
"""

# preprocess focus_list
Expand All @@ -244,10 +260,13 @@ def plot_tflink_network(
new_list.extend((taxon, func))
else:
print(f"Warning: {i} is not in taxa or function list")
nodes, links, categories = self.create_nodes_links(sample_list, new_list,plot_list_only, list_only_no_link)
nodes, links, categories, network_df = self.create_nodes_links(sample_list=sample_list,
focus_list = new_list,
plot_list_only = plot_list_only,
list_only_no_link=list_only_no_link)
else:
focus_list = []
nodes, links, categories = self.create_nodes_links(sample_list)
nodes, links, categories, network_df = self.create_nodes_links(sample_list = sample_list)


c = (
Expand Down Expand Up @@ -317,13 +336,20 @@ def plot_tflink_network(
)


return c
return c , network_df


def plot_co_expression_network(self, df_type:str= 'taxa', corr_method:str = 'pearson',
corr_threshold:float=0.5, sample_list:list[str]|None = None,
width:int = 12, height:int = 8, focus_list:list[str] = [], plot_list_only:bool = False,
):
) -> Tuple[Graph, pd.DataFrame]:
"""
Plots a co-expression network based on the correlation matrix of the specified data type.
Returns:
--------
Tuple[Graph, pd.DataFrame]
A tuple containing the network plot (Graph) and the network data frame (pd.DataFrame).
"""
from matplotlib import colormaps
#check sample_list length
if sample_list and len(sample_list) < 2:
Expand All @@ -341,7 +367,7 @@ def plot_co_expression_network(self, df_type:str= 'taxa', corr_method:str = 'pea
print("Renaming taxa to last level")
df = self.tfa.rename_taxa(df)
# modify the focus_list to the last level taxa
focus_list = self.modify_focus_list(focus_list)
focus_list = self.modify_focus_list(focus_list, return_taxa_functions_separately=False)

if extra_cols := sample_list:
print(f"Using sample list provided {extra_cols}")
Expand All @@ -358,6 +384,18 @@ def plot_co_expression_network(self, df_type:str= 'taxa', corr_method:str = 'pea
correlation_matrix = df.corr(method='spearman')
else:
raise ValueError(f"corr_method should be pearson or spearman, but got {corr_method}")

# cerate network_df for export to cytoscape from the correlation matrix
mask = np.triu(np.ones(correlation_matrix.shape), k=1).astype(bool)
network_df = network_df = correlation_matrix.where(mask)
# set index name and header name as item1 and item2
network_df.index.name = f'{df_type}1'
network_df.columns.name = f'{df_type}2'
network_df = network_df.stack().reset_index()
network_df.columns = [ f'{df_type}1', f'{df_type}2', 'correlation']
network_df['item1_focus'] = network_df[f'{df_type}1'].apply(lambda x: 'Y' if x in focus_list else 'N')
network_df['item2_focus'] = network_df[f'{df_type}2'].apply(lambda x: 'Y' if x in focus_list else 'N')
# Done creating network_df

node_sizes = correlation_matrix.apply(lambda x: (x > corr_threshold).sum(), axis=1)
max_node_size = node_sizes.max()
Expand Down Expand Up @@ -491,7 +529,7 @@ def plot_co_expression_network(self, df_type:str= 'taxa', corr_method:str = 'pea
),
)
)
return pic
return pic, network_df



Expand Down
2 changes: 1 addition & 1 deletion metax/utils/version.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
__version__ = '1.116.1'
__version__ = '1.117.0'
API_version = '3'
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "MetaXTools"
version = "1.116.1"
version = "1.117.0"
description = "MetaXTools is a novel tool for linking peptide sequences with taxonomic and functional information in Metaproteomics."
readme = "README_PyPi.md"
license = { text = "NorthOmics" }
Expand Down

0 comments on commit e076ceb

Please sign in to comment.