Skip to content

Commit

Permalink
- New: Added a function to plot the heatmap of the correlation of the…
Browse files Browse the repository at this point in the history
… taxa, functions, taxa-functions items.

- Fix: Fixed a bug of when plot the taxa-functions network.
- Change: Changed the sankey plot for intensity, split samples to different groups to show.
  • Loading branch information
byemaxx committed Jul 23, 2024
1 parent 989a99f commit a021d84
Show file tree
Hide file tree
Showing 11 changed files with 1,812 additions and 1,369 deletions.
14 changes: 14 additions & 0 deletions Docs/ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# Version: 1.109.1
## Date: 2024-07-23
### Changes:
- New: Added a function to plot the heatmap of the correlation of the taxa, functions, taxa-functions items.
- Fix: Fixed a bug of when plot the taxa-functions network.
- Change: Changed the sankey plot for intensity, split samples to different groups to show.


# Version: 1.109.0
## Date: 2024-07-22
### Changes:
- Change: Changed the layout of the main window to make the GUI more user-friendly and clear.


# Version: 1.108.7
## Date: 2024-07-14
### Changes:
Expand Down
110 changes: 74 additions & 36 deletions metax/gui/main_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,8 +431,8 @@ def __init__(self, MainWindow):
self.pushButton_deseq2_plot_sankey.clicked.connect(self.deseq2_plot_sankey)

# ### Co-Expression
self.pushButton_co_expr_plot.clicked.connect(self.plot_co_expr_network)
self.pushButton_co_expr_heatmap_plot.clicked.connect(self.plot_co_expr_heatmap)
self.pushButton_co_expr_plot.clicked.connect(lambda: self.plot_co_expr('network'))
self.pushButton_co_expr_heatmap_plot.clicked.connect(lambda: self.plot_co_expr('heatmap'))
self.comboBox_co_expr_table.currentIndexChanged.connect(self.update_co_expr_select_list)
self.pushButton_co_expr_add_to_list.clicked.connect(self.add_co_expr_to_list)
self.pushButton_co_expr_drop_item.clicked.connect(self.drop_co_expr_list)
Expand Down Expand Up @@ -1498,7 +1498,7 @@ def add_theme_to_combobox(self):
cmap_list = ['Auto'] + sorted(list(colormaps))


cmap_combox_list = ['comboBox_basic_hetatmap_theme', 'comboBox_tflink_cmap', 'comboBox_top_heatmap_cmap']
cmap_combox_list = ['comboBox_basic_corr_cmap','comboBox_basic_hetatmap_theme', 'comboBox_tflink_cmap', 'comboBox_top_heatmap_cmap', 'comboBox_corr_hetatmap_cmap']
for name in cmap_combox_list:
old_combobox = getattr(self, name)
new_combobox = CmapComboBox(old_combobox.parent())
Expand Down Expand Up @@ -3423,7 +3423,8 @@ def plot_basic_list(self, plot_type='heatmap'):
rename_sample = self.checkBox_basic_hetatmap_rename_sample_name.isChecked()
show_all_labels = (self.checkBox_basic_hetatmap_show_all_labels_x.isChecked(), self.checkBox_basic_hetatmap_show_all_labels_y.isChecked())
plot_mean = self.checkBox_basic_heatmap_plot_mean.isChecked()

sub_meta = self.comboBox_3dbar_sub_meta.currentText()

table_name = self.comboBox_basic_table.currentText()

if cmap == 'Auto':
Expand Down Expand Up @@ -3537,7 +3538,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 = self.comboBox_3dbar_sub_meta.currentText())
plot_mean = plot_mean, sub_meta = sub_meta)


elif plot_type == 'bar':
Expand Down Expand Up @@ -3566,14 +3567,17 @@ def plot_basic_list(self, plot_type='heatmap'):

elif plot_type == 'get_table':
self.show_message('Getting table...')
if plot_mean:
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)
elif sub_meta != 'None':
df, _ = self.tfa.BasicStats.get_combined_sub_meta_df(df=df, sub_meta=sub_meta, rename_sample=rename_sample, plot_mean=plot_mean)
else:
if rename_taxa:
df = self.tfa.rename_taxa(df)
if rename_sample:
df = self.tfa.rename_sample(df)

if rename_taxa:
df = self.tfa.rename_taxa(df)

self.show_table(df=df, title=title)

elif plot_type == 'sankey':
Expand All @@ -3587,12 +3591,13 @@ def plot_basic_list(self, plot_type='heatmap'):
self.show_message('Plotting Sankey...')
if self.checkBox_basic_heatmap_sankey_title.isChecked():
title_new = title
subtitle = sample_list
subtitle = str(sample_list)
else:
title_new = ''
subtitle = ''
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,
sub_meta=sub_meta, plot_mean=plot_mean,
show_legend=self.checkBox_basic_bar_show_legend.isChecked())
self.save_and_show_js_plot(pic, title)

Expand Down Expand Up @@ -4205,6 +4210,7 @@ def get_title_by_table_name(self, table_name):
elif method == 'corr':
cluster = self.checkBox_corr_cluster.isChecked()
show_all_labels = (self.checkBox_corr_show_all_labels_x.isChecked(), self.checkBox_corr_show_all_labels_y.isChecked())
cmap = self.comboBox_basic_corr_cmap.currentText()
# checek if the dataframe has at least 2 rows and 2 columns
if df.shape[0] < 2 or df.shape[1] < 2:
QMessageBox.warning(self.MainWindow, 'Warning', 'The number of rows or columns is less than 2, correlation cannot be plotted!')
Expand All @@ -4215,7 +4221,7 @@ def get_title_by_table_name(self, table_name):
self.show_message('Correlation is running, please wait...')
BasicPlot(self.tfa).plot_corr_sns(df=df, title_name=title_name, cluster= cluster,
width=width, height=height, font_size=font_size,
show_all_labels=show_all_labels, theme=theme,
show_all_labels=show_all_labels, theme=theme, cmap=cmap,
rename_sample = rename_sample, **self.heatmap_params_dict)

elif method == 'alpha_div':
Expand Down Expand Up @@ -4274,7 +4280,7 @@ def get_title_by_table_name(self, table_name):
title = 'Sankey of Taxa' if table_name == 'Taxa' else 'Sankey of Taxa-Functions'

pic = SankeyPlot(self.tfa, theme=self.html_theme).plot_intensity_sankey(df=df, width=width, height=height,
font_size = font_size, title='', subtitle='')
font_size = font_size, title='', subtitle='', sub_meta=sub_meta)
self.save_and_show_js_plot(pic, title)

elif method == 'num_bar':
Expand Down Expand Up @@ -4957,7 +4963,10 @@ def plot_deseq2_volcano(self):
QMessageBox.warning(self.MainWindow, 'Error', f'{error_message} \n\nPlease check your input!')
return None

def plot_co_expr_network(self):
def plot_co_expr(self, plot_type = 'network'):
'''
plot_type: network or heatmap
'''
df_type = self.comboBox_co_expr_table.currentText().lower()
corr_method = self.comboBox_co_expr_corr_method.currentText()
corr_threshold = self.doubleSpinBox_co_expr_corr_threshold.value()
Expand Down Expand Up @@ -4990,30 +4999,59 @@ def plot_co_expr_network(self):
return None


try:
self.show_message('Co-expression network is plotting...\n\n It may take a long time! Please wait...')
pic = NetworkPlot(self.tfa,
show_labels=show_labels,
rename_taxa=rename_taxa,
font_size=font_size,
theme=self.html_theme,
**self.tf_link_net_params_dict
).plot_co_expression_network(df_type= df_type, corr_method=corr_method,
corr_threshold=corr_threshold, sample_list=sample_list, width=width, height=height, focus_list=focus_list, plot_list_only=plot_list_only)
self.save_and_show_js_plot(pic, 'co-expression network')
except ValueError as e:
if 'sample_list should have at least 2' in str(e):
QMessageBox.warning(self.MainWindow, 'Error', "At least 2 samples are required!")
except Exception as e:
error_message = traceback.format_exc()
self.logger.write_log(f'plot_co_expr_network error: {error_message}', 'e')
self.logger.write_log(f'plot_co_expr_network: df_type: {df_type}, corr_method: {corr_method}, corr_threshold: {corr_threshold}, width: {width}, height: {height}, focus_list: {focus_list}', 'e')
QMessageBox.warning(self.MainWindow, 'Error', f'{error_message} \n\nPlease check your input!')
return None

def plot_co_expr_heatmap(self):
pass

if plot_type == 'heatmap':
self.show_message('Co-expression heatmap is plotting...\n\n It may take a long time! Please wait...')
try:
print(f'Calculate correlation with {corr_method} method...')
df = self.tfa.BasicStats.get_correlation(df_type = df_type, sample_list = sample_list, focus_list = focus_list, plot_list_only = plot_list_only, rename_taxa = rename_taxa, method=corr_method)
# save df to table_dict
self.update_table_dict(f'co-expression heatmap({df_type})', df)

show_all_labels = (
self.checkBox_corr_hetatmap_show_all_labels_x.isChecked(),
self.checkBox_corr_hetatmap_show_all_labels_y.isChecked(),
)
cmap = self.comboBox_corr_hetatmap_cmap.currentText()
BasicPlot(self.tfa).plot_items_corr_heatmap(df=df,
title_name=f'Co-expression heatmap of {df_type}',
cluster=True,
cmap=cmap,
width=width, height=height,
font_size=font_size,
show_all_labels=show_all_labels,
**self.heatmap_params_dict)

except Exception as e:
error_message = traceback.format_exc()
self.logger.write_log(f'plot_co_expr_heatmap error: {error_message}', 'e')
self.logger.write_log(f'plot_co_expr_heatmap: df_type: {df_type}, corr_method: {corr_method}, corr_threshold: {corr_threshold}, width: {width}, height: {height}, focus_list: {focus_list}', 'e')
QMessageBox.warning(self.MainWindow, 'Error', f'{error_message} \n\nPlease check your input!')
return None


elif plot_type == 'network':
try:
self.show_message('Co-expression network is plotting...\n\n It may take a long time! Please wait...')
pic = NetworkPlot(self.tfa,
show_labels=show_labels,
rename_taxa=rename_taxa,
font_size=font_size,
theme=self.html_theme,
**self.tf_link_net_params_dict
).plot_co_expression_network(df_type= df_type, corr_method=corr_method,
corr_threshold=corr_threshold, sample_list=sample_list, width=width, height=height, focus_list=focus_list, plot_list_only=plot_list_only)
self.save_and_show_js_plot(pic, 'co-expression network')
except ValueError as e:
if 'sample_list should have at least 2' in str(e):
QMessageBox.warning(self.MainWindow, 'Error', "At least 2 samples are required!")
except Exception as e:
error_message = traceback.format_exc()
self.logger.write_log(f'plot_co_expr_network error: {error_message}', 'e')
self.logger.write_log(f'plot_co_expr_network: df_type: {df_type}, corr_method: {corr_method}, corr_threshold: {corr_threshold}, width: {width}, height: {height}, focus_list: {focus_list}', 'e')
QMessageBox.warning(self.MainWindow, 'Error', f'{error_message} \n\nPlease check your input!')
return None
else:
raise ValueError(f'No such plot_type: {plot_type}')

#Sankey
def deseq2_plot_sankey(self):
Expand Down
Loading

0 comments on commit a021d84

Please sign in to comment.