diff --git a/Docs/ChangeLog.md b/Docs/ChangeLog.md
index a276296..0030b11 100644
--- a/Docs/ChangeLog.md
+++ b/Docs/ChangeLog.md
@@ -1,3 +1,15 @@
+# Version: 1.112.0
+## Date: 2024-09-09
+### Changes:
+- New: Added sub_meta for taxa-func link part.
+- Change: Chnaged the [Get Table] of the taxa-func link part to get the table from the heatmap(values and order).
+
+# Version: 1.111.8
+## Date: 2024-09-08
+### Changes:
+- New: 1. Added Box-Cox method of Data Preprocessing. 2. Added an option to change number of cos of trends clusuter figure.
+
+
# Version: 1.111.7
## Date: 2024-09-06
### Changes:
diff --git a/Docs/MetaX_Cookbook.assets/OTF_Structure.png b/Docs/MetaX_Cookbook.assets/OTF_Structure.png
new file mode 100644
index 0000000..72a301c
Binary files /dev/null and b/Docs/MetaX_Cookbook.assets/OTF_Structure.png differ
diff --git a/README.md b/README.md
index 35ec7da..a325cdc 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,15 @@ MetaX also features statistical modules and plotting tools for ana
![abstract](https://github.com/byemaxx/MetaX/raw/main/Docs/MetaX_Cookbook.assets/abstract.png)
-## Taxa-Functions Linkage
+
+## Operational Taxon-Function (OTF)
+
+**Operational Taxon-Function (OTF) Unit**: An operational unit which represents the association between specific taxa and biological functions.
+
+![OTF_Structure](https://github.com/byemaxx/MetaX/raw/main/Docs/MetaX_Cookbook.assets/OTF_Structure.png)
+
+## OTFs Network
+
Linking Taxa and Functions in different levels of the hierarchy, and different functional categories. e.g., **Species-KO**, **Genus-CAZy**, **Phylum-EC**, etc.
- ![OTF](https://github.com/byemaxx/MetaX/raw/main/Docs/MetaX_Cookbook.assets/tf_link_net.png)
diff --git a/metax/gui/main_gui.py b/metax/gui/main_gui.py
index c35f3e5..d3b668b 100644
--- a/metax/gui/main_gui.py
+++ b/metax/gui/main_gui.py
@@ -361,6 +361,7 @@ def __init__(self, MainWindow):
self.checkBox_create_protein_table.stateChanged.connect(self.change_event_checkBox_create_protein_table)
self.comboBox_method_of_protein_inference.currentIndexChanged.connect(self.update_method_of_protein_inference)
self.comboBox_3dbar_sub_meta.currentIndexChanged.connect(self.change_event_comboBox_3dbar_sub_meta)
+ self.comboBox_tflink_sub_meta.currentIndexChanged.connect(self.change_event_comboBox_tflink_sub_meta)
## Basic Stat
self.pushButton_plot_pca_sns.clicked.connect(lambda: self.plot_basic_info_sns('pca'))
@@ -473,8 +474,8 @@ def __init__(self, MainWindow):
self.comboBox_tfnet_select_list.add_all_searched.connect(self.add_all_searched_tfnet_to_focus_list)
# Taxa-func link
- self.pushButton_others_get_intensity_matrix.clicked.connect(self.get_tflink_intensity_matrix)
- self.pushButton_others_plot_heatmap.clicked.connect(self.plot_tflink_heatmap)
+ self.pushButton_others_get_intensity_matrix.clicked.connect(lambda: self.plot_tflink_heatmap('table'))
+ self.pushButton_others_plot_heatmap.clicked.connect(lambda: self.plot_tflink_heatmap('fig'))
self.pushButton_others_plot_line.clicked.connect(self.plot_tflink_bar)
self.pushButton_others_show_linked_taxa.clicked.connect(self.show_others_linked_taxa)
self.pushButton_others_show_linked_func.clicked.connect(self.show_others_linked_func)
@@ -671,7 +672,9 @@ def update_all_condition_meta(self):
self.comboBox_sub_meta_pca.addItems(['None'] + meta_list)
self.comboBox_3dbar_sub_meta.clear()
self.comboBox_3dbar_sub_meta.addItems(['None'] + meta_list)
-
+ self.comboBox_tflink_sub_meta.clear()
+ self.comboBox_tflink_sub_meta.addItems(['None'] + meta_list)
+
except Exception as e:
print(e)
@@ -781,6 +784,13 @@ def change_event_comboBox_3dbar_sub_meta(self):
# self.comboBox_3dbar_sub_meta.setEnabled(False)
# else:
# self.comboBox_3dbar_sub_meta.setEnabled(True)
+ def change_event_comboBox_tflink_sub_meta(self):
+ # when the sub_meta comboBox is not None, the mean plot is not available
+ if self.comboBox_tflink_sub_meta.currentText() != 'None':
+ self.checkBox_tflink_plot_mean.setEnabled(False)
+
+ else:
+ self.checkBox_tflink_plot_mean.setEnabled(True)
def hide_plot_setting_groupbox(self):
groupbox_list = ["groupBox_basic_plot", "groupBox_basic_heatmap_plot_settings",
@@ -2552,6 +2562,8 @@ def set_multi_table(self, restore_taxafunc=False, saved_obj=None):
"Log 10 transformation": "log10",
"Square root transformation": "sqrt",
"Cube root transformation": "cube",
+ "Box-Cox": "boxcox",
+
}
normalize_dict = {
"None": None,
@@ -3545,7 +3557,7 @@ def plot_basic_list(self, plot_type='heatmap'):
scale=scale, row_cluster=row_cluster, col_cluster=col_cluster,
cmap=cmap, rename_taxa=rename_taxa, font_size=font_size,
show_all_labels=show_all_labels, rename_sample=rename_sample,
- plot_mean = plot_mean, sub_meta = sub_meta)
+ plot_mean = plot_mean, sub_meta = sub_meta, return_type = 'fig')
elif plot_type == 'bar':
@@ -3732,7 +3744,8 @@ def plot_trends_cluster(self):
table_name = self.comboBox_trends_table.currentText()
font_size = self.spinBox_trends_font_size.value()
- title = f'{table_name.capitalize()} Cluster'
+ # title = f'{table_name.capitalize()} Cluster'
+ title = 'Cluster'
num_cluster = self.spinBox_trends_num_cluster.value()
@@ -3786,15 +3799,20 @@ def plot_trends_cluster(self):
df = dft.loc[self.trends_cluster_list]
try:
+ num_col = self.spinBox_trends_num_col.value()
+ if num_col > num_cluster:
+ print(f'num_col: {num_col} > num_cluster: {num_cluster}. Reset num_col to num_cluster.')
+ num_col = num_cluster
+
df = df.loc[(df!=0).any(axis=1)]
- self.show_message(f'Plotting trends cluster...')
+ self.show_message('Plotting trends cluster...')
# plot trends and get cluster table
fig, cluster_df = TrendsPlot(self.tfa).plot_trends(df= df, num_cluster = num_cluster,
width=width, height=height, title=title
- , font_size=font_size)
+ , font_size=font_size, num_col=num_col)
# create a dialog to show the figure
# plt_dialog = PltDialog(self.MainWindow, fig)
- plt_size= (width*50,height*num_cluster*50)
+ plt_size= (width*50, int(height*num_cluster*50/num_col) )
plt_dialog = ExportablePlotDialog(self.MainWindow,fig, plt_size)
#set title
plt_dialog.setWindowTitle(title)
@@ -4431,7 +4449,7 @@ def plot_top_heatmap(self):
self.logger.write_log(f'plot_top_heatmap error: {error_message}')
self.logger.write_log(f'plot_top_heatmap: table_name: {table_name}, top_num: {top_num}, value_type: {value_type}, fig_size: {fig_size}, pvalue: {pvalue}, sort_by: {sort_by}, cmap: {cmap}, scale: {scale}', 'e')
if 'No significant' in error_message:
- QMessageBox.warning(self.MainWindow, 'Warning', f'No significant results.')
+ QMessageBox.warning(self.MainWindow, 'Warning', f'No significant results. \n\n{error_message}')
else:
QMessageBox.warning(self.MainWindow, 'Error', f'{error_message}')
@@ -4495,14 +4513,15 @@ def get_top_cross_table(self):
rename_taxa=rename_taxa, sort_by = sort_by, scale_method = scale_method, return_type = 'table')
- except ValueError as e:
- QMessageBox.warning(self.MainWindow, 'Warning', f'No significant results.\n\n{e}')
- return None
except Exception as e:
error_message = traceback.format_exc()
self.logger.write_log(f'get_top_cross_table error: {error_message}', 'e')
self.logger.write_log(f'get_top_cross_table: table_name: {table_name}, top_num: {top_num}, value_type: {value_type}, pvalue: {pvalue}, sort_by: {sort_by}', 'e')
- QMessageBox.warning(self.MainWindow, 'Erro', error_message)
+ if 'No significant' in error_message:
+ QMessageBox.warning(self.MainWindow, 'Warning', f'No significant results.\n\n{error_message}')
+ else:
+ QMessageBox.warning(self.MainWindow, 'Error', f'{error_message}')
+
return None
try:
@@ -5318,39 +5337,7 @@ def plot_network(self):
self.logger.write_log(f'plot_network error: {error_message}', 'e')
self.logger.write_log(f'plot_network: sample_list:{sample_list}, focus_list:{focus_list}, plot_list_only:{plot_list_only}', 'e')
QMessageBox.warning(self.MainWindow, 'Error', f'{error_message}')
-
- # link
- def get_tflink_intensity_matrix(self):
- taxa = self.remove_pep_num_str_and_strip(self.comboBox_others_taxa.currentText())
- func = self.remove_pep_num_str_and_strip(self.comboBox_others_func.currentText())
-
- if not taxa and not func:
- QMessageBox.warning(self.MainWindow, 'Warning', 'Please select taxa or function!')
- return None
-
- params = {}
-
- # extract sample list
- sample_list = self.get_sample_list_tflink()
-
- params['sample_list'] = sample_list
-
- if taxa:
- params['taxon_name'] = taxa
- if func:
- params['func_name'] = func
-
- df = self.tfa.GetMatrix.get_intensity_matrix(**params)
-
- if not df.empty:
- if self.checkBox_tflink_hetatmap_rename_taxa.isChecked():
- df = self.tfa.rename_taxa(df)
- if self.checkBox_tflink_plot_mean.isChecked():
- df = self.tfa.BasicStats.get_stats_mean_df_by_group(df)
- self.show_table(df, title=f'{taxa} [ {func} ]')
- else:
- QMessageBox.warning(self.MainWindow, 'Warning', 'No data!, please reselect!')
-
+
def get_sample_list_tflink(self):
# get sample list
@@ -5432,7 +5419,7 @@ def filter_tflink(self):
pass
# Plot Heatmap
- def plot_tflink_heatmap(self):
+ def plot_tflink_heatmap(self, return_type = 'fig'):
taxa = self.remove_pep_num_str_and_strip(self.comboBox_others_taxa.currentText())
func = self.remove_pep_num_str_and_strip(self.comboBox_others_func.currentText())
width = self.spinBox_tflink_width.value()
@@ -5443,21 +5430,14 @@ def plot_tflink_heatmap(self):
rename_taxa = self.checkBox_tflink_hetatmap_rename_taxa.isChecked()
show_all_labels = (self.checkBox_tflink_bar_show_all_labels_x.isChecked(), self.checkBox_tflink_bar_show_all_labels_y.isChecked())
plot_mean = self.checkBox_tflink_plot_mean.isChecked()
+ rename_sample=self.checkBox_tflink_hetatmap_rename_sample.isChecked()
+ row_cluster = True if self.checkBox_tflink_hetatmap_row_cluster.isChecked() else False
+ col_cluster = True if self.checkBox_tflink_hetatmap_col_cluster.isChecked() else False
+ sub_meta = self.comboBox_tflink_sub_meta.currentText()
if cmap == 'Auto':
cmap = None
- row_cluster = False
- col_cluster = False
-
- if self.checkBox_tflink_hetatmap_row_cluster.isChecked():
- row_cluster = True
-
- if self.checkBox_tflink_hetatmap_col_cluster.isChecked():
- col_cluster = True
-
-
-
if not taxa and not func:
QMessageBox.warning(self.MainWindow, 'Warning', 'Please select taxa or function!')
return None
@@ -5468,10 +5448,18 @@ def plot_tflink_heatmap(self):
if taxa:
params['taxon_name'] = taxa
- title = taxa
+ if rename_taxa:
+ short_taxa = taxa.split('|')[-1]
+ else:
+ short_taxa = taxa
+ title = short_taxa
+
if func:
params['func_name'] = func
- title = func if not title else f"{taxa} [ {func} ]"
+ title = func
+
+ if taxa and func:
+ title = f"{short_taxa}\n{func}"
df = self.tfa.GetMatrix.get_intensity_matrix(**params)
@@ -5488,12 +5476,17 @@ def plot_tflink_heatmap(self):
df = self.delete_zero_columns(df)
try:
- self.show_message('Plotting heatmap, please wait...')
- HeatmapPlot(self.tfa, **self.heatmap_params_dict).plot_basic_heatmap(df=df, title=title, fig_size=(int(width), int(height)),
+ self.show_message('Plotting heatmap, please wait...') if return_type == 'fig' else self.show_message('Calculating data, please wait...')
+ fig_res = HeatmapPlot(self.tfa, **self.heatmap_params_dict).plot_basic_heatmap(df=df, title=title, fig_size=(int(width), int(height)),
scale=scale, row_cluster=row_cluster, col_cluster=col_cluster,
cmap=cmap, rename_taxa=rename_taxa, font_size=font_size, show_all_labels=show_all_labels,
- rename_sample=self.checkBox_tflink_hetatmap_rename_sample.isChecked(), plot_mean=plot_mean
+ rename_sample=rename_sample, sub_meta=sub_meta,
+ plot_mean=plot_mean, return_type = return_type
)
+
+ if return_type == 'table':
+ self.show_table(fig_res, title=title.replace('\n', '-'))
+
except Exception as e:
error_message = traceback.format_exc()
self.logger.write_log(f'plot_others_heatmap error: {error_message}', 'e')
@@ -5545,7 +5538,8 @@ def plot_tflink_bar(self):
show_legend = self.checkBox_tflink_bar_show_legend.isChecked()
plot_mean = self.checkBox_tflink_plot_mean.isChecked()
show_all_labels = (self.checkBox_tflink_bar_show_all_labels_x.isChecked(), self.checkBox_tflink_bar_show_all_labels_y.isChecked())
-
+ sub_meta = self.comboBox_tflink_sub_meta.currentText()
+
if not taxa and not func:
QMessageBox.warning(self.MainWindow, 'Warning', 'Please select taxa or function!')
@@ -5586,6 +5580,7 @@ def plot_tflink_bar(self):
params['font_size'] = font_size
params['plot_mean'] = plot_mean
params['show_all_labels'] = show_all_labels
+ params['sub_meta'] = sub_meta
self.show_message('Plotting bar plot, please wait...')
pic = BarPlot_js(self.tfa, theme=self.html_theme).plot_intensity_bar(**params)
diff --git a/metax/gui/metax_gui/main_window.ui b/metax/gui/metax_gui/main_window.ui
index f266400..d116c41 100644
--- a/metax/gui/metax_gui/main_window.ui
+++ b/metax/gui/metax_gui/main_window.ui
@@ -7,7 +7,7 @@
0
0
1122
- 794
+ 774
@@ -46,7 +46,7 @@
Qt::LeftToRight
- 2
+ 6
false
@@ -246,7 +246,7 @@
0
0
528
- 569
+ 553
@@ -937,6 +937,11 @@
Cube root transformation
+ -
+
+ Box-Cox
+
+
-
@@ -1459,7 +1464,7 @@
0
0
- 660
+ 1016
232
@@ -2730,8 +2735,8 @@
0
0
- 1016
- 158
+ 999
+ 150
@@ -5602,7 +5607,7 @@
0
0
996
- 140
+ 124
@@ -6120,7 +6125,7 @@
QTabWidget::Triangular
- 0
+ 1
@@ -6152,8 +6157,8 @@
0
0
- 1016
- 179
+ 493
+ 128
@@ -7382,60 +7387,31 @@
0
0
- 538
- 63
+ 1016
+ 124
-
-
-
-
-
-
- 75
- true
-
-
-
- General
-
-
-
- -
-
+
-
+
0
0
-
- 1
-
-
- 200
-
-
- 9
-
-
-
- -
-
-
-
- 75
- true
-
-
- Specific cluster
+ Simplify Taxa Names
+
+
+ true
- -
-
+
-
+
0
@@ -7443,37 +7419,37 @@
- Get Intnsity Results
+ Plot Samples
- -
-
-
-
- 0
- 0
-
+
-
+
+
+
+ 75
+ true
+
- Font Size
+ General
- -
-
-
-
- 0
- 0
-
+
-
+
+
+
+ 75
+ true
+
- Height
+ Specific cluster
- -
+
-
@@ -7489,21 +7465,8 @@
- -
-
-
-
- 0
- 0
-
-
-
- Plot Samples
-
-
-
- -
-
+
-
+
0
@@ -7511,60 +7474,135 @@
- Simplify Taxa Names
-
-
- true
+ Get Intnsity Results
-
-
-
-
- 0
- 0
-
-
-
- Width
-
-
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Width
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 1
+
+
+ 200
+
+
+ 16
+
+
+
+
-
-
-
-
- 0
- 0
-
-
-
- 1
-
-
- 200
-
-
- 16
-
-
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Height
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 1
+
+
+ 200
+
+
+ 9
+
+
+
+
- -
-
-
-
- 0
- 0
-
-
-
- 1
-
-
- 10
-
-
+
-
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Font Size
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 1
+
+
+ 10
+
+
+
+
+
+ -
+
+
-
+
+
+ Number of Col for Cluster Plot
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ 1
+
+
+
+
@@ -7721,144 +7759,6 @@
Taxa-Func Link
- -
-
-
-
- 0
- 0
-
-
-
- true
-
-
-
- -
-
-
-
-
-
-
- 0
- 0
-
-
-
- Linked Number: -
-
-
-
- -
-
-
- false
-
-
-
- 0
- 0
-
-
-
- Show Linked Taxa Only
-
-
-
-
-
- -
-
-
-
-
-
-
- 0
- 0
-
-
-
- Linked Number: -
-
-
-
- -
-
-
- false
-
-
-
- 0
- 0
-
-
-
- Show Linked Func Only
-
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Sample
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- -
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Group
-
-
- true
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- true
-
-
-
-
-
@@ -7917,7 +7817,7 @@
- Get Intensity Table
+ Get Heatmap Table
@@ -7930,21 +7830,18 @@
- -
-
-
-
- 0
- 0
-
-
-
- Meta
+
-
+
+
+ Qt::Horizontal
- -
-
+
-
+
+
+ -
+
0
@@ -7952,90 +7849,46 @@
- Function
+ Group
+
+
+ true
- -
-
+
-
+
-
-
+
-
+
0
0
-
- Qt::LeftToRight
-
- In Condition
+ Linked Number: -
-
-
+
false
-
+
0
0
+
+ Show Linked Taxa Only
+
- -
-
-
-
-
-
-
-
-
- false
-
-
-
- 0
- 0
-
-
-
-
- 300
- 16777215
-
-
-
-
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Qt::LeftToRight
-
-
-
-
@@ -8055,22 +7908,6 @@
- -
-
-
-
- 0
- 0
-
-
-
- Taxa
-
-
-
- -
-
-
-
-
@@ -8208,6 +8045,35 @@
+ -
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Taxa
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Meta
+
+
+
-
@@ -8670,6 +8536,198 @@
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Qt::LeftToRight
+
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Linked Number: -
+
+
+
+ -
+
+
+ false
+
+
+
+ 0
+ 0
+
+
+
+ Show Linked Func Only
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Sample
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Qt::LeftToRight
+
+
+ In Condition
+
+
+
+ -
+
+
+ false
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
-
+
+
-
+
+
+ false
+
+
+
+ 0
+ 0
+
+
+
+
+ 300
+ 16777215
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Function
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ true
+
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Sub Meta
+
+
+
+ -
+
+
+
+
@@ -10145,7 +10203,7 @@
0
0
1122
- 23
+ 21