From f77a0a217c6724b78dd145c1339c9d4218880bd0 Mon Sep 17 00:00:00 2001 From: mschwoerer <82171591+mschwoer@users.noreply.github.com> Date: Wed, 30 Oct 2024 13:12:32 +0100 Subject: [PATCH 1/8] refactor dim reduction analysis --- alphastats/gui/utils/analysis.py | 73 ++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/alphastats/gui/utils/analysis.py b/alphastats/gui/utils/analysis.py index 3ca10f6d..6a55251b 100644 --- a/alphastats/gui/utils/analysis.py +++ b/alphastats/gui/utils/analysis.py @@ -89,6 +89,79 @@ def show_widget(self): self._parameters["column"] = column +class DimensionReductionAnalysis(Analysis, ABC): + """Abstract class for dimension reduction analysis widgets.""" + + def show_widget(self): + """Gather parameters for dimension reduction analysis.""" + + group = st.selectbox( + "Color according to", + options=[None] + self._dataset.metadata.columns.to_list(), + ) + + circle = st.checkbox("circle") + + self._parameters.update({"circle": circle, "group": group}) + + +class PCAPlotAnalysis(DimensionReductionAnalysis): + """Widget for PCA Plot analysis.""" + + def do_analysis(self): + """Draw PCA Plot using the PCAPlot class.""" + + pca_plot = self._dataset.plot_pca( + group=self._parameters["group"], + circle=self._parameters["circle"], + ) + return pca_plot, None, self._parameters + + +class UMAPPlotAnalysis(DimensionReductionAnalysis): + """Widget for UMAP Plot analysis.""" + + def do_analysis(self): + """Draw PCA Plot using the PCAPlot class.""" + umap_plot = self._dataset.plot_umap( + group=self._parameters["group"], + circle=self._parameters["circle"], + ) + return umap_plot, None, self._parameters + + +class TSNEPlotAnalysis(DimensionReductionAnalysis): + """Widget for t-SNE Plot analysis.""" + + def show_widget(self): + """Show the widget and gather parameters.""" + super().show_widget() + + n_iter = st.select_slider( + "Maximum number of iterations for the optimization", + range(250, 2001), + value=1000, + ) + perplexity = st.select_slider("Perplexity", range(5, 51), value=30) + + self._parameters.update( + { + "n_iter": n_iter, + "perplexity": perplexity, + } + ) + + def do_analysis(self): + """Draw t-SNE Plot using the TSNEPlot class.""" + tsne_plot = self._dataset.plot_tsne( + group=self._parameters["group"], + circle=self._parameters["circle"], + perplexity=self._parameters["perplexity"], + n_iter=self._parameters["n_iter"], + ) + return tsne_plot, None, self._parameters + + class VolcanoPlotAnalysis(GroupCompareAnalysis): """Widget for Volcano Plot analysis.""" From 7c85c01e4f5b5ec621ce382aabf560f5abd53c04 Mon Sep 17 00:00:00 2001 From: mschwoerer <82171591+mschwoer@users.noreply.github.com> Date: Wed, 30 Oct 2024 13:14:12 +0100 Subject: [PATCH 2/8] add Plotting options class --- alphastats/gui/pages/04_Analysis.py | 19 +++++++++++--- alphastats/gui/utils/analysis.py | 18 +++++++++++++ alphastats/gui/utils/analysis_helper.py | 34 ++++++++++++++++--------- alphastats/gui/utils/options.py | 31 ---------------------- 4 files changed, 56 insertions(+), 46 deletions(-) diff --git a/alphastats/gui/pages/04_Analysis.py b/alphastats/gui/pages/04_Analysis.py index c303b45a..c8823eea 100644 --- a/alphastats/gui/pages/04_Analysis.py +++ b/alphastats/gui/pages/04_Analysis.py @@ -1,11 +1,15 @@ import streamlit as st +from alphastats.gui.utils.analysis import PlottingOptions from alphastats.gui.utils.analysis_helper import ( display_df, display_plot, do_analysis, ) -from alphastats.gui.utils.options import get_plotting_options, get_statistic_options +from alphastats.gui.utils.options import ( + get_plotting_options, + get_statistic_options, +) from alphastats.gui.utils.ui_helper import ( StateKeys, convert_df, @@ -44,16 +48,25 @@ c1, c2 = st.columns([0.33, 0.67]) with c1: + plotting_options = PlottingOptions.get_all_values() method = st.selectbox( "Analysis", options=[""] diff --git a/alphastats/gui/utils/analysis.py b/alphastats/gui/utils/analysis.py index ddf0a7de..b5130eb8 100644 --- a/alphastats/gui/utils/analysis.py +++ b/alphastats/gui/utils/analysis.py @@ -19,12 +19,12 @@ class PlottingOptions: VOLCANO_PLOT = "Volcano Plot" @classmethod - def get_all_values(cls): - """Get all values of the class.""" + def get_values(cls): + """Get all user-defined string values of the class.""" return [ value for key, value in cls.__dict__.items() - if not key.startswith("__") and not callable(value) + if not key.startswith("__") and isinstance(value, str) ] From 4cf41f846312bf2440fab6b392e1bc944b34212f Mon Sep 17 00:00:00 2001 From: mschwoerer <82171591+mschwoer@users.noreply.github.com> Date: Wed, 30 Oct 2024 13:35:32 +0100 Subject: [PATCH 5/8] fix TSNE --- alphastats/plots/DimensionalityReduction.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/alphastats/plots/DimensionalityReduction.py b/alphastats/plots/DimensionalityReduction.py index ae43750f..a701cad5 100644 --- a/alphastats/plots/DimensionalityReduction.py +++ b/alphastats/plots/DimensionalityReduction.py @@ -5,6 +5,7 @@ import plotly.express as px import plotly.graph_objects as go import sklearn +from sklearn.manifold._t_sne import TSNE from alphastats.DataSet_Preprocess import Preprocess from alphastats.keys import Cols @@ -119,7 +120,7 @@ def _pca(self): } def _tsne(self, **kwargs): - tsne = sklearn.manifold.TSNE(n_components=2, verbose=1, **kwargs) + tsne = TSNE(n_components=2, verbose=1, **kwargs) self.components = tsne.fit_transform(self.prepared_df) self.labels = { "0": "Dimension 1", From e37a87736ed4f30664de5af1cce51ef74734516b Mon Sep 17 00:00:00 2001 From: mschwoerer <82171591+mschwoer@users.noreply.github.com> Date: Wed, 30 Oct 2024 14:25:19 +0100 Subject: [PATCH 6/8] move method_dict --- alphastats/gui/utils/analysis_helper.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/alphastats/gui/utils/analysis_helper.py b/alphastats/gui/utils/analysis_helper.py index 4fad529a..d4361091 100644 --- a/alphastats/gui/utils/analysis_helper.py +++ b/alphastats/gui/utils/analysis_helper.py @@ -152,6 +152,8 @@ def do_analysis( return analysis.do_analysis() return None, None, {} + method_dict = options_dict.get(method) + # old, to be refactored logic: if method == "Differential Expression Analysis - T-test": parameters = helper_compare_two_groups() @@ -162,7 +164,6 @@ def do_analysis( parameters.update({"method": "wald"}) else: - method_dict = options_dict.get(method) parameters = st_general(method_dict=method_dict) submitted = st.button("Run analysis ..") From 1766107f145f237664d821cc0e69de5856f7f570 Mon Sep 17 00:00:00 2001 From: mschwoerer <82171591+mschwoer@users.noreply.github.com> Date: Wed, 30 Oct 2024 14:31:40 +0100 Subject: [PATCH 7/8] move method_dict --- alphastats/gui/utils/analysis_helper.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/alphastats/gui/utils/analysis_helper.py b/alphastats/gui/utils/analysis_helper.py index d4361091..97fffa8f 100644 --- a/alphastats/gui/utils/analysis_helper.py +++ b/alphastats/gui/utils/analysis_helper.py @@ -135,8 +135,6 @@ def do_analysis( Currently, analysis_object is only not-None for Volcano Plot. # TODO unify the API of all analysis methods """ - method_dict = options_dict.get(method) - options = { PlottingOptions.VOLCANO_PLOT: VolcanoPlotAnalysis, PlottingOptions.PCA_PLOT: PCAPlotAnalysis, From d57a90dd816b1f0541525772c042c4aa01d94265 Mon Sep 17 00:00:00 2001 From: mschwoerer <82171591+mschwoer@users.noreply.github.com> Date: Wed, 30 Oct 2024 14:50:44 +0100 Subject: [PATCH 8/8] fix frontend --- alphastats/gui/pages/04_Analysis.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/alphastats/gui/pages/04_Analysis.py b/alphastats/gui/pages/04_Analysis.py index 79ec0d50..1d64b928 100644 --- a/alphastats/gui/pages/04_Analysis.py +++ b/alphastats/gui/pages/04_Analysis.py @@ -64,11 +64,11 @@ ) if method in ( - plotting_options := list(get_plotting_options(st.session_state).keys()) + list((plot_options := get_plotting_options(st.session_state)).keys()) + plotting_options ): analysis_result, analysis_object, parameters = do_analysis( - method, options_dict=plotting_options + method, options_dict=plot_options ) show_plot = analysis_result is not None