diff --git a/Docs/ChangeLog.md b/Docs/ChangeLog.md index f43b4e7..cf38796 100644 --- a/Docs/ChangeLog.md +++ b/Docs/ChangeLog.md @@ -1,3 +1,10 @@ + +# Version: 1.119.7 +## Date: 2024-12-5 +### Changes: +- Change: Optimized the Data Overview section to make the layout more clear. +- Update README.md + # Version: 1.119.6 ## Date: 2024-12-5 ### Changes: diff --git a/Docs/MetaX_Cookbook.assets/otf_heatmap.png b/Docs/MetaX_Cookbook.assets/otf_heatmap.png new file mode 100644 index 0000000..e499ec2 Binary files /dev/null and b/Docs/MetaX_Cookbook.assets/otf_heatmap.png differ diff --git a/README.md b/README.md index 263bda4..2392313 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,11 @@ Show all functions of a taxon - tf_link_bar +**OTF Heatmap** +Show OTFS intensity in groups(samples), e.g., **Species-KO** OTF Heatmap + +otf_heatmap ## Download & Installation - **Desktop Version** (Recommended) diff --git a/metax/gui/main_gui.py b/metax/gui/main_gui.py index 46ca921..e3b5f22 100644 --- a/metax/gui/main_gui.py +++ b/metax/gui/main_gui.py @@ -1045,7 +1045,7 @@ def change_theme(self, theme, silent=False): padding: 5px; margin: 2px; height: 20px; - }} + }} ''' current_app = QtWidgets.QApplication.instance() @@ -4070,7 +4070,7 @@ def plot_trends_cluster(self): width=width, height=height, title=title , font_size=font_size, num_col=num_col) # create a dialog to show the figure - # plt_dialog = PltDialog(self.MainWindow, fig) + # plt_dialog = PltDialog(self.MainWindow, fig) #obsolete plt_size= (width*50, int(height*num_cluster*50/num_col) ) plt_dialog = ExportablePlotDialog(self.MainWindow,fig, plt_size) #set title @@ -4348,9 +4348,9 @@ def plot_taxa_stats(self): else: # BasicPlot(self.tfa).plot_taxa_stats() theme = self.comboBox_data_overiew_theme.currentText() - pic = BasicPlot(self.tfa).plot_taxa_stats_pie(theme=theme) + pic = BasicPlot(self.tfa).plot_taxa_stats_pie(theme=theme, font_size=8, width=5, height=4) # Add the new MatplotlibWidget - self.mat_widget_plot_peptide_num = MatplotlibWidget(pic) + self.mat_widget_plot_peptide_num = MatplotlibWidget(pic, width = 5, height = 4) self.verticalLayout_overview_plot.addWidget(self.mat_widget_plot_peptide_num) def plot_taxa_stats_new_window(self): @@ -4369,9 +4369,10 @@ def plot_taxa_number(self): QMessageBox.warning(self.MainWindow, 'Warning', 'Please run OTF Analyzer first!') else: theme = self.comboBox_data_overiew_theme.currentText() - pic = BasicPlot(self.tfa).plot_taxa_number(theme = theme).get_figure() + pic = BasicPlot(self.tfa).plot_taxa_number(theme = theme, font_size = 8, width = 5,height = 4 + ).get_figure() - self.mat_widget_plot_taxa_num = MatplotlibWidget(pic) + self.mat_widget_plot_taxa_num = MatplotlibWidget(pic, width = 5, height = 4) self.verticalLayout_overview_plot.addWidget(self.mat_widget_plot_taxa_num) def plot_taxa_number_new_window(self): @@ -4399,9 +4400,9 @@ def plot_peptide_num_in_func(self): self.show_message('Plotting peptide number in function...') BasicPlot(self.tfa).plot_prop_stats(func_name, theme=theme, res_type='show', font_size = font_size) else: - pic = BasicPlot(self.tfa).plot_prop_stats(func_name, theme=theme) + pic = BasicPlot(self.tfa).plot_prop_stats(func_name, theme=theme, font_size = 8, width=5, height=4) - self.mat_widget_plot_peptide_num_in_func = MatplotlibWidget(pic.get_figure()) + self.mat_widget_plot_peptide_num_in_func = MatplotlibWidget(pic.get_figure(), width = 5, height = 4) self.verticalLayout_overview_func.addWidget(self.mat_widget_plot_peptide_num_in_func) diff --git a/metax/gui/metax_gui/main_window.ui b/metax/gui/metax_gui/main_window.ui index 100fcdc..32aac38 100644 --- a/metax/gui/metax_gui/main_window.ui +++ b/metax/gui/metax_gui/main_window.ui @@ -46,7 +46,7 @@ Qt::LeftToRight - 3 + 1 false @@ -186,7 +186,7 @@ - Operational Taxa-Functions (OTF) Table (head 200) + Operational Taxon-Function (OTF) Table (head 200) @@ -205,6 +205,9 @@ 0 + + true + @@ -215,6 +218,15 @@ 0 + + true + + + true + + + false + @@ -246,7 +258,7 @@ 0 0 462 - 531 + 527 @@ -3248,8 +3260,8 @@ 0 0 - 885 - 170 + 665 + 157 @@ -6810,7 +6822,7 @@ 0 0 885 - 170 + 168 @@ -7664,8 +7676,8 @@ 0 0 - 885 - 123 + 620 + 65 @@ -9600,7 +9612,7 @@ 0 0 885 - 158 + 155 @@ -10869,7 +10881,7 @@ 0 0 991 - 21 + 23 diff --git a/metax/gui/metax_gui/matplotlib_figure_canvas.py b/metax/gui/metax_gui/matplotlib_figure_canvas.py index d9bc04d..84ead4e 100644 --- a/metax/gui/metax_gui/matplotlib_figure_canvas.py +++ b/metax/gui/metax_gui/matplotlib_figure_canvas.py @@ -3,14 +3,42 @@ from matplotlib.figure import Figure class MatplotlibWidget(QWidget): - def __init__(self, figure=None, parent=None): + def __init__(self, figure=None, parent=None, width=6, height=4, dpi=100): + """ + A QWidget that embeds a Matplotlib figure with fixed size to prevent deformation. + + :param figure: The Matplotlib Figure object. If None, a new Figure is created. + :param parent: The parent QWidget. + :param width: Width of the figure in inches. + :param height: Height of the figure in inches. + :param dpi: Dots per inch (resolution) of the figure. + """ super(MatplotlibWidget, self).__init__(parent) - self.figure = figure if figure else Figure() + # Create or use the provided figure + self.figure = figure if figure else Figure(figsize=(width, height), dpi=dpi) self.figure.tight_layout() + # Create the canvas for rendering the figure self.canvas = FigureCanvas(self.figure) self.canvas.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) + + # Set fixed size for the canvas + self.canvas.setFixedSize(width * dpi, height * dpi) + # Create and set layout self.layout = QHBoxLayout(self) - self.layout.addWidget(self.canvas) \ No newline at end of file + self.layout.addWidget(self.canvas) + + def set_size(self, width, height, dpi=None): + """ + Update the size of the Matplotlib figure and canvas. + + :param width: New width in inches. + :param height: New height in inches. + :param dpi: Optional new DPI. If not provided, the current DPI is used. + """ + dpi = dpi if dpi else self.figure.get_dpi() + self.figure.set_size_inches(width, height, forward=True) + self.canvas.setFixedSize(width * dpi, height * dpi) + self.canvas.draw() diff --git a/metax/gui/metax_gui/ui_main_window.py b/metax/gui/metax_gui/ui_main_window.py index c770287..c91043d 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\Qing\OneDrive - University of Ottawa\code\TaxaFunc\MetaX\metax\gui\metax_gui\main_window.ui' +# Form implementation generated from reading ui file 'c:\Users\max\OneDrive - University of Ottawa\code\TaxaFunc\MetaX\metax\gui\metax_gui\main_window.ui' # # Created by: PyQt5 UI code generator 5.15.9 # @@ -133,6 +133,8 @@ def setupUi(self, metaX_main): sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.tableWidget_taxa_func_view.sizePolicy().hasHeightForWidth()) self.tableWidget_taxa_func_view.setSizePolicy(sizePolicy) + self.tableWidget_taxa_func_view.setShowGrid(True) + self.tableWidget_taxa_func_view.setWordWrap(False) self.tableWidget_taxa_func_view.setObjectName("tableWidget_taxa_func_view") self.tableWidget_taxa_func_view.setColumnCount(0) self.tableWidget_taxa_func_view.setRowCount(0) @@ -147,7 +149,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, 462, 531)) + self.page_2.setGeometry(QtCore.QRect(0, 0, 462, 527)) self.page_2.setObjectName("page_2") self.gridLayout_27 = QtWidgets.QGridLayout(self.page_2) self.gridLayout_27.setObjectName("gridLayout_27") @@ -1652,7 +1654,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, 885, 170)) + self.scrollAreaWidgetContents_2.setGeometry(QtCore.QRect(0, 0, 665, 157)) self.scrollAreaWidgetContents_2.setObjectName("scrollAreaWidgetContents_2") self.gridLayout_50 = QtWidgets.QGridLayout(self.scrollAreaWidgetContents_2) self.gridLayout_50.setObjectName("gridLayout_50") @@ -3524,7 +3526,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, 885, 170)) + self.scrollAreaWidgetContents_5.setGeometry(QtCore.QRect(0, 0, 885, 168)) self.scrollAreaWidgetContents_5.setObjectName("scrollAreaWidgetContents_5") self.gridLayout_49 = QtWidgets.QGridLayout(self.scrollAreaWidgetContents_5) self.gridLayout_49.setObjectName("gridLayout_49") @@ -3986,7 +3988,7 @@ 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, 885, 123)) + self.scrollAreaWidgetContents_6.setGeometry(QtCore.QRect(0, 0, 620, 65)) self.scrollAreaWidgetContents_6.setObjectName("scrollAreaWidgetContents_6") self.gridLayout_57 = QtWidgets.QGridLayout(self.scrollAreaWidgetContents_6) self.gridLayout_57.setObjectName("gridLayout_57") @@ -5029,7 +5031,7 @@ def setupUi(self, metaX_main): self.scrollArea_7.setWidgetResizable(True) self.scrollArea_7.setObjectName("scrollArea_7") self.scrollAreaWidgetContents_8 = QtWidgets.QWidget() - self.scrollAreaWidgetContents_8.setGeometry(QtCore.QRect(0, 0, 885, 158)) + self.scrollAreaWidgetContents_8.setGeometry(QtCore.QRect(0, 0, 885, 155)) self.scrollAreaWidgetContents_8.setObjectName("scrollAreaWidgetContents_8") self.gridLayout_66 = QtWidgets.QGridLayout(self.scrollAreaWidgetContents_8) self.gridLayout_66.setObjectName("gridLayout_66") @@ -5683,7 +5685,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, 991, 21)) + self.menuBar.setGeometry(QtCore.QRect(0, 0, 991, 23)) self.menuBar.setObjectName("menuBar") self.menuTools = QtWidgets.QMenu(self.menuBar) self.menuTools.setObjectName("menuTools") @@ -5749,7 +5751,7 @@ def setupUi(self, metaX_main): self.retranslateUi(metaX_main) self.stackedWidget.setCurrentIndex(0) - self.tabWidget_TaxaFuncAnalyzer.setCurrentIndex(3) + self.tabWidget_TaxaFuncAnalyzer.setCurrentIndex(1) self.toolBox_2.setCurrentIndex(0) self.tabWidget_4.setCurrentIndex(0) self.tabWidget_3.setCurrentIndex(3) @@ -5802,8 +5804,10 @@ def retranslateUi(self, metaX_main): self.pushButton_load_example_for_analyzer.setText(_translate("metaX_main", "Load Example Data")) self.label_46.setText(_translate("metaX_main", "Operational Taxa-Functions (OTF) Analyzer")) self.tabWidget_TaxaFuncAnalyzer.setTabText(self.tabWidget_TaxaFuncAnalyzer.indexOf(self.tab), _translate("metaX_main", "Data Import")) - self.label_26.setText(_translate("metaX_main", "Operational Taxa-Functions (OTF) Table (head 200)")) + self.label_26.setText(_translate("metaX_main", "Operational Taxon-Function (OTF) Table (head 200)")) self.label_25.setText(_translate("metaX_main", "Meta Table")) + self.tableWidget_meta_view.setSortingEnabled(True) + self.tableWidget_taxa_func_view.setSortingEnabled(True) self.pushButton_overview_tax_plot_new_window.setText(_translate("metaX_main", "Plot taxa stats in new window")) self.pushButton_overview_peptide_plot_new_window.setText(_translate("metaX_main", "Plot peptide stats in new window")) self.label_154.setText(_translate("metaX_main", "Theme")) diff --git a/metax/utils/version.py b/metax/utils/version.py index b6393cc..eb7770b 100644 --- a/metax/utils/version.py +++ b/metax/utils/version.py @@ -1,2 +1,2 @@ -__version__ = '1.119.6' +__version__ = '1.119.7' API_version = '4' \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 9c53d4f..779741d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "MetaXTools" -version = "1.119.6" +version = "1.119.7" description = "MetaXTools is a novel tool for linking peptide sequences with taxonomic and functional information in Metaproteomics." readme = "README_PyPi.md" license = { text = "NorthOmics" }