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 @@ -10343,11 +10401,11 @@ 63 - 102 + 100 70 - 102 + 100 @@ -10359,11 +10417,11 @@ 63 - 102 + 100 77 - 103 + 101 @@ -10375,11 +10433,11 @@ 96 - 96 + 94 108 - 96 + 94 @@ -10391,11 +10449,11 @@ 96 - 96 + 94 119 - 97 + 95 @@ -10407,11 +10465,11 @@ 96 - 95 + 93 108 - 95 + 93 @@ -10423,11 +10481,11 @@ 96 - 95 + 93 119 - 96 + 94 @@ -10470,12 +10528,12 @@ setEnabled(bool) - 87 - 107 + 170 + 195 - 99 - 107 + 269 + 197 @@ -10487,11 +10545,11 @@ 95 - 97 + 95 108 - 97 + 95 @@ -10503,11 +10561,11 @@ 95 - 97 + 95 119 - 98 + 96 @@ -10519,11 +10577,11 @@ 96 - 96 + 94 108 - 96 + 94 @@ -10535,11 +10593,11 @@ 96 - 96 + 94 119 - 97 + 95 @@ -10550,12 +10608,12 @@ setEnabled(bool) - 700 - 192 + 1056 + 522 - 265 - 229 + 289 + 559 @@ -10566,12 +10624,12 @@ setEnabled(bool) - 700 - 192 + 1056 + 522 - 265 - 358 + 289 + 688 @@ -10582,12 +10640,12 @@ setEnabled(bool) - 700 - 192 + 1056 + 522 - 604 - 231 + 845 + 561 @@ -10598,12 +10656,12 @@ setEnabled(bool) - 87 - 107 + 170 + 195 - 110 - 108 + 480 + 197 @@ -10615,11 +10673,11 @@ 330 - 168 + 166 423 - 168 + 166 @@ -10646,12 +10704,12 @@ setEnabled(bool) - 134 - 151 + 63 + 99 - 227 - 153 + 70 + 99 @@ -10662,12 +10720,12 @@ setEnabled(bool) - 134 - 151 + 63 + 99 - 309 - 153 + 227 + 100 @@ -10678,12 +10736,12 @@ setEnabled(bool) - 63 - 101 + 149 + 151 - 73 - 101 + 246 + 153 @@ -10694,12 +10752,12 @@ setEnabled(bool) - 63 - 101 + 149 + 151 - 82 - 102 + 449 + 153 @@ -10710,12 +10768,12 @@ setVisible(bool) - 63 - 109 + 76 + 436 - 121 - 112 + 134 + 512 @@ -10742,12 +10800,12 @@ setVisible(bool) - 101 - 559 + 123 + 541 - 92 - 730 + 113 + 712 @@ -10774,12 +10832,12 @@ setVisible(bool) - 151 - 503 + 77 + 112 - 175 - 727 + 121 + 114 @@ -10790,12 +10848,12 @@ setVisible(bool) - 52 - 122 + 66 + 543 - 121 - 117 + 134 + 620 @@ -10806,12 +10864,12 @@ setVisible(bool) - 119 - 456 + 133 + 444 - 149 - 727 + 162 + 709 @@ -10823,11 +10881,11 @@ 55 - 114 + 112 - 113 - 116 + 121 + 114 @@ -10863,5 +10921,21 @@ + + checkBox_tflink_plot_mean + clicked(bool) + comboBox_tflink_sub_meta + setDisabled(bool) + + + 1019 + 542 + + + 553 + 114 + + + diff --git a/metax/gui/metax_gui/ui_main_window.py b/metax/gui/metax_gui/ui_main_window.py index ba6a8a6..bf6f8f6 100644 --- a/metax/gui/metax_gui/ui_main_window.py +++ b/metax/gui/metax_gui/ui_main_window.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file 'c:\Users\max\OneDrive - University of Ottawa\code\TaxaFunc\MetaX\metax\gui\metax_gui\main_window.ui' +# Form implementation generated from reading ui file 'c:\Users\Qing\OneDrive - University of Ottawa\code\TaxaFunc\MetaX\metax\gui\metax_gui\main_window.ui' # # Created by: PyQt5 UI code generator 5.15.9 # @@ -14,7 +14,7 @@ class Ui_metaX_main(object): def setupUi(self, metaX_main): metaX_main.setObjectName("metaX_main") - metaX_main.resize(1122, 794) + metaX_main.resize(1122, 774) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) @@ -147,7 +147,7 @@ def setupUi(self, metaX_main): self.toolBox_2.setMaximumSize(QtCore.QSize(1677, 16777215)) self.toolBox_2.setObjectName("toolBox_2") self.page_2 = QtWidgets.QWidget() - self.page_2.setGeometry(QtCore.QRect(0, 0, 528, 569)) + self.page_2.setGeometry(QtCore.QRect(0, 0, 528, 553)) self.page_2.setObjectName("page_2") self.gridLayout_27 = QtWidgets.QGridLayout(self.page_2) self.gridLayout_27.setObjectName("gridLayout_27") @@ -488,6 +488,7 @@ def setupUi(self, metaX_main): self.comboBox_set_data_transformation.addItem("") self.comboBox_set_data_transformation.addItem("") self.comboBox_set_data_transformation.addItem("") + self.comboBox_set_data_transformation.addItem("") self.gridLayout_15.addWidget(self.comboBox_set_data_transformation, 4, 1, 1, 3) self.comboBox_set_data_normalization = QtWidgets.QComboBox(self.tab_set_taxa_func) self.comboBox_set_data_normalization.setLayoutDirection(QtCore.Qt.LeftToRight) @@ -730,7 +731,7 @@ def setupUi(self, metaX_main): self.scrollArea.setWidgetResizable(True) self.scrollArea.setObjectName("scrollArea") self.scrollAreaWidgetContents = QtWidgets.QWidget() - self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 660, 232)) + self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 1016, 232)) self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents") self.gridLayout_34 = QtWidgets.QGridLayout(self.scrollAreaWidgetContents) self.gridLayout_34.setObjectName("gridLayout_34") @@ -1394,7 +1395,7 @@ def setupUi(self, metaX_main): self.scrollArea_2.setWidgetResizable(True) self.scrollArea_2.setObjectName("scrollArea_2") self.scrollAreaWidgetContents_2 = QtWidgets.QWidget() - self.scrollAreaWidgetContents_2.setGeometry(QtCore.QRect(0, 0, 1016, 158)) + self.scrollAreaWidgetContents_2.setGeometry(QtCore.QRect(0, 0, 999, 150)) self.scrollAreaWidgetContents_2.setObjectName("scrollAreaWidgetContents_2") self.gridLayout_50 = QtWidgets.QGridLayout(self.scrollAreaWidgetContents_2) self.gridLayout_50.setObjectName("gridLayout_50") @@ -2868,7 +2869,7 @@ def setupUi(self, metaX_main): self.scrollArea_3.setWidgetResizable(True) self.scrollArea_3.setObjectName("scrollArea_3") self.scrollAreaWidgetContents_4 = QtWidgets.QWidget() - self.scrollAreaWidgetContents_4.setGeometry(QtCore.QRect(0, 0, 996, 140)) + self.scrollAreaWidgetContents_4.setGeometry(QtCore.QRect(0, 0, 996, 124)) self.scrollAreaWidgetContents_4.setObjectName("scrollAreaWidgetContents_4") self.gridLayout_68 = QtWidgets.QGridLayout(self.scrollAreaWidgetContents_4) self.gridLayout_68.setObjectName("gridLayout_68") @@ -3169,7 +3170,7 @@ def setupUi(self, metaX_main): self.scrollArea_4.setWidgetResizable(True) self.scrollArea_4.setObjectName("scrollArea_4") self.scrollAreaWidgetContents_5 = QtWidgets.QWidget() - self.scrollAreaWidgetContents_5.setGeometry(QtCore.QRect(0, 0, 1016, 179)) + self.scrollAreaWidgetContents_5.setGeometry(QtCore.QRect(0, 0, 493, 128)) self.scrollAreaWidgetContents_5.setObjectName("scrollAreaWidgetContents_5") self.gridLayout_49 = QtWidgets.QGridLayout(self.scrollAreaWidgetContents_5) self.gridLayout_49.setObjectName("gridLayout_49") @@ -3814,12 +3815,29 @@ def setupUi(self, metaX_main): self.scrollArea_5.setWidgetResizable(True) self.scrollArea_5.setObjectName("scrollArea_5") self.scrollAreaWidgetContents_6 = QtWidgets.QWidget() - self.scrollAreaWidgetContents_6.setGeometry(QtCore.QRect(0, 0, 538, 63)) + self.scrollAreaWidgetContents_6.setGeometry(QtCore.QRect(0, 0, 1016, 124)) self.scrollAreaWidgetContents_6.setObjectName("scrollAreaWidgetContents_6") self.gridLayout_57 = QtWidgets.QGridLayout(self.scrollAreaWidgetContents_6) self.gridLayout_57.setObjectName("gridLayout_57") self.gridLayout_59 = QtWidgets.QGridLayout() self.gridLayout_59.setObjectName("gridLayout_59") + self.checkBox_trends_plot_interactive_rename_taxa = QtWidgets.QCheckBox(self.scrollAreaWidgetContents_6) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.checkBox_trends_plot_interactive_rename_taxa.sizePolicy().hasHeightForWidth()) + self.checkBox_trends_plot_interactive_rename_taxa.setSizePolicy(sizePolicy) + self.checkBox_trends_plot_interactive_rename_taxa.setChecked(True) + self.checkBox_trends_plot_interactive_rename_taxa.setObjectName("checkBox_trends_plot_interactive_rename_taxa") + self.gridLayout_59.addWidget(self.checkBox_trends_plot_interactive_rename_taxa, 1, 7, 1, 1) + self.checkBox_trends_plot_interactive_plot_samples = QtWidgets.QCheckBox(self.scrollAreaWidgetContents_6) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.checkBox_trends_plot_interactive_plot_samples.sizePolicy().hasHeightForWidth()) + self.checkBox_trends_plot_interactive_plot_samples.setSizePolicy(sizePolicy) + self.checkBox_trends_plot_interactive_plot_samples.setObjectName("checkBox_trends_plot_interactive_plot_samples") + self.gridLayout_59.addWidget(self.checkBox_trends_plot_interactive_plot_samples, 1, 1, 1, 3) self.label_174 = QtWidgets.QLabel(self.scrollAreaWidgetContents_6) font = QtGui.QFont() font.setBold(True) @@ -3827,17 +3845,6 @@ def setupUi(self, metaX_main): self.label_174.setFont(font) self.label_174.setObjectName("label_174") self.gridLayout_59.addWidget(self.label_174, 0, 0, 1, 1) - self.spinBox_trends_height = QtWidgets.QSpinBox(self.scrollAreaWidgetContents_6) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.spinBox_trends_height.sizePolicy().hasHeightForWidth()) - self.spinBox_trends_height.setSizePolicy(sizePolicy) - self.spinBox_trends_height.setMinimum(1) - self.spinBox_trends_height.setMaximum(200) - self.spinBox_trends_height.setProperty("value", 9) - self.spinBox_trends_height.setObjectName("spinBox_trends_height") - self.gridLayout_59.addWidget(self.spinBox_trends_height, 0, 4, 1, 1) self.label_175 = QtWidgets.QLabel(self.scrollAreaWidgetContents_6) font = QtGui.QFont() font.setBold(True) @@ -3845,30 +3852,6 @@ def setupUi(self, metaX_main): self.label_175.setFont(font) self.label_175.setObjectName("label_175") self.gridLayout_59.addWidget(self.label_175, 1, 0, 1, 1) - self.checkBox_get_trends_cluster_intensity = QtWidgets.QCheckBox(self.scrollAreaWidgetContents_6) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.checkBox_get_trends_cluster_intensity.sizePolicy().hasHeightForWidth()) - self.checkBox_get_trends_cluster_intensity.setSizePolicy(sizePolicy) - self.checkBox_get_trends_cluster_intensity.setObjectName("checkBox_get_trends_cluster_intensity") - self.gridLayout_59.addWidget(self.checkBox_get_trends_cluster_intensity, 1, 3, 1, 2) - self.label_158 = QtWidgets.QLabel(self.scrollAreaWidgetContents_6) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_158.sizePolicy().hasHeightForWidth()) - self.label_158.setSizePolicy(sizePolicy) - self.label_158.setObjectName("label_158") - self.gridLayout_59.addWidget(self.label_158, 0, 5, 1, 1) - self.label_92 = QtWidgets.QLabel(self.scrollAreaWidgetContents_6) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_92.sizePolicy().hasHeightForWidth()) - self.label_92.setSizePolicy(sizePolicy) - self.label_92.setObjectName("label_92") - self.gridLayout_59.addWidget(self.label_92, 0, 3, 1, 1) self.checkBox_trends_plot_interactive_show_legend = QtWidgets.QCheckBox(self.scrollAreaWidgetContents_6) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) @@ -3877,24 +3860,17 @@ def setupUi(self, metaX_main): self.checkBox_trends_plot_interactive_show_legend.setSizePolicy(sizePolicy) self.checkBox_trends_plot_interactive_show_legend.setChecked(True) self.checkBox_trends_plot_interactive_show_legend.setObjectName("checkBox_trends_plot_interactive_show_legend") - self.gridLayout_59.addWidget(self.checkBox_trends_plot_interactive_show_legend, 1, 5, 1, 1) - self.checkBox_trends_plot_interactive_plot_samples = QtWidgets.QCheckBox(self.scrollAreaWidgetContents_6) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.checkBox_trends_plot_interactive_plot_samples.sizePolicy().hasHeightForWidth()) - self.checkBox_trends_plot_interactive_plot_samples.setSizePolicy(sizePolicy) - self.checkBox_trends_plot_interactive_plot_samples.setObjectName("checkBox_trends_plot_interactive_plot_samples") - self.gridLayout_59.addWidget(self.checkBox_trends_plot_interactive_plot_samples, 1, 1, 1, 2) - self.checkBox_trends_plot_interactive_rename_taxa = QtWidgets.QCheckBox(self.scrollAreaWidgetContents_6) + self.gridLayout_59.addWidget(self.checkBox_trends_plot_interactive_show_legend, 1, 6, 1, 1) + self.checkBox_get_trends_cluster_intensity = QtWidgets.QCheckBox(self.scrollAreaWidgetContents_6) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.checkBox_trends_plot_interactive_rename_taxa.sizePolicy().hasHeightForWidth()) - self.checkBox_trends_plot_interactive_rename_taxa.setSizePolicy(sizePolicy) - self.checkBox_trends_plot_interactive_rename_taxa.setChecked(True) - self.checkBox_trends_plot_interactive_rename_taxa.setObjectName("checkBox_trends_plot_interactive_rename_taxa") - self.gridLayout_59.addWidget(self.checkBox_trends_plot_interactive_rename_taxa, 1, 6, 1, 1) + sizePolicy.setHeightForWidth(self.checkBox_get_trends_cluster_intensity.sizePolicy().hasHeightForWidth()) + self.checkBox_get_trends_cluster_intensity.setSizePolicy(sizePolicy) + self.checkBox_get_trends_cluster_intensity.setObjectName("checkBox_get_trends_cluster_intensity") + self.gridLayout_59.addWidget(self.checkBox_get_trends_cluster_intensity, 1, 4, 1, 2) + self.horizontalLayout_97 = QtWidgets.QHBoxLayout() + self.horizontalLayout_97.setObjectName("horizontalLayout_97") self.label_97 = QtWidgets.QLabel(self.scrollAreaWidgetContents_6) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) @@ -3902,7 +3878,7 @@ def setupUi(self, metaX_main): sizePolicy.setHeightForWidth(self.label_97.sizePolicy().hasHeightForWidth()) self.label_97.setSizePolicy(sizePolicy) self.label_97.setObjectName("label_97") - self.gridLayout_59.addWidget(self.label_97, 0, 1, 1, 1) + self.horizontalLayout_97.addWidget(self.label_97) self.spinBox_trends_width = QtWidgets.QSpinBox(self.scrollAreaWidgetContents_6) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) @@ -3913,7 +3889,40 @@ def setupUi(self, metaX_main): self.spinBox_trends_width.setMaximum(200) self.spinBox_trends_width.setProperty("value", 16) self.spinBox_trends_width.setObjectName("spinBox_trends_width") - self.gridLayout_59.addWidget(self.spinBox_trends_width, 0, 2, 1, 1) + self.horizontalLayout_97.addWidget(self.spinBox_trends_width) + self.gridLayout_59.addLayout(self.horizontalLayout_97, 0, 1, 1, 1) + self.horizontalLayout_98 = QtWidgets.QHBoxLayout() + self.horizontalLayout_98.setObjectName("horizontalLayout_98") + self.label_92 = QtWidgets.QLabel(self.scrollAreaWidgetContents_6) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_92.sizePolicy().hasHeightForWidth()) + self.label_92.setSizePolicy(sizePolicy) + self.label_92.setObjectName("label_92") + self.horizontalLayout_98.addWidget(self.label_92) + self.spinBox_trends_height = QtWidgets.QSpinBox(self.scrollAreaWidgetContents_6) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.spinBox_trends_height.sizePolicy().hasHeightForWidth()) + self.spinBox_trends_height.setSizePolicy(sizePolicy) + self.spinBox_trends_height.setMinimum(1) + self.spinBox_trends_height.setMaximum(200) + self.spinBox_trends_height.setProperty("value", 9) + self.spinBox_trends_height.setObjectName("spinBox_trends_height") + self.horizontalLayout_98.addWidget(self.spinBox_trends_height) + self.gridLayout_59.addLayout(self.horizontalLayout_98, 0, 2, 1, 1) + self.horizontalLayout_99 = QtWidgets.QHBoxLayout() + self.horizontalLayout_99.setObjectName("horizontalLayout_99") + self.label_158 = QtWidgets.QLabel(self.scrollAreaWidgetContents_6) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_158.sizePolicy().hasHeightForWidth()) + self.label_158.setSizePolicy(sizePolicy) + self.label_158.setObjectName("label_158") + self.horizontalLayout_99.addWidget(self.label_158) self.spinBox_trends_font_size = QtWidgets.QSpinBox(self.scrollAreaWidgetContents_6) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) @@ -3923,7 +3932,19 @@ def setupUi(self, metaX_main): self.spinBox_trends_font_size.setMinimum(1) self.spinBox_trends_font_size.setProperty("value", 10) self.spinBox_trends_font_size.setObjectName("spinBox_trends_font_size") - self.gridLayout_59.addWidget(self.spinBox_trends_font_size, 0, 6, 1, 1) + self.horizontalLayout_99.addWidget(self.spinBox_trends_font_size) + self.gridLayout_59.addLayout(self.horizontalLayout_99, 0, 4, 1, 1) + self.horizontalLayout_100 = QtWidgets.QHBoxLayout() + self.horizontalLayout_100.setObjectName("horizontalLayout_100") + self.label_195 = QtWidgets.QLabel(self.scrollAreaWidgetContents_6) + self.label_195.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.label_195.setObjectName("label_195") + self.horizontalLayout_100.addWidget(self.label_195) + self.spinBox_trends_num_col = QtWidgets.QSpinBox(self.scrollAreaWidgetContents_6) + self.spinBox_trends_num_col.setMinimum(1) + self.spinBox_trends_num_col.setObjectName("spinBox_trends_num_col") + self.horizontalLayout_100.addWidget(self.spinBox_trends_num_col) + self.gridLayout_59.addLayout(self.horizontalLayout_100, 0, 5, 1, 3) self.gridLayout_57.addLayout(self.gridLayout_59, 0, 0, 1, 1) self.scrollArea_5.setWidget(self.scrollAreaWidgetContents_6) self.gridLayout_60.addWidget(self.scrollArea_5, 0, 0, 1, 1) @@ -4009,94 +4030,6 @@ def setupUi(self, metaX_main): self.tab_8.setObjectName("tab_8") self.gridLayout_4 = QtWidgets.QGridLayout(self.tab_8) self.gridLayout_4.setObjectName("gridLayout_4") - self.comboBox_others_func = QtWidgets.QComboBox(self.tab_8) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.comboBox_others_func.sizePolicy().hasHeightForWidth()) - self.comboBox_others_func.setSizePolicy(sizePolicy) - self.comboBox_others_func.setEditable(True) - self.comboBox_others_func.setObjectName("comboBox_others_func") - self.gridLayout_4.addWidget(self.comboBox_others_func, 6, 1, 1, 2) - self.horizontalLayout_81 = QtWidgets.QHBoxLayout() - self.horizontalLayout_81.setObjectName("horizontalLayout_81") - self.label_others_func_num = QtWidgets.QLabel(self.tab_8) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_others_func_num.sizePolicy().hasHeightForWidth()) - self.label_others_func_num.setSizePolicy(sizePolicy) - self.label_others_func_num.setObjectName("label_others_func_num") - self.horizontalLayout_81.addWidget(self.label_others_func_num) - self.pushButton_others_show_linked_taxa = QtWidgets.QPushButton(self.tab_8) - self.pushButton_others_show_linked_taxa.setEnabled(False) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.pushButton_others_show_linked_taxa.sizePolicy().hasHeightForWidth()) - self.pushButton_others_show_linked_taxa.setSizePolicy(sizePolicy) - self.pushButton_others_show_linked_taxa.setObjectName("pushButton_others_show_linked_taxa") - self.horizontalLayout_81.addWidget(self.pushButton_others_show_linked_taxa) - self.gridLayout_4.addLayout(self.horizontalLayout_81, 6, 3, 1, 1) - self.horizontalLayout_82 = QtWidgets.QHBoxLayout() - self.horizontalLayout_82.setObjectName("horizontalLayout_82") - self.label_others_taxa_num = QtWidgets.QLabel(self.tab_8) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_others_taxa_num.sizePolicy().hasHeightForWidth()) - self.label_others_taxa_num.setSizePolicy(sizePolicy) - self.label_others_taxa_num.setObjectName("label_others_taxa_num") - self.horizontalLayout_82.addWidget(self.label_others_taxa_num) - self.pushButton_others_show_linked_func = QtWidgets.QPushButton(self.tab_8) - self.pushButton_others_show_linked_func.setEnabled(False) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.pushButton_others_show_linked_func.sizePolicy().hasHeightForWidth()) - self.pushButton_others_show_linked_func.setSizePolicy(sizePolicy) - self.pushButton_others_show_linked_func.setObjectName("pushButton_others_show_linked_func") - self.horizontalLayout_82.addWidget(self.pushButton_others_show_linked_func) - self.gridLayout_4.addLayout(self.horizontalLayout_82, 7, 3, 1, 1) - self.radioButton_tflink_sample = QtWidgets.QRadioButton(self.tab_8) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.radioButton_tflink_sample.sizePolicy().hasHeightForWidth()) - self.radioButton_tflink_sample.setSizePolicy(sizePolicy) - self.radioButton_tflink_sample.setObjectName("radioButton_tflink_sample") - self.gridLayout_4.addWidget(self.radioButton_tflink_sample, 3, 0, 1, 1) - self.line_3 = QtWidgets.QFrame(self.tab_8) - self.line_3.setFrameShape(QtWidgets.QFrame.HLine) - self.line_3.setFrameShadow(QtWidgets.QFrame.Sunken) - self.line_3.setObjectName("line_3") - self.gridLayout_4.addWidget(self.line_3, 1, 0, 1, 4) - self.line_6 = QtWidgets.QFrame(self.tab_8) - self.line_6.setFrameShape(QtWidgets.QFrame.HLine) - self.line_6.setFrameShadow(QtWidgets.QFrame.Sunken) - self.line_6.setObjectName("line_6") - self.gridLayout_4.addWidget(self.line_6, 4, 0, 1, 4) - self.gridLayout_tflink_group = QtWidgets.QGridLayout() - self.gridLayout_tflink_group.setObjectName("gridLayout_tflink_group") - self.gridLayout_4.addLayout(self.gridLayout_tflink_group, 2, 2, 1, 2) - self.radioButton_tflink_group = QtWidgets.QRadioButton(self.tab_8) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.radioButton_tflink_group.sizePolicy().hasHeightForWidth()) - self.radioButton_tflink_group.setSizePolicy(sizePolicy) - self.radioButton_tflink_group.setChecked(True) - self.radioButton_tflink_group.setObjectName("radioButton_tflink_group") - self.gridLayout_4.addWidget(self.radioButton_tflink_group, 2, 0, 1, 1) - self.comboBox_others_taxa = QtWidgets.QComboBox(self.tab_8) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.comboBox_others_taxa.sizePolicy().hasHeightForWidth()) - self.comboBox_others_taxa.setSizePolicy(sizePolicy) - self.comboBox_others_taxa.setEditable(True) - self.comboBox_others_taxa.setObjectName("comboBox_others_taxa") - self.gridLayout_4.addWidget(self.comboBox_others_taxa, 7, 1, 1, 2) self.gridLayout_62 = QtWidgets.QGridLayout() self.gridLayout_62.setObjectName("gridLayout_62") self.pushButton_others_plot_heatmap = QtWidgets.QPushButton(self.tab_8) @@ -4132,73 +4065,43 @@ def setupUi(self, metaX_main): self.checkBox_6.setObjectName("checkBox_6") self.gridLayout_62.addWidget(self.checkBox_6, 1, 0, 1, 1) self.gridLayout_4.addLayout(self.gridLayout_62, 9, 0, 1, 4) - self.label_149 = QtWidgets.QLabel(self.tab_8) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_149.sizePolicy().hasHeightForWidth()) - self.label_149.setSizePolicy(sizePolicy) - self.label_149.setObjectName("label_149") - self.gridLayout_4.addWidget(self.label_149, 0, 0, 1, 1) - self.label_18 = QtWidgets.QLabel(self.tab_8) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_18.sizePolicy().hasHeightForWidth()) - self.label_18.setSizePolicy(sizePolicy) - self.label_18.setObjectName("label_18") - self.gridLayout_4.addWidget(self.label_18, 6, 0, 1, 1) - self.horizontalLayout_78 = QtWidgets.QHBoxLayout() - self.horizontalLayout_78.setObjectName("horizontalLayout_78") - self.checkBox_tflink_in_condition = QtWidgets.QCheckBox(self.tab_8) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.checkBox_tflink_in_condition.sizePolicy().hasHeightForWidth()) - self.checkBox_tflink_in_condition.setSizePolicy(sizePolicy) - self.checkBox_tflink_in_condition.setLayoutDirection(QtCore.Qt.LeftToRight) - self.checkBox_tflink_in_condition.setObjectName("checkBox_tflink_in_condition") - self.horizontalLayout_78.addWidget(self.checkBox_tflink_in_condition) - self.comboBox_tflink_condition_meta = QtWidgets.QComboBox(self.tab_8) - self.comboBox_tflink_condition_meta.setEnabled(False) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.comboBox_tflink_condition_meta.sizePolicy().hasHeightForWidth()) - self.comboBox_tflink_condition_meta.setSizePolicy(sizePolicy) - self.comboBox_tflink_condition_meta.setObjectName("comboBox_tflink_condition_meta") - self.horizontalLayout_78.addWidget(self.comboBox_tflink_condition_meta) - self.horizontalLayout_49 = QtWidgets.QHBoxLayout() - self.horizontalLayout_49.setObjectName("horizontalLayout_49") - self.horizontalLayout_77 = QtWidgets.QHBoxLayout() - self.horizontalLayout_77.setObjectName("horizontalLayout_77") - self.comboBox_tflink_condition_group = QtWidgets.QComboBox(self.tab_8) - self.comboBox_tflink_condition_group.setEnabled(False) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.comboBox_tflink_condition_group.sizePolicy().hasHeightForWidth()) - self.comboBox_tflink_condition_group.setSizePolicy(sizePolicy) - self.comboBox_tflink_condition_group.setMaximumSize(QtCore.QSize(300, 16777215)) - self.comboBox_tflink_condition_group.setObjectName("comboBox_tflink_condition_group") - self.horizontalLayout_77.addWidget(self.comboBox_tflink_condition_group) - self.horizontalLayout_49.addLayout(self.horizontalLayout_77) - self.horizontalLayout_78.addLayout(self.horizontalLayout_49) - self.gridLayout_4.addLayout(self.horizontalLayout_78, 2, 1, 1, 1) self.line_32 = QtWidgets.QFrame(self.tab_8) self.line_32.setFrameShape(QtWidgets.QFrame.HLine) self.line_32.setFrameShadow(QtWidgets.QFrame.Sunken) self.line_32.setObjectName("line_32") self.gridLayout_4.addWidget(self.line_32, 8, 0, 1, 4) - self.comboBox_tflink_meta = QtWidgets.QComboBox(self.tab_8) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) + self.gridLayout_tflink_sample = QtWidgets.QGridLayout() + self.gridLayout_tflink_sample.setObjectName("gridLayout_tflink_sample") + self.gridLayout_4.addLayout(self.gridLayout_tflink_sample, 3, 1, 1, 3) + self.radioButton_tflink_group = QtWidgets.QRadioButton(self.tab_8) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.comboBox_tflink_meta.sizePolicy().hasHeightForWidth()) - self.comboBox_tflink_meta.setSizePolicy(sizePolicy) - self.comboBox_tflink_meta.setLayoutDirection(QtCore.Qt.LeftToRight) - self.comboBox_tflink_meta.setObjectName("comboBox_tflink_meta") - self.gridLayout_4.addWidget(self.comboBox_tflink_meta, 0, 1, 1, 1) + sizePolicy.setHeightForWidth(self.radioButton_tflink_group.sizePolicy().hasHeightForWidth()) + self.radioButton_tflink_group.setSizePolicy(sizePolicy) + self.radioButton_tflink_group.setChecked(True) + self.radioButton_tflink_group.setObjectName("radioButton_tflink_group") + self.gridLayout_4.addWidget(self.radioButton_tflink_group, 2, 0, 1, 1) + self.horizontalLayout_81 = QtWidgets.QHBoxLayout() + self.horizontalLayout_81.setObjectName("horizontalLayout_81") + self.label_others_func_num = QtWidgets.QLabel(self.tab_8) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_others_func_num.sizePolicy().hasHeightForWidth()) + self.label_others_func_num.setSizePolicy(sizePolicy) + self.label_others_func_num.setObjectName("label_others_func_num") + self.horizontalLayout_81.addWidget(self.label_others_func_num) + self.pushButton_others_show_linked_taxa = QtWidgets.QPushButton(self.tab_8) + self.pushButton_others_show_linked_taxa.setEnabled(False) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.pushButton_others_show_linked_taxa.sizePolicy().hasHeightForWidth()) + self.pushButton_others_show_linked_taxa.setSizePolicy(sizePolicy) + self.pushButton_others_show_linked_taxa.setObjectName("pushButton_others_show_linked_taxa") + self.horizontalLayout_81.addWidget(self.pushButton_others_show_linked_taxa) + self.gridLayout_4.addLayout(self.horizontalLayout_81, 6, 3, 1, 1) self.pushButton_others_fresh_taxa_func = QtWidgets.QPushButton(self.tab_8) self.pushButton_others_fresh_taxa_func.setEnabled(False) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) @@ -4208,17 +4111,6 @@ def setupUi(self, metaX_main): self.pushButton_others_fresh_taxa_func.setSizePolicy(sizePolicy) self.pushButton_others_fresh_taxa_func.setObjectName("pushButton_others_fresh_taxa_func") self.gridLayout_4.addWidget(self.pushButton_others_fresh_taxa_func, 5, 3, 1, 1) - self.label_19 = QtWidgets.QLabel(self.tab_8) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_19.sizePolicy().hasHeightForWidth()) - self.label_19.setSizePolicy(sizePolicy) - self.label_19.setObjectName("label_19") - self.gridLayout_4.addWidget(self.label_19, 7, 0, 1, 1) - self.gridLayout_tflink_sample = QtWidgets.QGridLayout() - self.gridLayout_tflink_sample.setObjectName("gridLayout_tflink_sample") - self.gridLayout_4.addLayout(self.gridLayout_tflink_sample, 3, 1, 1, 3) self.horizontalLayout_50 = QtWidgets.QHBoxLayout() self.horizontalLayout_50.setObjectName("horizontalLayout_50") self.label_75 = QtWidgets.QLabel(self.tab_8) @@ -4276,6 +4168,25 @@ def setupUi(self, metaX_main): self.pushButton_tflink_filter.setObjectName("pushButton_tflink_filter") self.horizontalLayout_50.addWidget(self.pushButton_tflink_filter) self.gridLayout_4.addLayout(self.horizontalLayout_50, 5, 1, 1, 2) + self.gridLayout_tflink_group = QtWidgets.QGridLayout() + self.gridLayout_tflink_group.setObjectName("gridLayout_tflink_group") + self.gridLayout_4.addLayout(self.gridLayout_tflink_group, 2, 2, 1, 2) + self.label_19 = QtWidgets.QLabel(self.tab_8) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_19.sizePolicy().hasHeightForWidth()) + self.label_19.setSizePolicy(sizePolicy) + self.label_19.setObjectName("label_19") + self.gridLayout_4.addWidget(self.label_19, 7, 0, 1, 1) + self.label_149 = QtWidgets.QLabel(self.tab_8) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_149.sizePolicy().hasHeightForWidth()) + self.label_149.setSizePolicy(sizePolicy) + self.label_149.setObjectName("label_149") + self.gridLayout_4.addWidget(self.label_149, 0, 0, 1, 1) self.groupBox_taxa_func_link_plot_settings = QtWidgets.QGroupBox(self.tab_8) self.groupBox_taxa_func_link_plot_settings.setMaximumSize(QtCore.QSize(16777215, 220)) self.groupBox_taxa_func_link_plot_settings.setObjectName("groupBox_taxa_func_link_plot_settings") @@ -4542,6 +4453,130 @@ def setupUi(self, metaX_main): self.scrollArea_6.setWidget(self.scrollAreaWidgetContents_7) self.gridLayout_65.addWidget(self.scrollArea_6, 0, 0, 1, 1) self.gridLayout_4.addWidget(self.groupBox_taxa_func_link_plot_settings, 10, 0, 1, 4) + self.comboBox_tflink_meta = QtWidgets.QComboBox(self.tab_8) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.comboBox_tflink_meta.sizePolicy().hasHeightForWidth()) + self.comboBox_tflink_meta.setSizePolicy(sizePolicy) + self.comboBox_tflink_meta.setLayoutDirection(QtCore.Qt.LeftToRight) + self.comboBox_tflink_meta.setObjectName("comboBox_tflink_meta") + self.gridLayout_4.addWidget(self.comboBox_tflink_meta, 0, 1, 1, 1) + self.horizontalLayout_82 = QtWidgets.QHBoxLayout() + self.horizontalLayout_82.setObjectName("horizontalLayout_82") + self.label_others_taxa_num = QtWidgets.QLabel(self.tab_8) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_others_taxa_num.sizePolicy().hasHeightForWidth()) + self.label_others_taxa_num.setSizePolicy(sizePolicy) + self.label_others_taxa_num.setObjectName("label_others_taxa_num") + self.horizontalLayout_82.addWidget(self.label_others_taxa_num) + self.pushButton_others_show_linked_func = QtWidgets.QPushButton(self.tab_8) + self.pushButton_others_show_linked_func.setEnabled(False) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.pushButton_others_show_linked_func.sizePolicy().hasHeightForWidth()) + self.pushButton_others_show_linked_func.setSizePolicy(sizePolicy) + self.pushButton_others_show_linked_func.setObjectName("pushButton_others_show_linked_func") + self.horizontalLayout_82.addWidget(self.pushButton_others_show_linked_func) + self.gridLayout_4.addLayout(self.horizontalLayout_82, 7, 3, 1, 1) + self.radioButton_tflink_sample = QtWidgets.QRadioButton(self.tab_8) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.radioButton_tflink_sample.sizePolicy().hasHeightForWidth()) + self.radioButton_tflink_sample.setSizePolicy(sizePolicy) + self.radioButton_tflink_sample.setObjectName("radioButton_tflink_sample") + self.gridLayout_4.addWidget(self.radioButton_tflink_sample, 3, 0, 1, 1) + self.line_3 = QtWidgets.QFrame(self.tab_8) + self.line_3.setFrameShape(QtWidgets.QFrame.HLine) + self.line_3.setFrameShadow(QtWidgets.QFrame.Sunken) + self.line_3.setObjectName("line_3") + self.gridLayout_4.addWidget(self.line_3, 1, 0, 1, 4) + self.line_6 = QtWidgets.QFrame(self.tab_8) + self.line_6.setFrameShape(QtWidgets.QFrame.HLine) + self.line_6.setFrameShadow(QtWidgets.QFrame.Sunken) + self.line_6.setObjectName("line_6") + self.gridLayout_4.addWidget(self.line_6, 4, 0, 1, 4) + self.horizontalLayout_78 = QtWidgets.QHBoxLayout() + self.horizontalLayout_78.setObjectName("horizontalLayout_78") + self.checkBox_tflink_in_condition = QtWidgets.QCheckBox(self.tab_8) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.checkBox_tflink_in_condition.sizePolicy().hasHeightForWidth()) + self.checkBox_tflink_in_condition.setSizePolicy(sizePolicy) + self.checkBox_tflink_in_condition.setLayoutDirection(QtCore.Qt.LeftToRight) + self.checkBox_tflink_in_condition.setObjectName("checkBox_tflink_in_condition") + self.horizontalLayout_78.addWidget(self.checkBox_tflink_in_condition) + self.comboBox_tflink_condition_meta = QtWidgets.QComboBox(self.tab_8) + self.comboBox_tflink_condition_meta.setEnabled(False) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.comboBox_tflink_condition_meta.sizePolicy().hasHeightForWidth()) + self.comboBox_tflink_condition_meta.setSizePolicy(sizePolicy) + self.comboBox_tflink_condition_meta.setObjectName("comboBox_tflink_condition_meta") + self.horizontalLayout_78.addWidget(self.comboBox_tflink_condition_meta) + self.horizontalLayout_49 = QtWidgets.QHBoxLayout() + self.horizontalLayout_49.setObjectName("horizontalLayout_49") + self.horizontalLayout_77 = QtWidgets.QHBoxLayout() + self.horizontalLayout_77.setObjectName("horizontalLayout_77") + self.comboBox_tflink_condition_group = QtWidgets.QComboBox(self.tab_8) + self.comboBox_tflink_condition_group.setEnabled(False) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.comboBox_tflink_condition_group.sizePolicy().hasHeightForWidth()) + self.comboBox_tflink_condition_group.setSizePolicy(sizePolicy) + self.comboBox_tflink_condition_group.setMaximumSize(QtCore.QSize(300, 16777215)) + self.comboBox_tflink_condition_group.setObjectName("comboBox_tflink_condition_group") + self.horizontalLayout_77.addWidget(self.comboBox_tflink_condition_group) + self.horizontalLayout_49.addLayout(self.horizontalLayout_77) + self.horizontalLayout_78.addLayout(self.horizontalLayout_49) + self.gridLayout_4.addLayout(self.horizontalLayout_78, 2, 1, 1, 1) + self.comboBox_others_func = QtWidgets.QComboBox(self.tab_8) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.comboBox_others_func.sizePolicy().hasHeightForWidth()) + self.comboBox_others_func.setSizePolicy(sizePolicy) + self.comboBox_others_func.setEditable(True) + self.comboBox_others_func.setObjectName("comboBox_others_func") + self.gridLayout_4.addWidget(self.comboBox_others_func, 6, 1, 1, 2) + self.label_18 = QtWidgets.QLabel(self.tab_8) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_18.sizePolicy().hasHeightForWidth()) + self.label_18.setSizePolicy(sizePolicy) + self.label_18.setObjectName("label_18") + self.gridLayout_4.addWidget(self.label_18, 6, 0, 1, 1) + self.comboBox_others_taxa = QtWidgets.QComboBox(self.tab_8) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.comboBox_others_taxa.sizePolicy().hasHeightForWidth()) + self.comboBox_others_taxa.setSizePolicy(sizePolicy) + self.comboBox_others_taxa.setEditable(True) + self.comboBox_others_taxa.setObjectName("comboBox_others_taxa") + self.gridLayout_4.addWidget(self.comboBox_others_taxa, 7, 1, 1, 2) + self.horizontalLayout_101 = QtWidgets.QHBoxLayout() + self.horizontalLayout_101.setObjectName("horizontalLayout_101") + self.label_196 = QtWidgets.QLabel(self.tab_8) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_196.sizePolicy().hasHeightForWidth()) + self.label_196.setSizePolicy(sizePolicy) + self.label_196.setObjectName("label_196") + self.horizontalLayout_101.addWidget(self.label_196) + self.comboBox_tflink_sub_meta = QtWidgets.QComboBox(self.tab_8) + self.comboBox_tflink_sub_meta.setObjectName("comboBox_tflink_sub_meta") + self.horizontalLayout_101.addWidget(self.comboBox_tflink_sub_meta) + self.gridLayout_4.addLayout(self.horizontalLayout_101, 0, 2, 1, 1) self.tabWidget_2.addTab(self.tab_8, "") self.tab_9 = QtWidgets.QWidget() self.tab_9.setObjectName("tab_9") @@ -5300,7 +5335,7 @@ def setupUi(self, metaX_main): self.statusbar.setObjectName("statusbar") metaX_main.setStatusBar(self.statusbar) self.menuBar = QtWidgets.QMenuBar(metaX_main) - self.menuBar.setGeometry(QtCore.QRect(0, 0, 1122, 23)) + self.menuBar.setGeometry(QtCore.QRect(0, 0, 1122, 21)) self.menuBar.setObjectName("menuBar") self.menuTools = QtWidgets.QMenu(self.menuBar) self.menuTools.setObjectName("menuTools") @@ -5360,11 +5395,11 @@ def setupUi(self, metaX_main): self.retranslateUi(metaX_main) self.stackedWidget.setCurrentIndex(0) - self.tabWidget_TaxaFuncAnalyzer.setCurrentIndex(2) + self.tabWidget_TaxaFuncAnalyzer.setCurrentIndex(6) self.toolBox_2.setCurrentIndex(0) self.tabWidget_4.setCurrentIndex(1) self.tabWidget_3.setCurrentIndex(3) - self.tabWidget.setCurrentIndex(0) + self.tabWidget.setCurrentIndex(1) self.tabWidget_2.setCurrentIndex(0) self.tabWidget_6.setCurrentIndex(1) self.toolBox_metalab_res_anno.setCurrentIndex(0) @@ -5406,6 +5441,7 @@ def setupUi(self, metaX_main): self.checkBox_7.toggled['bool'].connect(self.groupBox_taxa_func_link_net_plot_settings.setVisible) # type: ignore self.checkBox_set_taxa_func_split_func.clicked['bool'].connect(self.lineEdit_set_taxa_func_split_func_sep.setEnabled) # type: ignore self.checkBox_set_taxa_func_split_func.clicked['bool'].connect(self.checkBox_set_taxa_func_split_func_share_intensity.setEnabled) # type: ignore + self.checkBox_tflink_plot_mean.clicked['bool'].connect(self.comboBox_tflink_sub_meta.setDisabled) # type: ignore QtCore.QMetaObject.connectSlotsByName(metaX_main) metaX_main.setTabOrder(self.comboBox_taxa_level_to_stast, self.toolButton_meta_table_help) metaX_main.setTabOrder(self.toolButton_meta_table_help, self.comboBox_function_to_stast) @@ -5497,6 +5533,7 @@ def retranslateUi(self, metaX_main): self.comboBox_set_data_transformation.setItemText(2, _translate("metaX_main", "Log 10 transformation")) self.comboBox_set_data_transformation.setItemText(3, _translate("metaX_main", "Square root transformation")) self.comboBox_set_data_transformation.setItemText(4, _translate("metaX_main", "Cube root transformation")) + self.comboBox_set_data_transformation.setItemText(5, _translate("metaX_main", "Box-Cox")) self.comboBox_set_data_normalization.setItemText(0, _translate("metaX_main", "None")) self.comboBox_set_data_normalization.setItemText(1, _translate("metaX_main", "Standard Scaling (Z-Score)")) self.comboBox_set_data_normalization.setItemText(2, _translate("metaX_main", "Min-Max Scaling")) @@ -5914,15 +5951,16 @@ def retranslateUi(self, metaX_main): self.label_148.setText(_translate("metaX_main", "Meta")) self.label_100.setText(_translate("metaX_main", "Select for plotting")) self.groupBox_expression_trends_plot_settings.setTitle(_translate("metaX_main", "Plotting Parameter")) + self.checkBox_trends_plot_interactive_rename_taxa.setText(_translate("metaX_main", "Simplify Taxa Names")) + self.checkBox_trends_plot_interactive_plot_samples.setText(_translate("metaX_main", "Plot Samples")) self.label_174.setText(_translate("metaX_main", "General")) self.label_175.setText(_translate("metaX_main", "Specific cluster")) - self.checkBox_get_trends_cluster_intensity.setText(_translate("metaX_main", "Get Intnsity Results")) - self.label_158.setText(_translate("metaX_main", "Font Size")) - self.label_92.setText(_translate("metaX_main", "Height")) self.checkBox_trends_plot_interactive_show_legend.setText(_translate("metaX_main", "Show Legend")) - self.checkBox_trends_plot_interactive_plot_samples.setText(_translate("metaX_main", "Plot Samples")) - self.checkBox_trends_plot_interactive_rename_taxa.setText(_translate("metaX_main", "Simplify Taxa Names")) + self.checkBox_get_trends_cluster_intensity.setText(_translate("metaX_main", "Get Intnsity Results")) self.label_97.setText(_translate("metaX_main", "Width")) + self.label_92.setText(_translate("metaX_main", "Height")) + self.label_158.setText(_translate("metaX_main", "Font Size")) + self.label_195.setText(_translate("metaX_main", "Number of Col for Cluster Plot")) self.label_93.setText(_translate("metaX_main", "Select Cluster")) self.pushButton_trends_get_trends_table.setText(_translate("metaX_main", "Get ClusterTable")) self.label_165.setText(_translate("metaX_main", "Plot Specific Cluster")) @@ -5933,22 +5971,15 @@ def retranslateUi(self, metaX_main): self.checkBox_5.setText(_translate("metaX_main", "Show Plotting Parameter")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_15), _translate("metaX_main", "Expression Trends")) self.tabWidget_TaxaFuncAnalyzer.setTabText(self.tabWidget_TaxaFuncAnalyzer.indexOf(self.tab_diff_stats), _translate("metaX_main", "Expression Analysis")) - self.label_others_func_num.setText(_translate("metaX_main", "Linked Number: -")) - self.pushButton_others_show_linked_taxa.setText(_translate("metaX_main", "Show Linked Taxa Only")) - self.label_others_taxa_num.setText(_translate("metaX_main", "Linked Number: -")) - self.pushButton_others_show_linked_func.setText(_translate("metaX_main", "Show Linked Func Only")) - self.radioButton_tflink_sample.setText(_translate("metaX_main", "Sample")) - self.radioButton_tflink_group.setText(_translate("metaX_main", "Group")) self.pushButton_others_plot_heatmap.setText(_translate("metaX_main", "Plot Heatmap")) self.pushButton_others_plot_line.setText(_translate("metaX_main", "Plot Bar")) - self.pushButton_others_get_intensity_matrix.setText(_translate("metaX_main", "Get Intensity Table")) + self.pushButton_others_get_intensity_matrix.setText(_translate("metaX_main", "Get Heatmap Table")) self.checkBox_6.setText(_translate("metaX_main", "Show Plotting Parameter")) - self.label_149.setText(_translate("metaX_main", "Meta")) - self.label_18.setText(_translate("metaX_main", "Function")) - self.checkBox_tflink_in_condition.setText(_translate("metaX_main", "In Condition")) + self.radioButton_tflink_group.setText(_translate("metaX_main", "Group")) + self.label_others_func_num.setText(_translate("metaX_main", "Linked Number: -")) + self.pushButton_others_show_linked_taxa.setText(_translate("metaX_main", "Show Linked Taxa Only")) self.pushButton_others_fresh_taxa_func.setToolTip(_translate("metaX_main", "Restore both lists to their original full items")) self.pushButton_others_fresh_taxa_func.setText(_translate("metaX_main", "Reset List")) - self.label_19.setText(_translate("metaX_main", "Taxa")) self.label_75.setText(_translate("metaX_main", "Filter Top")) self.label_76.setText(_translate("metaX_main", "By")) self.comboBox_tflink_top_by.setItemText(0, _translate("metaX_main", "Total Intensity")) @@ -5965,6 +5996,8 @@ def retranslateUi(self, metaX_main): self.checkBox_tflink_top_filtered.setText(_translate("metaX_main", "Filter with threshold")) self.pushButton_tflink_filter.setToolTip(_translate("metaX_main", "Filter items in the two lists by condition")) self.pushButton_tflink_filter.setText(_translate("metaX_main", "Filter")) + self.label_19.setText(_translate("metaX_main", "Taxa")) + self.label_149.setText(_translate("metaX_main", "Meta")) self.groupBox_taxa_func_link_plot_settings.setTitle(_translate("metaX_main", "Plotting Parameter")) self.label_178.setText(_translate("metaX_main", "Bar")) self.checkBox_tflink_hetatmap_col_cluster.setText(_translate("metaX_main", "Col Cluster")) @@ -5989,6 +6022,12 @@ def retranslateUi(self, metaX_main): self.comboBox_tflink_hetatmap_scale.setItemText(2, _translate("metaX_main", "column")) self.comboBox_tflink_hetatmap_scale.setItemText(3, _translate("metaX_main", "all")) self.label_61.setText(_translate("metaX_main", "Theme")) + self.label_others_taxa_num.setText(_translate("metaX_main", "Linked Number: -")) + self.pushButton_others_show_linked_func.setText(_translate("metaX_main", "Show Linked Func Only")) + self.radioButton_tflink_sample.setText(_translate("metaX_main", "Sample")) + self.checkBox_tflink_in_condition.setText(_translate("metaX_main", "In Condition")) + self.label_18.setText(_translate("metaX_main", "Function")) + self.label_196.setText(_translate("metaX_main", "Sub Meta ")) self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_8), _translate("metaX_main", "Taxa-Func Link")) self.radioButton_network_bysample.setText(_translate("metaX_main", "Sample")) self.label_49.setText(_translate("metaX_main", "Table")) diff --git a/metax/taxafunc_analyzer/analyzer_utils/basic_stats.py b/metax/taxafunc_analyzer/analyzer_utils/basic_stats.py index a88243b..d79f70b 100644 --- a/metax/taxafunc_analyzer/analyzer_utils/basic_stats.py +++ b/metax/taxafunc_analyzer/analyzer_utils/basic_stats.py @@ -1,5 +1,6 @@ import pandas as pd from collections import OrderedDict +from scipy import stats class BasicStats: def __init__(self, tfa): @@ -178,4 +179,27 @@ def get_combined_sub_meta_df( else: group_list = [self.tfa.get_group_of_a_sample(i) for i in df.columns] if not plot_mean else df.columns.tolist() - return df, group_list \ No newline at end of file + return df, group_list + + # Shapiro-Wilk Test + def shapiro_test(self, df: pd.DataFrame, alpha=0.05) : + """ + Perform Shapiro-Wilk test on the given DataFrame and return the results. + + Args: + df (pd.DataFrame): The DataFrame to be tested. + alpha (float, optional): The significance level. Defaults to 0.05. + + Returns: + dict: A dictionary containing the boolean result of the Shapiro-Wilk test for each sample. + """ + shapiro_results = {} + for sample in df[self.tfa.sample_list]: + values = df[sample].dropna() + # remove zero values + values = values[values != 0] + _, p = stats.shapiro(values) + # save the boolean result in the dictionary + shapiro_results[sample] = {'p_value': p, 'is_normal': p > alpha} + + return shapiro_results diff --git a/metax/taxafunc_analyzer/analyzer_utils/cross_test.py b/metax/taxafunc_analyzer/analyzer_utils/cross_test.py index bd25fe6..35d3bd3 100644 --- a/metax/taxafunc_analyzer/analyzer_utils/cross_test.py +++ b/metax/taxafunc_analyzer/analyzer_utils/cross_test.py @@ -58,7 +58,7 @@ def _get_df_primary_secondary(self, df_type: str): - def get_stats_anova(self, group_list: list = None, df_type:str = 'taxa-func', condition:list =None) -> pd.DataFrame: + def get_stats_anova(self, group_list: list|None = None, df_type:str = 'taxa-func', condition:list|None =None) -> pd.DataFrame: df_type = self.convert_df_name_to_simple_name(df_type) group_list_all = sorted(set(self.tfa.get_meta_list(self.tfa.meta_name))) @@ -108,7 +108,7 @@ def get_stats_anova(self, group_list: list = None, df_type:str = 'taxa-func', co res_all = res_all[['P-value', 'f-statistic'] + all_sample_list] return res_all - def get_stats_ttest(self, group_list: list = None, df_type: str = 'taxa-func', condition:list =None) -> pd.DataFrame: + def get_stats_ttest(self, group_list: list|None = None, df_type: str = 'taxa-func', condition:list|None =None) -> pd.DataFrame: df_type = self.convert_df_name_to_simple_name(df_type) group_list_all = sorted(set(self.tfa.get_meta_list(self.tfa.meta_name))) @@ -163,7 +163,7 @@ def get_stats_ttest(self, group_list: list = None, df_type: str = 'taxa-func', c res_all = res_all[['P-value', 't-statistic'] + all_sample_list] return res_all - def get_stats_dunnett_test_against_control_with_conditon(self, control_group, condition, group_list:list =None, df_type: str = 'taxa-func') -> pd.DataFrame: + def get_stats_dunnett_test_against_control_with_conditon(self, control_group, condition, group_list:list|None =None, df_type: str = 'taxa-func') -> pd.DataFrame: df_type = self.convert_df_name_to_simple_name(df_type) meta_df = self.tfa.meta_df.copy() @@ -183,7 +183,7 @@ def get_stats_dunnett_test_against_control_with_conditon(self, control_group, co return res_df # a dataframe with 3 level columns index - def get_stats_dunnett_test(self, control_group, group_list: list = None, df_type: str = 'taxa-func', condition:list =None) -> pd.DataFrame: + def get_stats_dunnett_test(self, control_group, group_list: list|None = None, df_type: str = 'taxa-func', condition:list|None =None) -> pd.DataFrame: df_type = self.convert_df_name_to_simple_name(df_type) group_list_all = sorted(set(self.tfa.get_meta_list(self.tfa.meta_name))) @@ -327,7 +327,7 @@ def get_stats_deseq2_against_control_with_conditon(self, df, control_group, cond return res_df # a dataframe with 3 level columns index - def get_stats_deseq2_against_control(self, df, control_group, group_list: list = None, concat_sample_to_result: bool = False, quiet: bool = False, condition: list = None) -> pd.DataFrame: + def get_stats_deseq2_against_control(self, df, control_group, group_list: list|None = None, concat_sample_to_result: bool = False, quiet: bool = False, condition: list|None = None) -> pd.DataFrame: all_group_list = sorted(set(self.tfa.group_list)) if group_list is None: group_list = all_group_list @@ -359,7 +359,7 @@ def get_stats_deseq2_against_control(self, df, control_group, group_list: list = - def get_stats_deseq2(self, df, group1, group2, concat_sample_to_result: bool = True, quiet: bool = False, condition: list = None) -> pd.DataFrame: + def get_stats_deseq2(self, df, group1, group2, concat_sample_to_result: bool = True, quiet: bool = False, condition: list|None = None) -> pd.DataFrame: print(f'\n--Running Deseq2 [{group1}] vs [{group2}] with condition: [{condition}]--') group1_sample = self.tfa.get_sample_list_in_a_group(group1, condition=condition) @@ -447,7 +447,7 @@ def get_stats_deseq2(self, df, group1, group2, concat_sample_to_result: bool = T return res_merged # Get the Tukey test result of a taxon or a function - def get_stats_tukey_test(self, taxon_name: str=None, func_name: str=None, sum_all: bool=True, condition:list =None): + def get_stats_tukey_test(self, taxon_name: str|None =None, func_name: str|None =None, sum_all: bool=True, condition:list|None =None): # :param taxon_name: the taxon name # :param func_name: the function name # :return: the Tukey test result @@ -459,7 +459,7 @@ def get_stats_tukey_test(self, taxon_name: str=None, func_name: str=None, sum_al return tukey_df - def get_stats_tukey_test_each(self, taxon_name: str = None, func_name: str = None, condition:list =None): + def get_stats_tukey_test_each(self, taxon_name: str|None = None, func_name: str|None = None, condition:list|None =None): # Copy the dataframe and reset index df = self.tfa.taxa_func_df.copy() df = df.reset_index() @@ -515,7 +515,7 @@ def get_stats_tukey_test_each(self, taxon_name: str = None, func_name: str = Non # Return the combined Tukey test results return tukey_results - def get_stats_tukey_test_sum(self, taxon_name: str=None, func_name: str=None, condition:list =None): + def get_stats_tukey_test_sum(self, taxon_name: str|None=None, func_name: str|None=None, condition:list|None =None): # :param taxon_name: the taxon name # :param func_name: the function name # :return: the Tukey test result @@ -569,10 +569,10 @@ def get_stats_tukey_test_sum(self, taxon_name: str=None, func_name: str=None, co # find out the items that are not significant in taxa but significant in function, and vice versa - def get_stats_diff_taxa_but_func(self, group_list: list = None, p_value: float = 0.05, - taxa_res_df: pd.DataFrame =None, - func_res_df: pd.DataFrame=None, - taxa_func_res_df: pd.DataFrame=None, condition:list =None) -> tuple: + def get_stats_diff_taxa_but_func(self, group_list: list|None = None, p_value: float = 0.05, + taxa_res_df: pd.DataFrame|None =None, + func_res_df: pd.DataFrame|None =None, + taxa_func_res_df: pd.DataFrame|None =None, condition:list|None =None) -> tuple: # calculate the test result if not given if taxa_res_df is None or func_res_df is None or taxa_func_res_df is None: @@ -605,10 +605,11 @@ def get_stats_diff_taxa_but_func(self, group_list: list = None, p_value: float = # check the p_value is between 0 and 1 if p_value < 0 or p_value > 1: raise ValueError("p_value must be between 0 and 1") - # 获取p-value大于0.05的Taxon条目 + # 获取p-value大于0.05的Taxon items not_significant_taxa = df_taxa_test_res[df_taxa_test_res['P-value'] >= p_value].index.get_level_values('Taxon').tolist() print(f"Under P-value = {p_value}: \n \ Significant Taxa: [{len(df_taxa_test_res) - len(not_significant_taxa)}], Not Significant Taxa: [{len(not_significant_taxa)}]") + # 获取p-value小于0.05的Function items not_significant_func = df_func_test_res[df_func_test_res['P-value'] >= p_value].index.get_level_values(self.tfa.func_name).tolist() print(f"Under P-value = {p_value}: \n \ Significant Function: [{len(df_func_test_res) - len(not_significant_func)}], Not Significant Function: [{len(not_significant_func)}]") diff --git a/metax/taxafunc_analyzer/analyzer_utils/data_preprocessing.py b/metax/taxafunc_analyzer/analyzer_utils/data_preprocessing.py index c5673c7..fd53b73 100644 --- a/metax/taxafunc_analyzer/analyzer_utils/data_preprocessing.py +++ b/metax/taxafunc_analyzer/analyzer_utils/data_preprocessing.py @@ -2,6 +2,7 @@ from .re_combat import reComBat import numpy as np from joblib import Parallel, delayed +from scipy import stats @@ -71,7 +72,8 @@ def _data_transform(self, df: pd.DataFrame, transform_method: str = None) -> pd. 'cube': np.cbrt, 'log10': lambda x: np.log10(x + 1), 'log2': lambda x: np.log2(x + 1), - 'sqrt': np.sqrt + 'sqrt': np.sqrt, + 'boxcox': lambda x: x.apply(lambda col: stats.boxcox(col + 1)[0]) } if transform_method in transform_operations: diff --git a/metax/taxafunc_ploter/bar_plot_js.py b/metax/taxafunc_ploter/bar_plot_js.py index b04e374..5be6694 100644 --- a/metax/taxafunc_ploter/bar_plot_js.py +++ b/metax/taxafunc_ploter/bar_plot_js.py @@ -42,10 +42,10 @@ def _add_group_name_to_sample(self, df): return df - def plot_intensity_bar(self, taxon_name:str=None, sample_list:list = None, - func_name:str=None, peptide_seq=None, + def plot_intensity_bar(self, taxon_name:str|None=None, sample_list:list|None = None, + func_name:str|None =None, peptide_seq=None, width:int=1200, height:int=800, df= None, - title:str=None, rename_taxa:bool=False, + title:str|None =None, rename_taxa:bool=False, show_legend:bool=True, font_size:int=10, rename_sample:bool=True, plot_mean:bool=False, plot_percent:bool=False, sub_meta:str="None", @@ -83,16 +83,25 @@ def plot_intensity_bar(self, taxon_name:str=None, sample_list:list = None, df = df.div(df.sum(axis=0), axis=1) * 100 - # create title + # Create title if title is None: - if taxon_name is None: - title = f'{func_name}' - elif func_name is None: - title = f'{taxon_name}' - elif peptide_seq is not None: + if peptide_seq is not None: title = f'The intensity of {peptide_seq}' else: - title = f'{taxon_name}\n{func_name}' + renamed_taxon = taxon_name.split('|')[-1] if rename_taxa and taxon_name else taxon_name + + # If only taxon_name exists + if renamed_taxon and not func_name: + title = f'{renamed_taxon}' + + # If only func_name exists + elif func_name and not renamed_taxon: + title = f'{func_name}' + + # If both taxon_name and func_name exist + elif renamed_taxon and func_name: + title = f'{renamed_taxon}\n{func_name}' + global_opts_params = { "legend_opts": opts.LegendOpts( diff --git a/metax/taxafunc_ploter/heatmap_plot.py b/metax/taxafunc_ploter/heatmap_plot.py index cf5c5b2..63de651 100644 --- a/metax/taxafunc_ploter/heatmap_plot.py +++ b/metax/taxafunc_ploter/heatmap_plot.py @@ -52,6 +52,10 @@ def rename_taxa(self, df): f'{i.split(" <")[0].split("|")[-1]} <{i.split(" <")[1][:-1]}>' for i in index_list ] + # check if the new_index_list is unique + if len(new_index_list) != len(set(new_index_list)): + raise ValueError("Duplicate taxa names after renaming!") + df.index = new_index_list return df @@ -246,6 +250,10 @@ def plot_basic_heatmap_of_test_res(self, df, top_number:int = 100, value_type:st else: raise ValueError("No 'f-statistic' or 't-statistic' in the dataframe") + # if mat is empty, raise error + if mat.empty: + raise ValueError(f"No significant differences between groups in {plot_type} <= [{pvalue}]") + if len(mat) < 2: row_cluster = False if len(mat.columns) < 2: @@ -338,7 +346,7 @@ def plot_basic_heatmap_of_test_res(self, df, top_number:int = 100, value_type:st except Exception as e: print(f'Error: {e}') plt.close('all') - raise ValueError("No significant differences") + raise ValueError(f"Error: {e}") # Plot basic heatmap of matrix with color bar @@ -349,7 +357,7 @@ def plot_basic_heatmap(self, df, title = 'Heatmap',fig_size:tuple|None = None, scale = None, col_cluster:bool = True, row_cluster:bool = True, cmap:str|None = None, rename_taxa:bool = True, font_size:int = 10, show_all_labels:tuple = (False, False), rename_sample:bool = True, plot_mean:bool = False, - sub_meta: str = "None", scale_method:str = 'maxmin' + sub_meta: str = "None", scale_method:str = 'maxmin', return_type:str = 'fig' ): ''' sub_meta is higher plot_mean, if sub_meta provided, plot_mean is False @@ -357,6 +365,7 @@ def plot_basic_heatmap(self, df, title = 'Heatmap',fig_size:tuple|None = None, if plot_mean and sub_meta == 'None': # if sub_meta is not None, plot_mean is False df = self.tfa.BasicStats.get_stats_mean_df_by_group(df) + print('Plot the mean of the data, set rename_sample to False') rename_sample = False @@ -373,22 +382,40 @@ def plot_basic_heatmap(self, df, title = 'Heatmap',fig_size:tuple|None = None, if rename_taxa: mat = self.rename_taxa(mat) - if cmap is None: - cmap = 'YlOrRd' - if fig_size is None: - fig_size = (30,30) - mat, group_list = self.tfa.BasicStats.get_combined_sub_meta_df(df=mat, sub_meta=sub_meta, rename_sample=rename_sample, plot_mean=plot_mean) - color_list = self.assign_colors(group_list) - - # if only one column, remove col_cluster, set scale to None if len(mat.columns) < 2: col_cluster = False # scale = None + + if return_type == 'table': + sns_params = { + "col_cluster": col_cluster, + "row_cluster": row_cluster, + "method": self.linkage_method, + "metric": self.distance_metric, + } + fig = sns.clustermap(mat, **sns_params) + # get the sorted dataframe + if row_cluster and not col_cluster: + sorted_df = mat.iloc[fig.dendrogram_row.reordered_ind, :] + elif col_cluster and not row_cluster: + sorted_df = mat.iloc[:, fig.dendrogram_col.reordered_ind] + elif row_cluster and col_cluster: + sorted_df = mat.iloc[fig.dendrogram_row.reordered_ind, fig.dendrogram_col.reordered_ind] + else: + sorted_df = mat + plt.close(fig.figure) + return sorted_df + + # else plot heatmap figure + if cmap is None: + cmap = 'YlOrRd' + if fig_size is None: + fig_size = (30,30) - + color_list = self.assign_colors(group_list) sns_params = { # "center": 0, "cmap": cmap, diff --git a/metax/taxafunc_ploter/line_plot.py b/metax/taxafunc_ploter/line_plot.py index cac6257..2830c98 100644 --- a/metax/taxafunc_ploter/line_plot.py +++ b/metax/taxafunc_ploter/line_plot.py @@ -4,31 +4,48 @@ class LinePlot: def __init__(self, tfobj): - self.tfobj = tfobj + self.tfa = tfobj # plot intensity line for each sample # Example: plot_intensity_line(sw, func_name=func_name, taxon_name=taxon_name, fig_size=(30,20)) - def plot_intensity_line(self, taxon_name:str=None, sample_list:list = None, func_name:str=None, peptide_seq=None, width:int=20, height:int=12): - fig_size = (width, height) + def plot_intensity_line( + self, + taxon_name: str|None = None, + sample_list: list|None = None, + func_name: str|None = None, + peptide_seq=None, + fig_size: tuple = (20, 12), + plot_mean: bool = False, + rename_taxa: bool = True, + rename_sample: bool = True, + ): + sns.set_theme() + plt.style.use('bmh') - df = self.tfobj.GetMatrix.get_intensity_matrix(taxon_name=taxon_name, func_name=func_name, peptide_seq=peptide_seq, sample_list= sample_list) + df = self.tfa.GetMatrix.get_intensity_matrix( + taxon_name=taxon_name, + func_name=func_name, + peptide_seq=peptide_seq, + sample_list=sample_list, + ) if df.empty: raise ValueError('No data to plot') - # create color list for groups & rename columns - col_names = df.columns.tolist() - meta_df = self.tfobj.meta_df - meta_name = self.tfobj.meta_name - groups_list = [] - new_col_names = [] - for i in col_names: - group = meta_df[meta_df['Sample'] == i] - group = group[meta_name].values[0] - new_col_names.append(f'{i} ({group})') - groups_list.append(group) - df.columns = new_col_names + + + if plot_mean: + df = self.tfa.BasicStats.get_stats_mean_df_by_group(df) + rename_sample = False + + if rename_sample: + df, _ = self.tfa.add_group_name_for_sample(df) + index_name = df.index.name + color_list = "tab10" if len(df) <= 10 else "tab20" # create title + if rename_taxa and taxon_name is not None: + taxon_name = taxon_name.split('|')[-1] + if taxon_name is None: title = f'{func_name}' elif func_name is None: @@ -41,12 +58,35 @@ def plot_intensity_line(self, taxon_name:str=None, sample_list:list = None, func dfp = pd.melt(df.reset_index(), id_vars=index_name, var_name='Samples', value_name='Intensity') plt.figure(figsize=fig_size) - fig = sns.lineplot(x='Samples', y='Intensity', hue=index_name, data=dfp, palette='Set1', legend = True) - + fig = sns.lineplot( + x="Samples", + y="Intensity", + hue=index_name, + data=dfp, + palette=color_list, + legend=True, + ) + fig.set_title(title, fontsize=15) - fig.set_xlabel('Samples', fontsize=15) + fig.set_xlabel('') fig.set_ylabel('Intensity', fontsize=15) - fig.tick_params(axis='x', rotation=90, labelsize=8) + fig.tick_params(axis='x', rotation=0, labelsize=15) + + + # set legend out of the plot + plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.) + plt.show() return fig + + +# LinePlot(sw).plot_intensity_line(taxon_name="d__Bacteria|p__Proteobacteria|c__Gammaproteobacteria|o__Enterobacterales|f__Enterobacteriaceae|g__Citrobacter_B|s__Citrobacter_B koseri", +# sample_list=sample_list, +# func_name="ko00061:Fatty acid biosynthesis", +# plot_mean=True, +# rename_taxa=True, +# rename_sample=True, +# fig_size=(10,8) + +# ) \ No newline at end of file diff --git a/metax/taxafunc_ploter/trends_plot.py b/metax/taxafunc_ploter/trends_plot.py index e342843..6522bc5 100644 --- a/metax/taxafunc_ploter/trends_plot.py +++ b/metax/taxafunc_ploter/trends_plot.py @@ -3,12 +3,13 @@ from sklearn.cluster import KMeans import matplotlib.pyplot as plt import seaborn as sns +import math class TrendsPlot: def __init__(self, tfobj): - self.tfobj = tfobj - - def plot_trends(self, df, num_cluster, width=15, height=5, title='Cluster', font_size=10): + self.tfobj = tfobj + + def plot_trends(self, df, num_cluster, width=15, height=5, title='Cluster', font_size=10, num_col=1): # Load the data df = self.tfobj.BasicStats.get_stats_mean_df_by_group(df) @@ -26,18 +27,19 @@ def plot_trends(self, df, num_cluster, width=15, height=5, title='Cluster', font # Add the cluster labels to the DataFrame clustered_df = scaled_df.copy() - # 不再重新排序列 - # adding the cluster column clustered_df['Cluster'] = clusters - - custom_params = {"axes.spines.right": False, "axes.spines.top": False} + custom_params = {"axes.spines.right": False, "axes.spines.top": False} sns.set_theme(style="ticks", rc=custom_params) palette = sns.color_palette("dark", n_clusters) - try: - fig, axs = plt.subplots(n_clusters, 1, figsize=(width, height*n_clusters)) - if n_clusters == 1: - axs = [axs] + + try: + # Calculate the number of rows based on num_col + num_row = math.ceil(n_clusters / num_col) + + fig, axs = plt.subplots(num_row, num_col, figsize=(width, height * num_row)) + axs = axs.flatten() # Flatten the axs array for easy iteration + for i in range(n_clusters): cluster_data = clustered_df[clustered_df['Cluster'] == i] avg_data = cluster_data.drop('Cluster', axis=1).mean() @@ -53,6 +55,11 @@ def plot_trends(self, df, num_cluster, width=15, height=5, title='Cluster', font axs[i].tick_params(axis='x', rotation=90) # Rotate x-axis labels axs[i].tick_params(axis='both', which='major', labelsize=font_size) + # Remove any empty subplots if n_clusters is not a perfect multiple of num_col + for ax in axs[n_clusters:]: + ax.remove() + + plt.tight_layout() plt.close() return fig, clustered_df except Exception as e: diff --git a/metax/utils/version.py b/metax/utils/version.py index eab6ab7..c0b048d 100644 --- a/metax/utils/version.py +++ b/metax/utils/version.py @@ -1,2 +1,2 @@ -__version__ = '1.111.7' +__version__ = '1.112.0' API_version = '2' \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 74307c6..000827b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "MetaXTools" -version = "1.111.7" +version = "1.112.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" }