diff --git a/Docs/ChangeLog.md b/Docs/ChangeLog.md
index 4bef56c..ca4ca32 100644
--- a/Docs/ChangeLog.md
+++ b/Docs/ChangeLog.md
@@ -1,3 +1,21 @@
+# Version: 1.107.8
+## Date: 2024-06-26
+### Changes:
+- Change:
+- 1.Use the heap as the default data structure to apply razor method to sum peptide intensity to protein intensity.
+- 2.Changed the update message to a dialog window to show the update message to avoid the update message is too long to show in the message box.
+
+# Version: 1.107.7
+## Date: 2024-06-24
+### Changes:
+- Change: Changed the method of summing peptiede intensity to protein intensity, changed the method "razor" to same as MaxQuant, and added a new method "rank".
+
+# Version: 1.107.6
+## Date: 2024-06-19
+### Changes:
+- New: added an option in Settings to enable user to set the color of the theme (white or dark) of the HTML plot.
+
+
# Version: 1.107.5
## Date: 2024-06-18
### Changes:
diff --git a/Docs/MetaX_Cookbook.assets/settings_page2.png b/Docs/MetaX_Cookbook.assets/settings_page2.png
index 2564529..e081c18 100644
Binary files a/Docs/MetaX_Cookbook.assets/settings_page2.png and b/Docs/MetaX_Cookbook.assets/settings_page2.png differ
diff --git a/Docs/MetaX_Cookbook.md b/Docs/MetaX_Cookbook.md
index 341293e..eb1daf7 100644
--- a/Docs/MetaX_Cookbook.md
+++ b/Docs/MetaX_Cookbook.md
@@ -116,7 +116,7 @@ The **Database Updater** allows updating the database built by the **Database Bu
### 1. Results from MAG Workflow
-The peptide results use Metagenome-assembled genomes (MAGs) as the reference database for protein searches, e.g., MetaLab-MAG and other databases like MGnify.
+The peptide results use Metagenome-assembled genomes (MAGs) as the reference database for protein searches, e.g., MetaLab-MAG, MetaLab-DIA and other workflows wich using MAG databases like MGnify or customized MAGs Database.
- Annotate the peptide to Operational Taxa-Functions (OTF) Table before analysis using the Peptide Annotator.
@@ -227,9 +227,16 @@ The Data Overview provides basic information about your data, such as the number
Click **Create Proteins Intensity Table** to sum peptides to proteins if the Protein column is in the original table.
-- **Occam's Razor and Anti-Razor:** Methods available for inferring shared peptides.
- 1. Build the rank of proteins.
- 2. Choose the protein with a higher rank for the shared peptide.
+- **Occam's Razor**, **Anti-Razor** and **Rank:** Methods available for inferring shared peptides.
+ - Razor:
+ 1. Build a minimal set of proteins to cover all peptides.
+ 2. For each peptide, choose the protein which has most peptides (if multiple proteins have the same number of peptides, share intensity to them).
+ - Anti-Razor:
+ - All proteins are shared the intensity of each peptide.
+ - Rank:
+ 1. Build the rank of proteins.
+ 2. Choose the protein with a higher rank for the shared peptide.
+
- **Methods to Build Protein Rank:**
- unique_counts: Use the counts of proteins inferred by unique peptides.
@@ -709,6 +716,7 @@ We can select **meta** **groups** or **samples** (default a
- The yellow dots are taxa, and the grey dots are functions, the size of the dots presents the intensity
- The red dots are the taxa we focused on
- The green dots are the functions we focused on
+- More parameters can be set in **Dev**->**Settings**->**Others** (e.g. Nodes Shape, color, Line Style)
diff --git a/utils/AnalyzerUtils/SumProteinIntensity.py b/utils/AnalyzerUtils/SumProteinIntensity.py
index db35c6b..55bd907 100644
--- a/utils/AnalyzerUtils/SumProteinIntensity.py
+++ b/utils/AnalyzerUtils/SumProteinIntensity.py
@@ -1,40 +1,46 @@
# This file is used to sum the protein intensity for each sample
-# Method: razor or anti-razor
+# Method: razor, anti-razor or rank
# By sample: True or False
# Output: a dataframe with protein as index and sample as columns
##############################################
# USAGE:
# from utils.AnalyzerUtils.SumProteinIntensity import SumProteinIntensity
# out = SumProteinIntensity(sw)
-# df1 = out.sum_protein_intensity(method='razor', by_sample=False, rank_method='count')
-# df2 = out.sum_protein_intensity(method='razor', by_sample=False, rank_method='shared')
-# df3 = out.sum_protein_intensity(method='razor', by_sample=False, rank_method='unique')
+# df0 = out.sum_protein_intensity(method='razor')
+# df1 = out.sum_protein_intensity(method='rank', by_sample=False, rank_method='all_counts')
+# df2 = out.sum_protein_intensity(method='rank', by_sample=False, rank_method='shared_intensity')
+# df3 = out.sum_protein_intensity(method='rank', by_sample=False, rank_method='unique_counts')
# df4 = out.sum_protein_intensity(method='anti-razor')
##############################################
+from collections import defaultdict
import pandas as pd
+from tqdm import tqdm
+
class SumProteinIntensity:
def __init__(self, taxa_func_analyzer):
self.tfa = taxa_func_analyzer
- self.res_intensity_dict = {} #store all sample to output
- self.rank_dict = {} #store the rank of protein intensity for each sample temporarily
- self.rank_method = None
+ self.res_intensity_dict = {} # store all sample to output
+ self.rank_dict = {} # store the rank of protein intensity for each sample temporarily
+ self.rank_method = None # only used for rank method
self.extract_col_name = [self.tfa.peptide_col_name, self.tfa.protein_col_name] + self.tfa.sample_list
- self.df = self.tfa.original_df.loc[:,self.extract_col_name]
+ self.df = self.tfa.original_df.loc[:, self.extract_col_name]
self._init_dicts()
+ self.greedy_method = None # only used for razor method
- def sum_protein_intensity(self, method='razor', by_sample=False, rank_method='unique_counts'):
+ def sum_protein_intensity(self, method='razor', by_sample=False, rank_method='unique_counts', greedy_method='heap'):
- if method not in ['razor', 'anti-razor']:
- raise ValueError('Method must in ["razor", "anti-razor"]')
+ if method not in ['razor', 'anti-razor', 'rank']:
+ raise ValueError('Method must in ["razor", "anti-razor", "rank"]')
if rank_method not in ['shared_intensity', 'all_counts', 'unique_counts', 'unique_intensity']:
raise ValueError('Rank method must in ["shared_intensity", "all_counts", "unique_counts", "unique_intensity"]')
self.rank_method = rank_method
+ self.greedy_method = greedy_method
- if method == 'razor':
+ if method == 'rank':
print(f"\n-------------Start to sum protein intensity using method: [{method}] by_sample: [{by_sample}] rank_method: [{rank_method}]-------------")
# make a dict to count the intensity of each protein, intensity sahred by peptides will be divided by the number of peptides
if by_sample:
@@ -42,7 +48,7 @@ def sum_protein_intensity(self, method='razor', by_sample=False, rank_method='un
# update the dict for each sample
print(f'Creating protein rank dict for [{sample}] by shared intensity', end='\r')
self._update_protein_rank_dict(sample_name = sample, rank_method = rank_method)
- self._sum_protein_razor(sample, by_sample)
+ self._sum_protein_rank(sample, by_sample)
else: # without sample
# only need to create the dict once
@@ -51,8 +57,12 @@ def sum_protein_intensity(self, method='razor', by_sample=False, rank_method='un
self._update_protein_rank_dict(sample_name = None, rank_method = rank_method)
for sample in self.tfa.sample_list:
- self._sum_protein_razor(sample, by_sample)
-
+ self._sum_protein_rank(sample, by_sample)
+ elif method == 'razor':
+ print('start to sum protein intensity using method: [razor]')
+ # use Set Cover Problem to get the protein list, then sum the intensity
+ pep_to_protein = self._create_pep_to_protein_razor()
+ self._sum_protein_razor(pep_to_protein)
elif method == 'anti-razor':
print(f"\n-------------Start to sum protein intensity using method: [{method}] by_sample: [True] rank_method: [Shared]-------------")
@@ -76,7 +86,119 @@ def sum_protein_intensity(self, method='razor', by_sample=False, rank_method='un
return res_df
+ # razor method
+ def find_minimum_protein_set(self, peptides, protein_to_peptides):
+ protein_to_peptides_copy = protein_to_peptides.copy()
+ peptides_to_cover = set(peptides)
+ selected_proteins = set()
+ method = self.greedy_method
+
+ if method == 'greedy':
+ print('Start creating protein dict for "Set Cover Problem" with Greedy Approximation Algorithm')
+ with tqdm(total=len(peptides_to_cover), desc="Covering peptides") as pbar:
+ while peptides_to_cover:
+ best_protein = None
+ peptides_covered_by_best = set()
+ for protein, covered_peptides in protein_to_peptides_copy.items():
+ covered = peptides_to_cover & covered_peptides
+ if len(covered) > len(peptides_covered_by_best):
+ best_protein = protein
+ peptides_covered_by_best = covered
+
+ if not best_protein:
+ break
+
+ selected_proteins.add(best_protein)
+ peptides_to_cover -= peptides_covered_by_best
+ protein_to_peptides_copy.pop(best_protein) # remove the protein from the dict to speed up the process
+ pbar.update(len(peptides_covered_by_best))
+ elif method == 'heap':
+ import heapq
+ print('Start creating protein dict for "Set Cover Problem" with Heap Optimization of Greedy Approximation Algorithm')
+ protein_coverage = {protein: covered_peptides & peptides_to_cover
+ for protein, covered_peptides in protein_to_peptides_copy.items()}
+ protein_heap = [(-len(covered), protein) for protein, covered in protein_coverage.items()]
+ heapq.heapify(protein_heap)
+
+ with tqdm(total=len(peptides_to_cover), desc="Covering peptides") as pbar:
+ while peptides_to_cover:
+ while protein_heap:
+ max_covered, best_protein = heapq.heappop(protein_heap)
+ if best_protein in protein_coverage:
+ peptides_covered_by_best = protein_coverage.pop(best_protein)
+ break
+
+ if not best_protein or not peptides_covered_by_best:
+ break
+
+ selected_proteins.add(best_protein)
+ peptides_to_cover -= peptides_covered_by_best
+ pbar.update(len(peptides_covered_by_best))
+
+ # update other proteins' coverage
+ for protein in list(protein_coverage.keys()):
+ if protein_coverage[protein] & peptides_covered_by_best:
+ protein_coverage[protein] -= peptides_covered_by_best
+ heapq.heappush(protein_heap, (-len(protein_coverage[protein]), protein))
+ if not protein_coverage[protein]:
+ del protein_coverage[protein]
+ else:
+ raise ValueError(f"Invalid greedy method: {method}. Must be ['greedy' or 'heap']")
+
+ return selected_proteins
+ def _create_pep_to_protein_razor(self) -> dict:
+ """
+ Create a dictionary mapping peptides to proteins based on a minimum protein set.
+
+ Returns:
+ dict: A dictionary mapping peptides to proteins.
+ key: peptide
+ value: a list of proteins
+ """
+
+ df = self.df.loc[:, [self.tfa.peptide_col_name, self.tfa.protein_col_name]]
+ # Create a dictionary mapping proteins to peptides
+ protein_to_peptides = defaultdict(set)
+ peptides = set(df[self.tfa.peptide_col_name])
+
+ for _, row in tqdm(df.iterrows(), total=df.shape[0], desc="Creating protein to peptides mapping"):
+ sequence = row[self.tfa.peptide_col_name]
+ proteins = row[self.tfa.protein_col_name].split(';')
+ for protein in proteins:
+ protein_to_peptides[protein].add(sequence)
+
+ mini_protein_set = self.find_minimum_protein_set(peptides, protein_to_peptides)
+
+ # remove the proteins not in the mini_protein_set from the protein_to_peptides
+ filtered_protein_to_peptides = {protein: protein_to_peptides[protein] for protein in mini_protein_set}
+ # Assign each peptide to the protein that contains it with the highest peptide count
+ print('Assigning peptides to proteins')
+ peptide_to_protein = defaultdict(list)
+ for peptide in tqdm(peptides, desc="Assigning peptides to proteins"):
+ possible_proteins = [protein for protein, peps in filtered_protein_to_peptides.items() if peptide in peps]
+ if possible_proteins:
+ # 找到包含该肽最多的蛋白质
+ max_protein_count = max(len(filtered_protein_to_peptides[protein]) for protein in possible_proteins)
+ best_proteins = [protein for protein in possible_proteins if len(filtered_protein_to_peptides[protein]) == max_protein_count]
+ peptide_to_protein[peptide].extend(best_proteins)
+
+ return peptide_to_protein
+
+ def _sum_protein_razor(self, peptide_to_protein: dict):
+
+ for sample in tqdm(self.tfa.sample_list):
+ print(f'Assigning protein intensity for [{sample}]')
+ df = self.df.loc[:,[ self.tfa.peptide_col_name, sample]]
+ # create a dict to store the intensity of each peptide
+ df.set_index(self.tfa.peptide_col_name, inplace=True)
+ peptide_intensity_dict = df.to_dict()[sample]
+ for peptide, proteins in peptide_to_protein.items():
+ intensity = peptide_intensity_dict[peptide]
+ self._update_output_dict(proteins, sample, intensity)
+
+
+
def _init_dicts(self):
for sample in self.tfa.sample_list:
self.res_intensity_dict[sample] = {}
@@ -147,7 +269,7 @@ def _update_output_dict(self, protein_list: list, sample_name:str, intensity:flo
self.res_intensity_dict[sample_name][protein] = intensity
- def _sum_protein_razor(self, sample_name:str, by_sample=False):
+ def _sum_protein_rank(self, sample_name:str, by_sample=False):
# print in one line
print(f'Asigning protein intensity for [{sample_name}]', end='\r')
df = self.df.loc[:,[ self.tfa.protein_col_name, sample_name]]
@@ -180,7 +302,4 @@ def _sum_protein_anti_razor(self, sample_name:str):
for row in df.itertuples():
proteins = row[1].split(';')
intensity = row[2]
- self._update_output_dict(proteins, sample_name, intensity)
-
-
-
+ self._update_output_dict(proteins, sample_name, intensity)
\ No newline at end of file
diff --git a/utils/GUI.py b/utils/GUI.py
index e7dfee7..77a1dfc 100644
--- a/utils/GUI.py
+++ b/utils/GUI.py
@@ -129,9 +129,6 @@ def __init__(self, MainWindow):
# Check and load settings
self.load_basic_Settings()
- # set the default theme mode
- self.theme = 'white'
-
#check update
self.update_required = False
self.check_update(manual_check_trigger=False)
@@ -161,6 +158,9 @@ def __init__(self, MainWindow):
self.add_theme_to_combobox()
# ploting parameters
+ # set the default theme mode
+ self.html_theme = 'white'
+
self.heatmap_params_dict = {'linkage_method': 'average', 'distance_metric': 'euclidean'}
self.tf_link_net_params_dict = {'taxa_shape': 'circle', 'func_shape': 'rect',
@@ -650,12 +650,21 @@ def show_settings_window(self):
self.settings_dialog.setModal(False)
layout = QVBoxLayout(self.settings_dialog)
self.settings_dialog.resize(900, 600)
-
- settings_widget = SettingsWidget(self.settings_dialog, self.update_branch, self.auto_check_update)
+ # General settings
+ settings_widget = SettingsWidget(
+ parent=self.settings_dialog,
+ update_branch=self.update_branch,
+ auto_check_update=self.auto_check_update,
+ QSettings=self.settings,
+ )
settings_widget.update_mode_changed.connect(self.on_update_mode_changed)
settings_widget.auto_check_update_changed.connect(self.on_auto_check_update_changed)
+ # plotting parameters
settings_widget.heatmap_params_dict_changed.connect(self.on_heatmap_params_changed)
settings_widget.tf_link_net_params_dict_changed.connect(self.on_tf_link_net_params_changed)
+ settings_widget.html_theme_changed.connect(self.on_html_theme_changed)
+ # Other settings
+ settings_widget.protein_infer_method_changed.connect(self.on_protein_infer_method_changed)
layout.addWidget(settings_widget)
self.settings_dialog.setLayout(layout)
@@ -682,6 +691,15 @@ def on_tf_link_net_params_changed(self, params_dict):
self.tf_link_net_params_dict = params_dict
print(f"Taxa-func link network params changed to: {params_dict}")
+ def on_html_theme_changed(self, theme):
+ self.html_theme = theme
+ print(f"HTML theme changed to: {theme}")
+
+ def on_protein_infer_method_changed(self, method):
+ #save to settings
+ self.settings.setValue("protein_infer_greedy_mode", method)
+ print(f"Protein infering razor mode changed to: {method}")
+
############### basic function End ###############
@@ -722,9 +740,11 @@ def change_theme(self, theme, silent=False):
self.show_message(f"Changing theme to {theme}...")
# save the theme to settings
self.settings.setValue("theme", theme)
- # save the theme mode to GUI attribute (dark or light)
- self.theme = 'dark' if 'dark' in theme else 'white'
- print(f"Theme mode: {self.theme}")
+
+ #! Deprecated, switch to manual change in Settings
+ ## save the theme mode to GUI attribute (dark or light)
+ # self.html_theme = 'dark' if 'dark' in theme else 'white'
+ # print(f"Theme mode: {self.html_theme}")
# recover the .xml suffix
theme = theme + '.xml'
@@ -824,8 +844,8 @@ def change_theme(self, theme, silent=False):
def change_event_checkBox_create_protein_table(self):
if self.checkBox_create_protein_table.isChecked():
- self.checkBox_infrence_protein_by_sample.setEnabled(True)
- self.comboBox_protein_ranking_method.setEnabled(True)
+ # self.checkBox_infrence_protein_by_sample.setEnabled(True)
+ # self.comboBox_protein_ranking_method.setEnabled(True)
self.comboBox_method_of_protein_inference.setEnabled(True)
else:
self.comboBox_method_of_protein_inference.setEnabled(False)
@@ -833,12 +853,12 @@ def change_event_checkBox_create_protein_table(self):
self.comboBox_protein_ranking_method.setEnabled(False)
def update_method_of_protein_inference(self):
- if self.comboBox_method_of_protein_inference.currentText() == "anti-razor":
+ if self.comboBox_method_of_protein_inference.currentText() in ["razor", "anti-razor"]:
# set checked
self.checkBox_infrence_protein_by_sample.setChecked(True)
self.checkBox_infrence_protein_by_sample.setEnabled(False)
self.comboBox_protein_ranking_method.setEnabled(False)
- else:
+ else: # method is ["rank"]
self.checkBox_infrence_protein_by_sample.setEnabled(True)
self.comboBox_protein_ranking_method.setEnabled(True)
self.checkBox_infrence_protein_by_sample.setChecked(False)
@@ -2471,7 +2491,8 @@ def set_multi_table(self, restore_taxafunc=False, saved_obj=None):
sum_protein_params = {
'method': self.comboBox_method_of_protein_inference.currentText(),
'by_sample': self.checkBox_infrence_protein_by_sample.isChecked(),
- 'rank_method' :self.comboBox_protein_ranking_method.currentText()
+ 'rank_method' :self.comboBox_protein_ranking_method.currentText(),
+ 'greedy_method': self.settings.value('protein_infer_greedy_mode', 'heap')
}
@@ -3396,7 +3417,7 @@ def plot_basic_list(self, plot_type='heatmap'):
if reply == QMessageBox.No:
return None
self.show_message(f'Plotting {plot_type}...')
- pic = BarPlot_js(self.tfa, theme=self.theme).plot_intensity_bar(df = df, width=width, height=height,
+ pic = BarPlot_js(self.tfa, theme=self.html_theme).plot_intensity_bar(df = df, width=width, height=height,
title= '', rename_taxa=rename_taxa,
show_legend=show_legend, font_size=font_size,
rename_sample=rename_sample, plot_mean = plot_mean,
@@ -3432,7 +3453,7 @@ def plot_basic_list(self, plot_type='heatmap'):
else:
title_new = ''
subtitle = ''
- pic = SankeyPlot(self.tfa, theme=self.theme).plot_intensity_sankey(df=df, width=width, height=height,
+ pic = SankeyPlot(self.tfa, theme=self.html_theme).plot_intensity_sankey(df=df, width=width, height=height,
title=title_new, subtitle=subtitle, font_size=font_size,
show_legend=self.checkBox_basic_bar_show_legend.isChecked())
self.save_and_show_js_plot(pic, title)
@@ -3717,7 +3738,7 @@ def plot_trends_interactive_line(self):
try:
- pic = TrendsPlot_js(self.tfa, theme=self.theme).plot_trends_js( df=df, width=width, height= height, title=title,
+ pic = TrendsPlot_js(self.tfa, theme=self.html_theme).plot_trends_js( df=df, width=width, height= height, title=title,
rename_taxa=rename_taxa, show_legend=show_legend,
add_group_name = plot_samples, font_size=font_size)
self.save_and_show_js_plot(pic, f'Cluster {cluster_num+1} of {table_name}')
@@ -3792,7 +3813,7 @@ def save_and_show_js_plot(self, pic, title, width=None, height=None):
pic.render(save_path)
self.logger.write_log(f'html saved: {save_path}', 'i')
- web = webDialog.WebDialog(save_path, None, theme=self.theme)
+ web = webDialog.WebDialog(save_path, None, theme=self.html_theme)
if title:
web.setWindowTitle(title)
@@ -4036,7 +4057,7 @@ def get_title_by_table_name(self, table_name):
return None
self.show_message('PCA is running, please wait...')
pic = PcaPlot_js(self.tfa,
- theme=self.theme
+ theme=self.html_theme
).plot_pca_pyecharts_3d(df=df, title_name=title_name, show_label = show_label,
rename_sample = rename_sample,
width=width, height=height, font_size=font_size, legend_col_num=legend_col_num)
@@ -4094,7 +4115,7 @@ def get_title_by_table_name(self, table_name):
else:
show_label = False
- pic = SunburstPlot(theme=self.theme).create_sunburst_chart(taxa_df= taxa_df, width=width, height=height,
+ pic = SunburstPlot(theme=self.html_theme).create_sunburst_chart(taxa_df= taxa_df, width=width, height=height,
title='Sunburst of Taxa', show_label=show_label,
label_font_size = font_size)
self.save_and_show_js_plot(pic, 'Sunburst of Taxa')
@@ -4106,7 +4127,7 @@ def get_title_by_table_name(self, table_name):
taxa_df = self.tfa.taxa_df[sample_list]
- pic = TreeMapPlot(theme=self.theme).create_treemap_chart(taxa_df= taxa_df, width=width, height=height,
+ pic = TreeMapPlot(theme=self.html_theme).create_treemap_chart(taxa_df= taxa_df, width=width, height=height,
show_sub_title = self.checkBox_pca_if_show_lable.isChecked(),
font_size = font_size)
self.save_and_show_js_plot(pic, 'Treemap of Taxa')
@@ -4120,7 +4141,7 @@ def get_title_by_table_name(self, table_name):
df = df[sample_list]
title = 'Sankey of Taxa' if table_name == 'Taxa' else 'Sankey of Taxa-Functions'
- pic = SankeyPlot(self.tfa, theme=self.theme).plot_intensity_sankey(df=df, width=width, height=height,
+ pic = SankeyPlot(self.tfa, theme=self.html_theme).plot_intensity_sankey(df=df, width=width, height=height,
font_size = font_size, title='', subtitle='')
self.save_and_show_js_plot(pic, title)
@@ -4789,7 +4810,7 @@ def plot_deseq2_volcano(self):
# VolcanoPlot().plot_volcano(df, padj = pvalue, log2fc = log2fc, title_name='2 groups', width=width, height=height)
try:
df = self.table_dict[table_name]
- pic = VolcanoPlot(theme=self.theme).plot_volcano_js(df, pvalue = pvalue, p_type = p_type,
+ pic = VolcanoPlot(theme=self.html_theme).plot_volcano_js(df, pvalue = pvalue, p_type = p_type,
log2fc_min = log2fc_min, log2fc_max=log2fc_max,
title_name=title_name, font_size = font_size,
width=width, height=height)
@@ -4842,7 +4863,7 @@ def plot_co_expr_network(self):
show_labels=show_labels,
rename_taxa=rename_taxa,
font_size=font_size,
- theme=self.theme,
+ theme=self.html_theme,
**self.tf_link_net_params_dict
).plot_co_expression_network(df_type= df_type, corr_method=corr_method,
corr_threshold=corr_threshold, sample_list=sample_list, width=width, height=height, focus_list=focus_list, plot_list_only=plot_list_only)
@@ -4889,7 +4910,7 @@ def deseq2_plot_sankey(self):
df = self.table_dict[table_name]
title_name = f'{group1} vs {group2} of {table_name.split("(")[1].split(")")[0]}'
- pic = SankeyPlot(self.tfa, theme=self.theme).plot_fc_sankey(df, width=width, height=height, pvalue=pvalue, p_type = p_type,
+ pic = SankeyPlot(self.tfa, theme=self.html_theme).plot_fc_sankey(df, width=width, height=height, pvalue=pvalue, p_type = p_type,
log2fc_min=log2fc_min, log2fc_max=log2fc_max, title =title_name, font_size=font_size)
self.save_and_show_js_plot(pic, f'Sankay plot {title_name}')
@@ -5075,7 +5096,7 @@ def plot_network(self):
show_labels=show_labels,
rename_taxa=rename_taxa,
font_size=font_size,
- theme=self.theme,
+ theme=self.html_theme,
**self.tf_link_net_params_dict
).plot_tflink_network(sample_list=sample_list, width=width, height=height, focus_list=focus_list,plot_list_only=plot_list_only)
self.save_and_show_js_plot(pic, 'taxa-func link Network')
@@ -5354,7 +5375,7 @@ def plot_tflink_bar(self):
params['show_all_labels'] = show_all_labels
self.show_message('Plotting bar plot, please wait...')
- pic = BarPlot_js(self.tfa, theme=self.theme).plot_intensity_bar(**params)
+ pic = BarPlot_js(self.tfa, theme=self.html_theme).plot_intensity_bar(**params)
self.save_and_show_js_plot(pic, 'Intensity Bar Plot')
diff --git a/utils/MetaX_GUI/MainWindow.ui b/utils/MetaX_GUI/MainWindow.ui
index 2377049..1323d1f 100644
--- a/utils/MetaX_GUI/MainWindow.ui
+++ b/utils/MetaX_GUI/MainWindow.ui
@@ -46,7 +46,7 @@
Qt::LeftToRight
- 6
+ 2
@@ -798,6 +798,11 @@
anti-razor
+ -
+
+ rank
+
+
-
@@ -1315,7 +1320,7 @@
-
- 1
+ 0
@@ -8026,7 +8031,7 @@
0
0
1059
- 21
+ 23