Repository: siheming/mspypeline (language: python)

Issue:
Pauline
bumped version


Discussion / hints:

Fix patch:
diff --git a/.gitignore b/.gitignore
index 0b15834..824bcb0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,8 @@ test/mock_data/
 doc/build/*
 .coverage
 htmlcov/
+doc/source/_static
+doc/source/savefig
 
 *.ipynb
 *.df
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..d6646f8
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "mspypeline_public_dataset"]
+	path = mspypeline_public_dataset
+	url = https://github.com/siheming/mspypeline_public_dataset.git
diff --git a/doc/source/adjustable_options_config.rst b/doc/source/adjustable_options_config.rst
new file mode 100644
index 0000000..e438683
--- /dev/null
+++ b/doc/source/adjustable_options_config.rst
@@ -0,0 +1,5 @@
+Adjustable Options Configs
+===========================
+
+.. include:: ../../mspypeline/config/ms_analysis_adjustable_options.yml
+   :literal:
diff --git a/doc/source/analysis_options.rst b/doc/source/analysis_options.rst
new file mode 100644
index 0000000..82231a1
--- /dev/null
+++ b/doc/source/analysis_options.rst
@@ -0,0 +1,79 @@
+.. _Plot-Options:
+
+Analysis options
+=================
+
+Data Analysis
+~~~~~~~~~~~~~
+| The ``mspypeline`` was developed to consolidate the proteomics data analysis workflow while providing both simplicity
+  and flexibility.
+| The :ref:`usage of the GUI <gui-quickstart>` provides the opportunity to explore and visualize data straight forward,
+  without interaction of the code. The GUI offers the majority of data analysis options currently available in the
+  ``mspypeline``.
+| Additional plots and more advanced analysis may be performed by specifying optional arguments in the
+  :ref:`configuration <default-yaml>` file or by accessing the package as a :ref:`python module <python-quickstart>`.
+
+
+Plots
+*****
+
+The GUI allows for the following plots:
+
+**Normalization plots:**
+
+* Normalization overview: :meth:`~mspypeline.BasePlotter.plot_normalization_overview`
+* Heatmap overview: :meth:`~mspypeline.BasePlotter.plot_heatmap_overview_all_normalizers`
+
+**Outlier detection and comparison plots:**
+
+* Detection counts: :meth:`~mspypeline.BasePlotter.plot_detection_counts`
+* Number of detected proteins :meth:`~mspypeline.BasePlotter.plot_detected_proteins_per_replicate`
+* Venn diagrams: :meth:`~mspypeline.BasePlotter.plot_venn_results`
+* Group diagrams: :meth:`~mspypeline.BasePlotter.plot_venn_groups`
+* PCA overview: :meth:`~mspypeline.BasePlotter.plot_pca_overview`
+* Intensity histogram: :meth:`~mspypeline.BasePlotter.plot_intensity_histograms`
+* Relative std: :meth:`~mspypeline.BasePlotter.plot_relative_std`
+* Scatter replicates: :meth:`~mspypeline.BasePlotter.plot_scatter_replicates`
+* Experiment comparison: :meth:`~mspypeline.BasePlotter.plot_experiment_comparison`
+* Rank: :meth:`~mspypeline.BasePlotter.plot_rank`
+
+**Statistical inference plots:**
+
+* Pathway analysis: :meth:`~mspypeline.BasePlotter.plot_pathway_analysis`
+* Go analysis: :meth:`~mspypeline.BasePlotter.plot_go_analysis`
+* Volcano plot (R): :meth:`~mspypeline.BasePlotter.plot_r_volcano`
+
+**Additionally via python:**
+
+* :meth:`~mspypeline.BasePlotter.plot_kde`
+* :meth:`~mspypeline.BasePlotter.plot_boxplot`
+* :meth:`~mspypeline.BasePlotter.plot_n_proteins_vs_quantile`
+* :meth:`~mspypeline.BasePlotter.plot_intensity_heatmap`
+
+
+
+.. _plotters:
+
+Plotters
+~~~~~~~~~
+To perform data analysis and visualisation the Plotters from the MSPlots module are used. The MSPypeline currently
+contains two Plotters, the ``mspypeline.BasePlotter`` and the ``mspypeline.MaxQuantPlotter``.
+
+Base Plotter
+*************
+The BasePlotter provides all plots listed above. No quality control report is provided.
+
+MaxQuant Plotter
+*****************
+The MaxQuant Plotter is a child class of the Base Plotter and inherits all functionality and plotting options listed
+above. Additionally, the MaxQuant Plotter provides a quality control report based on supplementary MaxQuant data.
+
+Quality Control Report
+***********************
+| A quality control report for the output of MaxQuant. See :meth:`~mspypeline.MaxQuantPlotter.create_report`
+  for a description of the output.
+| This quality control report is specifically designed to process supplementary MaxQuant files available to generate a
+  multi-page pdf document. Here, the quality of the raw data can be investigated, for instance, the influence of
+  experimental parameters such as protein digestion, technical information like retention time and length of individual
+  samples as well as the corresponding chromatograms or the number of peptides measured and sequenced and the proportion
+  of contamination of protein intensities.
diff --git a/doc/source/api_reference/index.rst b/doc/source/api_reference/index.rst
index 7b98d75..8d3c7fd 100644
--- a/doc/source/api_reference/index.rst
+++ b/doc/source/api_reference/index.rst
@@ -11,9 +11,9 @@ Some of the documentation might be incomplete, but all important features are do
    :caption: Contents
 
    mspypeline
-   mspplots
    mspinitializer
    file_reader
+   mspplots
    modules
    plotting_backend
    helpers
diff --git a/doc/source/api_reference/mspypeline.rst b/doc/source/api_reference/mspypeline.rst
index 13f4fcb..0547bd6 100644
--- a/doc/source/api_reference/mspypeline.rst
+++ b/doc/source/api_reference/mspypeline.rst
@@ -6,15 +6,15 @@ import with:
 
 .. code-block:: python
 
-  from mspypeline import MSPGUI, MSPParser, UIHandler
+  from mspypeline import MSPParser, UIHandler, MSPGUI
 
 
 
-.. autoclass:: MSPGUI
-   :members:
-
 .. autoclass:: MSPParser
    :members:
 
 .. autoclass:: UIHandler
    :members:
+
+.. autoclass:: MSPGUI
+   :members:
\ No newline at end of file
diff --git a/doc/source/conf.py b/doc/source/conf.py
index cbab8ff..4baad3a 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -12,6 +12,8 @@
 #
 import os
 import sys
+from sphinx.ext import autodoc
+
 sys.path.insert(0, os.path.abspath("./_ext"))  # for custom extensions
 sys.path.insert(0, os.path.abspath("../.."))  # to find the package
 
@@ -58,10 +60,36 @@
 
 # autodoc
 autodoc_typehints = "description"
-autoclass_content = "init"
+autoclass_content = "class"
 
 
 # napoleon options
 napoleon_google_docstring = False
-napoleon_include_init_with_doc = False
+napoleon_include_init_with_doc = True
+
+# create documentor for description only
+# from https://stackoverflow.com/questions/7825263/including-docstring-in-sphinx-documentation
+
+
+class DescriptionOnlyDocumenter(autodoc.MethodDocumenter):
+    objtype = "descriptiononly"
+    priority = 0
+
+    # do not indent the content
+    content_indent = ""
+
+    def add_directive_header(self, sig):
+        pass
+
+    def get_doc(self, **kwargs):
+        res = super(DescriptionOnlyDocumenter, self).get_doc(**kwargs)
+        assert len(res) == 1
+        try:
+            res = [res[0][:res[0].index("Parameters")]]
+        except ValueError:
+            pass
+        return res
+
 
+def setup(app):
+    app.add_autodocumenter(DescriptionOnlyDocumenter)
diff --git a/doc/source/default_config.rst b/doc/source/default_config.rst
index 54c2f96..76ba71b 100644
--- a/doc/source/default_config.rst
+++ b/doc/source/default_config.rst
@@ -1,5 +1,5 @@
-Defaults
-========
+Default Configs
+===============
 
 .. include:: ../../mspypeline/config/ms_analysis_default.yml
    :literal:
diff --git a/doc/source/file_readers.rst b/doc/source/file_readers.rst
index ab4d4ef..a7bce87 100644
--- a/doc/source/file_readers.rst
+++ b/doc/source/file_readers.rst
@@ -2,21 +2,26 @@
 
 File readers
 ============
-File readers are required to translate the format of each specific file into an internal format.
+File readers are required to translate the format of each specific file into an internal format. File readers scan
+available data and create a data dictionary with keys to the data. Data stored on system hardware, is thus only loaded
+on demand.
 
 
-Max Quant Reader
+MaxQuant Reader
 ~~~~~~~~~~~~~~~~
+The MQReader preprocesses data from MaxQuant files into the internal data format to provide the correct input for the
+plotters.
+Minimum requirement to start and work with the MQReader:
 
-Minimum requirements: proteinGroups.txt file.
+* proteinGroups.txt file.
 
 .. note::
-    Currently tested with Max Quant version: 1.5+
+    Currently tested with MaxQuant version: 1.5+
 .. warning::
     All files to be analyzed need to be in a directory called txt
 
-The Report will use these files (if available):
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+The Quality Report will use these files (if available):
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 * proteinGroups.txt
 * peptides.txt
@@ -26,7 +31,7 @@ The Report will use these files (if available):
 * msmsScans.txt
 * evidence.txt
 
-If files are missing some plots will not be created or might be empty.
+If files are missing some plots of the :ref:`quality control report <plotters>` will not be created or might be empty.
 
 The Plots will use these files:
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/doc/source/gallery.rst b/doc/source/gallery.rst
new file mode 100644
index 0000000..74ae6c3
--- /dev/null
+++ b/doc/source/gallery.rst
@@ -0,0 +1,390 @@
+.. currentmodule:: mspypeline
+
+.. _gallery:
+
+Gallery
+========
+
+In the following, each plot that can be created with the ``mspypeline`` will be shown and explained giving a minimal
+code example to create this plot when using the package as a :ref:`python module <python-quickstart>`.
+
+Plotter creation
+^^^^^^^^^^^^^^^^^
+First, a plotter object has to be created too make the plots. Here, the :class:`~MaxQuantPlotter` is build from
+the :class:`~MSPInitializer` class which creates and reads in the :ref:`configuration file <settings>` and initiates the
+:class:`~MQReader` that loads the exemplary data set provided.
+
+.. ipython:: python
+
+    import pandas as pd
+    import os
+    from mspypeline import load_example_dataset, MaxQuantPlotter
+    # load the data that is provided in a submodule
+    init = load_example_dataset(configs={
+        "pathways": ["BIOCARTA_EGF_PATHWAY.txt", "HALLMARK_IL2_STAT5_SIGNALING.txt"],
+        "go_terms": ["GO_POSITIVE_REGULATION_OF_CYTOKINE_PRODUCTION.txt", "GO_INFLAMMATORY_RESPONSE.txt"]
+        })
+    plotter = MaxQuantPlotter.from_MSPInitializer(init)
+
+    # create a second plotter without collapsed technical replicates
+    init = load_example_dataset(configs={"has_techrep": False, "pathways":[]})
+    plotter_with_tech_reps = MaxQuantPlotter.from_MSPInitializer(init)
+
+define some helper functions
+
+.. ipython:: python
+
+    def select_fig(plts, idx):
+        # sets active figure which can then be saved by the @savefig decorator
+        plt.figure(plts[idx][0].number)
+
+
+MaxQuant Report
+^^^^^^^^^^^^^^^^^^^^^^^
+Created using: :meth:`~mspypeline.MaxQuantPlotter.create_report`
+
+    | The MaxQuant report was built with the intention to offer a broad insight into the different sources of information
+      from a MaxQuant output. Besides the protein intensities (from the *proteinGroups.txt* file) which are the only source
+      of data for all other parts of the analysis with the :ref:`MaxQuant Plotter <plotters>`, further information
+      about experimental and technical parameters of the experiment are taken into account.
+    | The MaxQuant report can function as quality control of the data and will output a multi-page pdf document composed of
+      a variety of information and graphics.
+    | Make sure that :ref:`all MaxQuant files <file-readers>` are provided, which are used to create the report.
+
+.. ipython:: python
+
+    #plotter.create_report("./source/_static");
+    print("skipping report")
+
+The resulting `MaxQuant Report <./_static/MaxQuantReport.pdf>`_.
+
+
+Normalization Plots
+^^^^^^^^^^^^^^^^^^^^
+
+The helper function :meth:`~mspypeline.BasePlotter.plot_all_normalizer_overview` is used to generate the same plot
+multiple times with different normalizations methods of the base data.
+
+.. _norm-overview:
+
+Normalization overview
+***********************
+Created using: :meth:`~mspypeline.BasePlotter.plot_normalization_overview_all_normalizers` by calling
+:meth:`~mspypeline.BasePlotter.plot_normalization_overview`
+
+.. autodescriptiononly:: mspypeline.BasePlotter.plot_normalization_overview
+
+.. ipython:: python
+
+    #plotter.plot_normalization_overview_all_normalizers("raw_log2", 0, save_path="./source/_static");
+    print("skipping norm overview")
+
+View `this normalization overview example <./_static/normalization_overview_all_normalizers_raw_log2.pdf>`_.
+
+.. _heatmap-overview:
+
+Heatmap overview
+******************
+Created using: :meth:`~mspypeline.BasePlotter.plot_heatmap_overview_all_normalizers` by calling
+:meth:`~mspypeline.BasePlotter.plot_intensity_heatmap`.
+
+.. autodescriptiononly:: mspypeline.BasePlotter.plot_intensity_heatmap
+
+.. ipython:: python
+
+    #plotter.plot_heatmap_overview_all_normalizers("raw_log2", 0, save_path="./source/_static");
+    print("skipping heatmap overview")
+
+View `this heatmap overview example <./_static/heatmap_overview_all_normalizers_raw_log2.pdf>`_.
+
+
+Outlier detection and comparison plots
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Detection counts
+*****************
+Created using: :meth:`~mspypeline.BasePlotter.plot_detection_counts`
+
+.. autodescriptiononly:: mspypeline.BasePlotter.plot_detection_counts
+
+.. ipython:: python
+
+    @savefig detection_counts.png width=400 align=center
+    plotter.plot_detection_counts("lfq_log2", 0, save_path=None);
+
+
+Number of detected proteins
+****************************
+Created using: :meth:`~mspypeline.BasePlotter.plot_detected_proteins_per_replicate`
+
+.. autodescriptiononly:: mspypeline.BasePlotter.plot_detected_proteins_per_replicate
+
+
+    | Depending on whether :ref:`technical replicates <tech-reps>` should be recognized/averaged (top graph) or not
+      (bottom graph) the data and resulting plot will have different outcomes. The number of detected proteins in total
+      and per sample changes as 0 values are handled as missing values ("nan") and neglected when calculating the mean of
+      samples.
+
+.. ipython:: python
+
+    @savefig detected_proteins.png width=600 align=center
+    plotter.plot_detected_proteins_per_replicate("lfq_log2", 1, save_path=None);
+
+    @savefig detected_proteins_tech_rep.png width=600 align=center
+    plotter_with_tech_reps.plot_detected_proteins_per_replicate("lfq_log2", 1, save_path=None);
+
+
+Venn diagrams
+**************
+Created using: :meth:`~mspypeline.BasePlotter.plot_venn_results`
+
+.. autodescriptiononly:: mspypeline.BasePlotter.plot_venn_results
+
+.. ipython:: python
+
+    plots = plotter.plot_venn_results("lfq_log2", 1, close_plots=None, save_path=None)
+
+    @savefig venn_plot1.png width=600 align=center
+    select_fig(plots, 0);
+
+    @savefig venn_plot2.png width=450 align=center
+    select_fig(plots, 1);
+
+
+Group diagrams
+***************
+Created using: :meth:`~mspypeline.BasePlotter.plot_venn_groups`
+
+.. autodescriptiononly:: mspypeline.BasePlotter.plot_venn_groups
+
+.. ipython:: python
+
+    plotter.plot_venn_groups("lfq_log2", 0, close_plots=None, save_path="./source/_static", fig_format=".png");
+
+.. image:: _static/plots/venn_replicate_group_level_0_lfq_log2_level_0.png
+    :width: 440
+    :height: 400
+    :align: left
+
+.. image:: _static/plots/venn_bar_group_level_0_lfq_log2_level_0.png
+    :width: 200
+    :height: 400
+    :align: right
+
+
+PCA overview
+*************
+Created using: :meth:`~mspypeline.BasePlotter.plot_pca_overview`
+
+.. autodescriptiononly:: mspypeline.BasePlotter.plot_pca_overview
+
+.. ipython:: python
+
+    plotter.plot_pca_overview("lfq_log2", 1, save_path="./source/_static", fig_format=".png");
+
+.. image:: _static/pca_overview_lfq_log2_level_1.png
+    :width: 550
+    :align: center
+
+
+Intensity histogram
+********************
+Created using: :meth:`~mspypeline.BasePlotter.plot_intensity_histograms`
+
+.. autodescriptiononly:: mspypeline.BasePlotter.plot_intensity_histograms
+
+.. ipython:: python
+
+    @savefig intensity_hist.png width=600 align=center
+    plotter.plot_intensity_histograms("lfq_log2", 1, save_path=None);
+
+
+Relative std
+*************
+Created using: :meth:`~mspypeline.BasePlotter.plot_relative_std`
+
+.. autodescriptiononly:: mspypeline.BasePlotter.plot_relative_std
+
+.. ipython:: python
+
+    @savefig relative_std.png width=500 align=center
+    plotter.plot_relative_std("lfq_log2", 0, save_path=None);
+
+
+Scatter replicates
+*******************
+Created using: :meth:`~mspypeline.BasePlotter.plot_scatter_replicates`
+
+.. autodescriptiononly:: mspypeline.BasePlotter.plot_scatter_replicates
+
+.. ipython:: python
+
+    plotter.plot_scatter_replicates("lfq_log2", 1, save_path="./source/_static", fig_format=".png");
+
+.. image:: _static/scatter_H838_unst_lfq_log2_level_1.png
+    :width: 700
+    :align: center
+
+
+Experiment comparison
+**********************
+Created using: :meth:`~mspypeline.BasePlotter.plot_experiment_comparison`
+
+.. autodescriptiononly:: mspypeline.BasePlotter.plot_experiment_comparison
+
+.. ipython:: python
+
+    plotter.plot_experiment_comparison("lfq_log2", 0, save_path="./source/_static", fig_format=".png");
+
+.. image:: _static/scatter_comparison_H1975_vs_H838_lfq_log2_level_0.png
+    :width: 650
+    :align: center
+
+
+Rank
+*****
+Created using: :meth:`~mspypeline.BasePlotter.plot_rank`
+
+.. autodescriptiononly:: mspypeline.BasePlotter.plot_rank
+
+.. ipython:: python
+
+    plotter.plot_rank("lfq_log2", 0, save_path="./source/_static", fig_format=".png");
+
+.. image:: _static/rank_H1975_lfq_log2_level_0.png
+    :width: 700
+    :align: center
+
+
+Statistical inference plots
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Pathway analysis
+*****************
+Created using: :meth:`~mspypeline.BasePlotter.plot_pathway_analysis`
+
+.. autodescriptiononly:: mspypeline.BasePlotter.plot_pathway_analysis
+
+| Shown below are two pathway analysis figures, both plotting the protein intensities of the
+  :ref:`Biocarta EGF pathway <pathway-proteins>` but calculated for different analysis levels. Here, the choice of the
+  :ref:`analysis level <analysis-design>` or depth determines which samples are considered a *"group"*.
+| In the upper figure where the analysis was performed on the lowest level (level 0) which only consists of two groups
+  (H1975 & H838), all samples belonging to any one of them are grouped together.
+| In the lower figure, where the analysis was performed on then next higher level (level 1) the two groups of level 0
+  are further subdivided into a total of four different groups to which (only) 3 samples are assigned.
+| Statistical analysis are always performed between two *"groups"* of samples and require a minimum of 3 samples to
+  indicate significances.
+
+.. ipython:: python
+
+    plots_level0 = plotter.plot_pathway_analysis("lfq_log2", 0, close_plots=None, save_path=None)
+    plots_level1 = plotter.plot_pathway_analysis("lfq_log2", 1, close_plots=None, save_path=None)
+
+    @savefig pathway_analysis_level0.png width=700 align=center
+    select_fig(plots_level0, 0);
+
+    @savefig pathway_analysis_level1.png width=700 align=center
+    select_fig(plots_level1, 0);
+
+
+Go analysis
+************
+Created using: :meth:`~mspypeline.BasePlotter.plot_go_analysis`
+
+.. autodescriptiononly:: mspypeline.BasePlotter.plot_go_analysis
+
+.. ipython:: python
+
+    @savefig go_analysis.png width=700 align=left
+    plotter.plot_go_analysis("lfq_log2", 1, save_path=None);
+
+
+Volcano plot (R)
+*****************
+Created using: :meth:`~mspypeline.BasePlotter.plot_r_volcano`
+
+.. autodescriptiononly:: mspypeline.BasePlotter.plot_r_volcano
+
+    | In the here shown volcano plot, the 10 most significant proteins for each group are annotated. However, if proteins
+      of a specific pathway should be annotated, this can be achieved by selecting one or more
+      :ref:`pathway lists <pathway-proteins>`.
+
+.. ipython:: python
+
+    plotter_with_tech_reps.plot_r_volcano("lfq_log2", 0, sample1="H1975", sample2="H838", adj_pval=True, save_path="./source/_static", fig_format=".png");
+
+.. image:: _static/plots/volcano_H1975_H838_annotation_adjusted_p_value__lfq_log2.png
+
+
+Additionally via python
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Kernel density estimate plot
+*******************************
+Created using: :meth:`~mspypeline.BasePlotter.plot_kde`
+
+.. autodescriptiononly:: mspypeline.BasePlotter.plot_kde
+
+    | In the graphs shown below, the effect of the two different protein :ref:`intensity types <hyperparameter>`.
+      In the images below the *"raw"* and *"lfq"* intensities are shown, as well as two normalizations of the raw data,
+      *"tail robust quantile normalization"* and *"tail robust quantile normalization with missing value handling"*.
+      The KDE can thus help to understand the effect of configuring certain
+      hyperparameters and how intensity types or normalization methods may influence the data.
+
+.. ipython:: python
+
+    plotter.add_normalized_option("raw", plotter.normalizers["trqn"], "trqn")
+    plotter.add_normalized_option("raw", plotter.normalizers["trqn_missing_handled"], "trqn_missing_handled")
+
+    @savefig kde_raw_plot.png width=320 align=left
+    plotter.plot_kde("raw_log2", 3, save_path=None);
+
+    @savefig kde_lfq_plot.png width=320 align=right
+    plotter.plot_kde("lfq_log2", 3, save_path=None);
+
+    @savefig kde_raw_trqn.png width=320 align=left
+    plotter.plot_kde("raw_trqn_log2", 3, save_path=None);
+
+    @savefig kde_raw_trqn_missing.png width=320 align=right
+    plotter.plot_kde("raw_trqn_missing_handled_log2", 3, save_path=None);
+
+Boxplot
+********
+Created using: :meth:`~mspypeline.BasePlotter.plot_boxplot`
+
+.. autodescriptiononly:: mspypeline.BasePlotter.plot_boxplot
+
+.. ipython:: python
+
+    @savefig boxplot.png width=700 align=center
+    plotter.plot_boxplot("lfq_log2", 3, save_path=None);
+
+Number of Proteins vs Quantiles
+********************************
+Created using: :meth:`~mspypeline.BasePlotter.plot_n_proteins_vs_quantile`
+
+.. autodescriptiononly:: mspypeline.BasePlotter.plot_n_proteins_vs_quantile
+
+
+.. ipython:: python
+    :okwarning:
+
+    plotter.plot_n_proteins_vs_quantile("lfq_log2", 3, save_path="./source/_static", fig_format=".png");
+
+.. image:: _static/n_proteins_vs_quantile_lfq_log2_level_3.png
+
+Intensity Heatmap
+******************
+Created using: :meth:`~mspypeline.BasePlotter.plot_intensity_heatmap`
+
+.. autodescriptiononly:: mspypeline.BasePlotter.plot_intensity_heatmap
+
+    | In the heatmap shown below, samples are sorted by the number of missing values and proteins are ranked by the number
+      of missing values across all samples. So depending on the defined preferences, the heatmap can, for instance, be
+      used to gather information about the distribution of missing values or the influence of the normalization method by
+      the appearance of patterns.
+
+.. ipython:: python
+
+    @savefig intensity_heatmap.png width=700 align=center
+    plotter.plot_intensity_heatmap("lfq_log2", 3, sort_index_by_missing=True, sort_columns_by_missing=True, save_path=None);
diff --git a/doc/source/get_started.rst b/doc/source/get_started.rst
index d47fcb6..588ff84 100644
--- a/doc/source/get_started.rst
+++ b/doc/source/get_started.rst
@@ -57,7 +57,7 @@ A simple analysis might look something like this:
 
 For more code examples see the :ref:`Examples <examples>`.
 
-.. _gui-quickstart:
+.. _`gui-quickstart`:
 
 Usage with GUI
 ~~~~~~~~~~~~~~
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 4aa78d6..0fca7d3 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -11,8 +11,17 @@ The source code is available on `github <https://github.com/siheming/mspypeline/
 
 Usage
 =====
-Please refer to the other parts of the documentation for :ref:`installation <installation>`,
-:ref:`how to get started <get-started>`, or use the search.
+| The ``mspypeline`` was developed to consolidate the proteomics data analysis workflow while providing both simplicity
+  and flexibility for the user.
+| Designed with an intuitive and concise graphical user interface (GUI), the ``mspypeline`` offers researchers,
+  unfamiliar with programming or data analysis, the opportunity to explore and visualize their data independently and in
+  a time-effective manner. Simultaneously, the more experienced user may interact closer with the ``mspypeline`` to
+  perform advanced analysis leveraging the plethora of customization options.
+| Thus, the ``mspypeline`` provides a platform that supports users with their proteomics data analysis by giving insight
+  into the data, offering parameter adaptation when needed, generating custom figures and by reaching biological
+  relevant conclusions through differential expression analysis and hypothesis testing.
+| Please refer to the other parts of the documentation for :ref:`installation <installation>`,
+  :ref:`how to get started <get-started>`, or use the search.
 
 
 Citation
@@ -28,11 +37,12 @@ In preparation.
    installation
    get_started
    workflow
-   package_design
-   plotters
    file_readers
-   examples
+   analysis_options
+   settings_and_configuration
    package_config
+   examples
+   gallery
    API <api_reference/index>
 
 
diff --git a/doc/source/package_config.rst b/doc/source/package_config.rst
index 707d253..a973f1d 100644
--- a/doc/source/package_config.rst
+++ b/doc/source/package_config.rst
@@ -1,11 +1,35 @@
-package configuration
+Custom Protein Lists
 =====================
 
-Default analysis settings
+Pathway and GO analysis
 ~~~~~~~~~~~~~~~~~~~~~~~~~
-.. toctree::
-   default_config
 
+| Pathway and GO analysis protein files are lists of proteins that are somewhat associated with the respective pathway
+  or GO term. Importantly, these lists have been manually created and should merely fulfill the purpose of giving an
+  idea or providing an example for a potential analysis (see :ref:`gallery`).
+
+  * GO protein lists are required for the GO analysis plot using :meth:`~mspypeline.BasePlotter.plot_go_analysis`, in
+    which an enrichment analysis for each selected GO Term file is created.
+  * Pathway protein lists serve multiple plotting options including the rank plot using
+    :meth:`~mspypeline.BasePlotter.plot_rank`, the pathway analysis plot using
+    :meth:`~mspypeline.BasePlotter.plot_pathway_analysis` and the volcano plot using
+    :meth:`~mspypeline.BasePlotter.plot_r_volcano`.
+
+| Pathway (and GO term) lists are configured globally for a data analysis and not individually for each plot. If one or
+  more pathway protein lists are selected in the GUI or :ref:`configs file <default-yaml>`, these pathways will
+  be used for any of the three listed plots if they are being created.
+| To change the choice of pathways or GO terms for an analysis, the previously selected pathways have to be un-checked
+  in the corresponding selection box in the GUI or the *"pathways:"* or *"go_term:"* arguments in the configs file have
+  to be edited manually.
+
+.. tip::
+    | Any desired pathway and GO analysis protein file can be manually provided to the ``mspypeline`` by the user. The
+      file simply has to:
+    | 1. follow the *one-column-txt-format* that can be seen in the exemplary files listed below,
+    | 2. be saved in the *.../mspypeline/config/pathway or go_term* directory, where all the other files are stored.
+
+.. attention::
+    All protein and GO analysis protein files provided here are based on the **HUMAN** proteome.
 
 .. _pathway-proteins:
 
diff --git a/doc/source/package_design.rst b/doc/source/package_design.rst
deleted file mode 100644
index 4e1623a..0000000
--- a/doc/source/package_design.rst
+++ /dev/null
@@ -1,134 +0,0 @@
-.. py:currentmodule:: mspypeline
-
-Package design
-==============
-
-.. _analysis-design:
-
-Analysis design
-~~~~~~~~~~~~~~~
-
-The project assumes that samples can be arranged into a tree structure which represents an experimental design.
-The analysis design can have any level of depth.
-
-.. warning::
-   * Different levels of the analysis design need to be separated by underscore (**_**)
-   * All samples must have the same number of levels (meaning same number of underscores)
-
-**Example Analysis Design**
-
-Assume an experiment where two cancer cell lines are compared to two non-cancer cell lines. Additionally, we have 5
-technical replicates per cell line. One sample could be called e.g. "Cancer_Line1_Rep1", or "Control_Line2_Rep3".
-The resulting analysis design could look like this:
-
-.. ipython:: python
-
-    from mspypeline.helpers import get_analysis_design
-    from pprint import pprint
-    samples = [f"Cancer_Line{l}_Rep{r}" for l in range(1, 3) for r in range(1, 6)] + [
-        f"Control_Line{l}_Rep{r}" for l in range(1, 3) for r in range(1, 6)]
-    analysis_design = get_analysis_design(samples)
-    pprint(analysis_design)
-
-Here, the "Cancer" group has a total of 10 children, which are then split in "Line1" and "Line2". "Line1" and "Line"
-both have 5 children. Level 0 corresponds to "Cancer" and "Control", level 1 corresponds to "Cancer_Line1",
-"Cancer_Line2", "Control_Line1" and "Control_Line2".
-
-An analysis design could also be more complicated like: "Cancer_Human_Week10_Cell1_Rep1".
-
-
-Sample mapping
-^^^^^^^^^^^^^^
-If the naming in the file does not translate to a proper analysis design an additional mapping can be provided.
-
-* This file is created automatically if the naming convention is violated. If the file is created automatically it will
-  be created with the name **sample_mapping_template.txt**. The general structure is already present, but the second
-  column needs to be changed into the new desired name. Then the file needs to be renamed to **sample_mapping.txt**.
-* Otherwise, it can be created manually with the name **sample_mapping.txt** on the same level as the config directory.
-  The file needs to be tab-separated with two columns. The first column named old_name should contain the sample name
-  of the ms run. The second column named new_name should follow the naming convention.
-
-Technical Replicates
-^^^^^^^^^^^^^^^^^^^^
-If the configuration setting `has_techrep` is set to True or the corresponding checkbox in the GUI is ticked the
-lowest level of the analysis design is considered as a technical replicate. Technical replicates are averaged to one
-level higher in the analysis design by taking the mean of all samples below a node. Values that are 0 are replaced with
-missing values, then for calculating the mean missing values are ignored (meaning the average of the three values
-32, 30, 0 would be replaced with 32, 30 and NaN resulting in an average of 30).
-
-.. ipython:: python
-
-    import numpy as np
-    import pandas as pd
-    from mspypeline import DataTree
-    data = pd.DataFrame(np.exp2(np.random.normal(26, 2, (5, 20))).astype(int), columns=samples)
-    tree_agg = DataTree.from_analysis_design(analysis_design, data, True)
-    tree_no_agg = DataTree.from_analysis_design(analysis_design, data, False)
-    tree_no_agg.aggregate(None, None)
-    tree_agg.aggregate(None, None)
-
-The columns of the last output are now named "Cancer_Line1", "Cancer_Line2", etc. and the values of the replicates
-"Rep1" to "Rep5" is averaged as mean. This can help to improve results since measurement results are noisy or proteins
-might be missing in some of the samples by random chance.
-
-Thresholds and Comparisons
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-Some plots need to determine whether a protein can be compared between two different groups.
-Four different results are possible when comparing a protein between group A and group B.
-
-* Unique in A: above threshold in A and completely absent in B
-* Unique in B: above threshold in B and completely absent in A
-* Can be compared: above threshold in A and B
-* Otherwise: not considered
-
-The threshold is determined dynamically based on the number of samples in a group. The next two plots show the
-thresholding for different numbers of samples.
-
-.. ipython:: python
-
-    import matplotlib.pyplot as plt
-    from mspypeline.helpers import get_number_of_non_na_values, get_non_na_percentage
-    x_values = [x for x in range(1, 31)]
-    y_values = [get_number_of_non_na_values(x) for x in x_values]
-    fig, ax = plt.subplots(1,1, figsize=(7,7))
-    ax.plot(x_values, y_values, marker=".");
-    ax.set_xticks(x_values);
-    ax.set_yticks(y_values);
-    ax.set_xlabel("Number of samples");
-    @savefig plot_non_na_samples.png width=6in
-    ax.set_ylabel("Required number of non na (missing) values");
-
-The plot shows that the minimum number of non missing values is 3, then steadily increases.
-
-An example: Group A has 7 samples, Group B has 8 Samples.
-
-* Unique in A: Group A has equals or more than 5 non missing values and Group B has only missing values
-* Unique in B: Group B has equals or more than 6 non missing values and Group A has only missing values
-* Can be compared: Group A has equals or more than 5 non missing values and
-  Group B has equals or more than 6 non missing values
-* Not considered: In all other cases
-
-This criterion is quite harsh, but the results will be dependable.
-
-The next plot shows the required percentage of non zero values.
-
-.. ipython:: python
-
-    y_values = [get_non_na_percentage(x) for x in x_values]
-    fig, ax = plt.subplots(1,1, figsize=(7,7))
-    ax.plot(x_values, y_values, marker=".");
-    ax.set_ylim(0, 1);
-    ax.set_xlabel("Number of samples");
-    ax.set_xticks(x_values);
-    @savefig plot_non_zero_values.png width=6in
-    ax.set_ylabel("Required percentage of non zero values");
-
-
-File readers
-~~~~~~~~~~~~
-For the different file formats a file reader can be designed to translate the file into the correct internal format.
-Currently only a reader for the MaxQuant format is provided.
-
-Settings as YAML files
-~~~~~~~~~~~~~~~~~~~~~~
-The specified settings are saved as yaml files. Plots can be easily reproduced by reusing the same settings.
diff --git a/doc/source/pathways/Custom Axl Pathway.rst b/doc/source/pathways/Custom Axl Pathway.rst
deleted file mode 100644
index 221f169..0000000
--- a/doc/source/pathways/Custom Axl Pathway.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Custom Axl Pathway
-==================
-
-.. include:: ../../../mspypeline/config/pathways/CUSTOM_AXL_PATHWAY.txt
-   :literal:
-
diff --git a/doc/source/pathways/Go Apoptotic Signaling Pathway.rst b/doc/source/pathways/Go Apoptotic Signaling Pathway.rst
deleted file mode 100644
index 6c5cab9..0000000
--- a/doc/source/pathways/Go Apoptotic Signaling Pathway.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Go Apoptotic Signaling Pathway
-==============================
-
-.. include:: ../../../mspypeline/config/pathways/GO_APOPTOTIC_SIGNALING_PATHWAY.txt
-   :literal:
-
diff --git a/doc/source/pathways/Go Cytokine Production.rst b/doc/source/pathways/Go Cytokine Production.rst
deleted file mode 100644
index 3607a55..0000000
--- a/doc/source/pathways/Go Cytokine Production.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Go Cytokine Production
-======================
-
-.. include:: ../../../mspypeline/config/pathways/GO_CYTOKINE_PRODUCTION.txt
-   :literal:
-
diff --git a/doc/source/pathways/Go Inflammatory Response.rst b/doc/source/pathways/Go Inflammatory Response.rst
deleted file mode 100644
index 303c99c..0000000
--- a/doc/source/pathways/Go Inflammatory Response.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Go Inflammatory Response
-========================
-
-.. include:: ../../../mspypeline/config/pathways/GO_INFLAMMATORY_RESPONSE.txt
-   :literal:
-
diff --git a/doc/source/pathways/Go Negative Regulation Of Inflammatory Response.rst b/doc/source/pathways/Go Negative Regulation Of Inflammatory Response.rst
deleted file mode 100644
index 2da0a1f..0000000
--- a/doc/source/pathways/Go Negative Regulation Of Inflammatory Response.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Go Negative Regulation Of Inflammatory Response
-===============================================
-
-.. include:: ../../../mspypeline/config/pathways/GO_NEGATIVE_REGULATION_OF_INFLAMMATORY_RESPONSE.txt
-   :literal:
-
diff --git a/doc/source/pathways/Go Positive Regulation Of Cytokine Production.rst b/doc/source/pathways/Go Positive Regulation Of Cytokine Production.rst
deleted file mode 100644
index 13cdd56..0000000
--- a/doc/source/pathways/Go Positive Regulation Of Cytokine Production.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Go Positive Regulation Of Cytokine Production
-=============================================
-
-.. include:: ../../../mspypeline/config/pathways/GO_POSITIVE_REGULATION_OF_CYTOKINE_PRODUCTION.txt
-   :literal:
-
diff --git a/doc/source/pathways/Go Regeneration.rst b/doc/source/pathways/Go Regeneration.rst
deleted file mode 100644
index 4c7b4c2..0000000
--- a/doc/source/pathways/Go Regeneration.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Go Regeneration
-===============
-
-.. include:: ../../../mspypeline/config/pathways/GO_Regeneration.txt
-   :literal:
-
diff --git a/doc/source/pathways/Go Response To Hepatocyte Growth Factor.rst b/doc/source/pathways/Go Response To Hepatocyte Growth Factor.rst
deleted file mode 100644
index f85c50a..0000000
--- a/doc/source/pathways/Go Response To Hepatocyte Growth Factor.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Go Response To Hepatocyte Growth Factor
-=======================================
-
-.. include:: ../../../mspypeline/config/pathways/GO_RESPONSE_TO_HEPATOCYTE_GROWTH_FACTOR.txt
-   :literal:
-
diff --git a/doc/source/pathways/Naba Matrisome Associated.rst b/doc/source/pathways/Naba Matrisome Associated.rst
deleted file mode 100644
index 7644d08..0000000
--- a/doc/source/pathways/Naba Matrisome Associated.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Naba Matrisome Associated
-=========================
-
-.. include:: ../../../mspypeline/config/pathways/NABA_MATRISOME_ASSOCIATED.txt
-   :literal:
-
diff --git a/doc/source/pathways/Naba Matrisome.rst b/doc/source/pathways/Naba Matrisome.rst
deleted file mode 100644
index f3d8cf5..0000000
--- a/doc/source/pathways/Naba Matrisome.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Naba Matrisome
-==============
-
-.. include:: ../../../mspypeline/config/pathways/NABA_MATRISOME.txt
-   :literal:
-
diff --git a/doc/source/pathways/Naba Secreted Factors.rst b/doc/source/pathways/Naba Secreted Factors.rst
deleted file mode 100644
index 94b499e..0000000
--- a/doc/source/pathways/Naba Secreted Factors.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Naba Secreted Factors
-=====================
-
-.. include:: ../../../mspypeline/config/pathways/NABA_SECRETED_FACTORS.txt
-   :literal:
-
diff --git a/doc/source/pathways/Reactome Met Receptor Activation.rst b/doc/source/pathways/Reactome Met Receptor Activation.rst
deleted file mode 100644
index bb76bdc..0000000
--- a/doc/source/pathways/Reactome Met Receptor Activation.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Reactome Met Receptor Activation
-================================
-
-.. include:: ../../../mspypeline/config/pathways/REACTOME_MET_RECEPTOR_ACTIVATION.txt
-   :literal:
-
diff --git a/doc/source/plotters.rst b/doc/source/plotters.rst
deleted file mode 100644
index 51e3629..0000000
--- a/doc/source/plotters.rst
+++ /dev/null
@@ -1,59 +0,0 @@
-.. _plotters:
-
-Plotters
-===============
-
-Base Plotter
-~~~~~~~~~~~~
-
-Report
-******
-The Base Plotter does not provide a report.
-
-Plots
-*****
-
-The GUI allows for these plots:
-
-Normalization plots:
-
-* Normalization overview: :meth:`~mspypeline.BasePlotter.plot_normalization_overview`
-* Heatmap overview: :meth:`~mspypeline.BasePlotter.plot_intensity_heatmap`
-
-Comparison plots:
-
-* Detection counts: :meth:`~mspypeline.BasePlotter.plot_detection_counts`
-* Number of detected proteins :meth:`~mspypeline.BasePlotter.plot_detected_proteins_per_replicate`
-* Venn diagrams: :meth:`~mspypeline.BasePlotter.plot_venn_results`
-* Group diagrams: :meth:`~mspypeline.BasePlotter.plot_venn_groups`
-* PCA overview: :meth:`~mspypeline.BasePlotter.plot_pca_overview`
-* Intensity histogram: :meth:`~mspypeline.BasePlotter.plot_intensity_histograms`
-* Relative std: :meth:`~mspypeline.BasePlotter.plot_relative_std`
-* Scatter replicates: :meth:`~mspypeline.BasePlotter.plot_scatter_replicates`
-* Experiment comparison: :meth:`~mspypeline.BasePlotter.plot_experiment_comparison`
-* Rank: :meth:`~mspypeline.BasePlotter.plot_rank`
-
-Statistical inference plots:
-
-* Pathway analysis: :meth:`~mspypeline.BasePlotter.plot_pathway_analysis`
-* Pathway timecourse: :meth:`~mspypeline.BasePlotter.plot_pathway_timecourse`
-* Go analysis: :meth:`~mspypeline.BasePlotter.plot_go_analysis`
-* Volcano plot (R): :meth:`~mspypeline.BasePlotter.plot_r_volcano`
-
-Additionally via python:
-
-* :meth:`~mspypeline.BasePlotter.plot_kde`
-* :meth:`~mspypeline.BasePlotter.plot_boxplot`
-* :meth:`~mspypeline.BasePlotter.plot_n_proteins_vs_quantile`
-
-Max Quant Plotter
-~~~~~~~~~~~~~~~~~
-
-Report
-*******
-A quality control report for the output of MaxQuant. See :meth:`~mspypeline.MaxQuantPlotter.create_report`
-for a description of the output.
-
-Plots
-*****
-The MaxQuant Plotter provides the same plots as the Base Plotter.
diff --git a/doc/source/savefig/plot_global_protein_level_median_norm.png b/doc/source/savefig/plot_global_protein_level_median_norm.png
deleted file mode 100644
index d908f59..0000000
Binary files a/doc/source/savefig/plot_global_protein_level_median_norm.png and /dev/null differ
diff --git a/doc/source/savefig/plot_global_protein_level_raw.png b/doc/source/savefig/plot_global_protein_level_raw.png
deleted file mode 100644
index 45b8581..0000000
Binary files a/doc/source/savefig/plot_global_protein_level_raw.png and /dev/null differ
diff --git a/doc/source/savefig/plot_non_na_samples.png b/doc/source/savefig/plot_non_na_samples.png
deleted file mode 100644
index 08fe4b4..0000000
Binary files a/doc/source/savefig/plot_non_na_samples.png and /dev/null differ
diff --git a/doc/source/savefig/plot_non_zero_values.png b/doc/source/savefig/plot_non_zero_values.png
deleted file mode 100644
index eb1cac7..0000000
Binary files a/doc/source/savefig/plot_non_zero_values.png and /dev/null differ
diff --git a/doc/source/settings_and_configuration.rst b/doc/source/settings_and_configuration.rst
new file mode 100644
index 0000000..49c89ca
--- /dev/null
+++ b/doc/source/settings_and_configuration.rst
@@ -0,0 +1,190 @@
+.. _settings:
+
+Settings and Configurations
+============================
+
+The configuration YAML file
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+| To specify the settings for the analysis a config.yml YAML file has to be provided. The YAML file stores the main
+  configurations that determine which results will be created. This configuration file also offers the specification of
+  multiple optional analysis options.
+| If no custom YAML file is generated, the :ref:`default YAML file <default-yaml>` provided by the ``mspypeline`` at the
+  start of the analysis may be used containing the default analysis settings. If the data analysis is performed via the
+  GUI, no further interaction with the YAML file is necessary.
+| Plots can be easily reproduced by reusing the same settings/YAML file.
+
+.. _default-yaml:
+
+Analysis settings
+*************************
+.. toctree::
+    default_config
+.. toctree::
+    adjustable_options_config
+
+
+.. _analysis-design:
+
+Analysis Design
+~~~~~~~~~~~~~~~
+| To perform comparative data analysis, the ``mspypeline`` assumes that the data consists samples that can be arranged
+  into a tree structure that resamples the experimental setup. Different samples of an experiment are arranged
+  in groups and subgroups dependent on the samples name. This naming convention is the key principal to draw comparisons
+  between distinct samples of different groups/at different levels. The analysis design can be of any level of depth.
+
+.. warning::
+   * Different levels of the analysis design need to be separated by underscore (**_**)
+   * All samples must have the same number of levels (meaning same number of underscores)
+
+
+**Example Analysis Design**
+
+| Assume an experiment, where two cancer cell lines are compared to two non-cancer cell lines. Additionally, we have 3
+  technical replicates per cell line. One sample could be called e.g. "Cancer_Line1_Rep1", or "Control_Line2_Rep3".
+| The resulting analysis design could look like this:
+
+.. ipython:: python
+
+    from mspypeline.helpers import get_analysis_design
+    from pprint import pprint
+    samples = [f"Cancer_Line{l}_Rep{r}" for l in range(1, 3) for r in range(1, 4)] + [
+        f"Control_Line{l}_Rep{r}" for l in range(1, 3) for r in range(1, 4)]
+    analysis_design = get_analysis_design(samples)
+    pprint(analysis_design)
+
+| Level 0 corresponds to "Cancer" and "Control", level 1 corresponds to "Cancer_Line1", "Cancer_Line2", "Control_Line1"
+  and "Control_Line2" and level 2 corresponds to the technical replicates "Cancer_Line1_Rep1", ... . Here, the "Cancer"
+  group has a total of 6 children, which are then split in "Line1" and "Line2". "Line1" and "Line2" both have 3 children.
+| If a comparison between the "Cancer" and "Control" groups should be performed, the lowest level (level 0) of the Data
+  Tree must be chosen in rhe analysis. The results will consequently show the comparison of both level 0 groups "Cancer"
+  and "Control" with all their children.
+| On the other hand, if the different cancer and control cell lines should be compared, the second level (level 1) of the
+  Data Tree must be selected. The results will consequently show the comparison of the four different level 1 groups
+  "Cancer_Line1", "Cancer_Line2", "Control_Line1 and "Control_Line2" each with their 3 replicates.
+| If all the 12 replicates should be compared to each other, the last level (level 2) must be selected in the analysis.
+
+
+.. _sample-mapping:
+
+Sample Mapping
+***************
+
+| Should the naming convention deviate from the expected standard, it is possible to subsequently correct the sample
+  naming with a provided sample mapping so that samples translate to a proper analysis design.
+| If the naming convention is violated a sample mapping can be provided manually or by using the default file.
+
+* default **sample_mapping_template.txt** file: This file is created automatically if the naming convention is
+  incorrect. The file already provides the general structure of the sample mapping consisting of two columns *old name*
+  which is readily filled out and *new name* which needs to be filled with the new desired sample name. Then the file
+  needs to be renamed to **sample_mapping.txt**.
+* manual **sample_mapping.txt** file: The file needs to be tab-separated with two columns and saved on the same level
+  as the config directory. The first column named *old name* should contain the sample name
+  of the ms run. The second column named *new name* should follow the naming convention.
+
+| A *sample-mapping.txt* file should have a simple structure as shown in the table below. All samples need to be mapped,
+  non-conforming sample names need to be corrected in the *new name* columns (e.g. row 1-3) and sample names that are
+  already correct simply need to be copied in the *new name* columns (e.g. row 4-5).
+| Since this example is only intended to give a small insight into the sample-mapping file, the remaining samples of the
+  analysis design are not listed here, which would be necessary for a real data analysis.
+
+.. list-table:: sample_mapping.txt
+    :widths: 25, 25
+    :header-rows: 1
+
+    * - old name
+      - new name
+    * - Cancer_Line1-Rep1
+      - Cancer_Line1_Rep1
+    * - Cance_Line1_Rep2
+      - Cancer_Line1_Rep2
+    * - Cancer_Line_1_Rep3
+      - Cancer_Line1_Rep3
+    * - Cancer_Line2_Rep1
+      - Cancer_Line2_Rep1
+    * - Cancer_Line2_Rep2
+      - Cancer_Line2_Rep2
+    * - Cancer...
+      - Cancer..
+
+.. _tech-reps:
+
+Technical Replicates
+********************
+| If the :ref:`configuration setting <default-yaml>` `has_techrep` is set to True or the corresponding checkbox in the
+  GUI is ticked, the highest level of the analysis design is considered as a technical replicate.
+| Technical replicates are averaged and cumulated to one sample of the next lowest level in the analysis design.
+  Respectively, the mean of all samples below a node is calculated and assigned to that node. The last level of the Data
+  Tree is thus omitted. Values that are 0 are replaced with missing values, which are neglected when calculating the
+  mean of samples (e.g. the average of the three values 32, 30, 0 would be replaced with 32, 30 and NaN resulting in an
+  average of 30).
+
+.. ipython:: python
+
+    import numpy as np
+    import pandas as pd
+    from mspypeline import DataTree
+    data = pd.DataFrame(np.exp2(np.random.normal(26, 2, (3, 12))).astype(int), columns=samples)
+    tree_agg = DataTree.from_analysis_design(analysis_design, data, True)
+    tree_no_agg = DataTree.from_analysis_design(analysis_design, data, False)
+    tree_no_agg.aggregate(None, None)
+    tree_agg.aggregate(None, None)
+
+| The columns of the last output are now named "Cancer_Line1", "Cancer_Line2", etc. and the values of the replicates
+  "Rep1" to "Rep3" is averaged as mean. This can help to improve results since measurement results are noisy or proteins
+  might be missing in some of the samples by random chance.
+
+
+
+.. _thresholding:
+
+Thresholds and Comparisons
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+| Some plots need to determine whether a protein can be compared between two different groups.
+| Four different results are possible when comparing a protein between group A and group B.
+
+* Unique in A: above threshold in A and completely absent in B
+* Unique in B: above threshold in B and completely absent in A
+* Can be compared: above threshold in A and B
+* Otherwise: not considered
+
+| The threshold is determined dynamically based on the number of samples in a group. The next two plots show the
+  thresholding for different numbers of samples.
+
+.. ipython:: python
+
+    import matplotlib.pyplot as plt
+    from mspypeline.helpers import get_number_of_non_na_values, get_non_na_percentage
+    x_values = [x for x in range(1, 31)]
+    y_values = [get_number_of_non_na_values(x) for x in x_values]
+    fig, ax = plt.subplots(1,1, figsize=(7,5))
+    ax.plot(x_values, y_values, marker=".");
+    ax.set_xticks(x_values);
+    ax.set_yticks(y_values);
+    ax.set_xlabel("Number of samples");
+    @savefig plot_non_na_samples.png width=6in
+    ax.set_ylabel("Required number of non na (missing) values");
+
+The plot shows that the minimum number of non missing values is 3, then steadily increases.
+
+An example: Group A has 7 samples, Group B has 8 Samples.
+
+* Unique in A: Group A has equals or more than 5 non missing values and Group B has only missing values
+* Unique in B: Group B has equals or more than 6 non missing values and Group A has only missing values
+* Can be compared: Group A has equals or more than 5 non missing values and
+  Group B has equals or more than 6 non missing values
+* Not considered: In all other cases
+
+This criterion is quite harsh, but the results will be dependable.
+
+The next plot shows the required percentage of non zero values.
+
+.. ipython:: python
+
+    y_values = [get_non_na_percentage(x) for x in x_values]
+    fig, ax = plt.subplots(1,1, figsize=(7,5))
+    ax.plot(x_values, y_values, marker=".");
+    ax.set_ylim(0, 1);
+    ax.set_xlabel("Number of samples");
+    ax.set_xticks(x_values);
+    @savefig plot_non_zero_values.png width=6in
+    ax.set_ylabel("Required percentage of non zero values");
diff --git a/doc/source/workflow.rst b/doc/source/workflow.rst
index a7c1ad4..d8d7357 100644
--- a/doc/source/workflow.rst
+++ b/doc/source/workflow.rst
@@ -5,12 +5,33 @@ Workflow
 
 Quality control
 ~~~~~~~~~~~~~~~
-Ensure that the quality of the results to analyze are of sufficient quality. This can be done with the report provided
-by the :ref:`mspypeline plotters <plotters>`.
+| Ensure that the quality of the results to analyze are of sufficient quality. This can be done with the report provided
+  by the :ref:`mspypeline plotters <plotters>`.
 
-Determining normalization method
+.. _hyperparameter:
+
+Determining Data Hyperparameter
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Decide for a normalization method. Normalization options are:
+| Data may be processed in multiple ways and such modeling has the potential to shape the results of an analysis
+  substantially.
+| This kind of data processing comprises the choice of protein intensities provided by MaxQuant, including raw,
+  label-free quantification (LFQ) or intensity-based absolute quantification (iBAQ) intensities, the removal of
+  erroneous samples or the normalization and standardization of the data set.
+
+Intensity options
+^^^^^^^^^^^^^^^^^^^
+
+* LFQ Intensity ("lfq_log2")
+* raw Intensity ("raw_log2")
+* iBAQ Intensity ("ibaq_log2")
+
+| Despite the choice of protein intensity, the GUI handles all data in log2 format. However, it is possible to analyze
+  the data without log2 scale ("lfq", "raw", "ibaq") if advanced data analysis is performed by interacting rather direct
+  with the plotters.
+
+
+Normalization options
+^^^^^^^^^^^^^^^^^^^^^^
 
 * No normalization
 * Median Normalization via: :class:`~mspypeline.MedianNormalizer`
@@ -22,30 +43,42 @@ Decide for a normalization method. Normalization options are:
 * Tail Robust Median Normalization via: :class:`~mspypeline.TailRobustNormalizer` and
   :class:`~mspypeline.MedianNormalizer`
 
-To help to decide for a normalization method two plots can help:
-:meth:`~mspypeline.BasePlotter.plot_normalization_overview` and :meth:`~mspypeline.BasePlotter.plot_intensity_heatmap`.
-Please read the function description how normalized data should look like. Also, after deciding for a normalization
-method it should not be changed, especially in hindsight after seeing the results of other plots.
+| To aid the determination of the best possible normalization method, two plots may be created:
+  :meth:`~mspypeline.BasePlotter.plot_normalization_overview` and
+  :meth:`~mspypeline.BasePlotter.plot_heatmap_overview_all_normalizers`.
+| These methods will output a multipage PDF file in which the data is plotted repeatedly after applying the different
+  normalization options. Thereby it is possible to get a better understanding of the effect of each normalization method
+  on the data.
+| Please read the function description explaining what normalized data should look like. Once a normalization method is
+  chosen, it is highly recommended to perform all further analysis with the same normalized data.
+
+
 
-(Optionally) Select pathways and GO-Terms of interest
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Exploratory Analysis
+~~~~~~~~~~~~~~~~~~~~~
+
+Create descriptive and comparison plots
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+| The descriptive and comparison plots can for example help to analyze how biological replicates compare to another or
+  how different conditions effect detected proteins.
+
+Create statistical inference plots
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+| The statistical inference plots show differential protein intensities between two groups or conditions. The Volcano
+  plot uses the R package limma to determine significances based on moderated t-statistics. Additional R packages might
+  be downloaded when this plot is created for the first time.
+
+Select pathways and GO-Terms of interest
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 Select :ref:`pathway-proteins`. Selected pathways will have following effects:
 
 * for the :meth:`~mspypeline.BasePlotter.plot_pathway_analysis` one plot per pathway will be created
 * in the :meth:`~mspypeline.BasePlotter.plot_rank`, if a protein is found it will be marked on the plot
   and colored by the pathway
+* in the :meth:`~mspypeline.BasePlotter.plot_r_volcano`, if a pathway is selected, proteins of that pathway will be
+  annotated in the plot instead of the most significant proteins that are annotated by default
 
 Select :ref:`go-term-proteins`. Selected GO-Terms will have following effects:
 
-* for the :meth:`~mspypeline.BasePlotter.plot_go_analysis` one additional barplot is added
-
-Create descriptive and comparison plots
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The descriptive and comparison plots can e.g. help to analyze how biological replicates compare to another or
-how different conditions effect detected proteins.
+* for the :meth:`~mspypeline.BasePlotter.plot_go_analysis` one additional barplot is added per GO term
 
-Create statistical inference plots
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The statistical inference plots show how significant different proteins are expressed in different conditions.
-The Volcano plot uses the R package limma, so additional R packages might be downloaded when this plot is created
-for the first time.
diff --git a/environment.yml b/environment.yml
index 0771bbc..3fff582 100644
--- a/environment.yml
+++ b/environment.yml
@@ -14,7 +14,6 @@ dependencies:
   - matplotlib-venn=0.11.5
   - adjusttext=0.7.3.1
   - scikit-learn=0.22.1
-  - plotly=4.6.0
   - sphinx=3.0.4
   - sphinx-autoapi=1.4.0
   - sphinx_rtd_theme=0.4.3
diff --git a/mspypeline/__init__.py b/mspypeline/__init__.py
index 8e39d12..c0fe69e 100644
--- a/mspypeline/__init__.py
+++ b/mspypeline/__init__.py
@@ -12,7 +12,7 @@ def create_app(test_config=None):
 
 # flatten package imports for the core package
 from .version import __version__
-from .plotting_backend import plotly_plots, matplotlib_plots
+from .plotting_backend import matplotlib_plots
 from .modules import *
 from .core import *
 from .file_reader import *
@@ -23,7 +23,6 @@ def create_app(test_config=None):
     "path_package",
     "path_package_config",
     "__version__",
-    "plotly_plots",
     "matplotlib_plots",
     "MQReader"
 ]
@@ -31,6 +30,32 @@ def create_app(test_config=None):
 __all__.extend(modules.__all__)
 __all__.extend(file_reader.__all__)
 
+
+def load_example_dataset(path_dataset: str = None, configs: dict = None):
+    import pandas as pd
+
+    if configs is None:
+        configs = {}
+    if path_dataset is None:
+        path_dataset = os.path.join(os.path.split(path_package)[0], "mspypeline_public_dataset")
+    path_dataset_txt = os.path.join(path_dataset, "txt")
+    init = MSPInitializer(path_dataset)
+    init.init_config()
+    init.file_path_yaml = "default"
+    init.configs.update(configs)
+    init.read_data()
+
+    init.reader_data["mqreader"]["contaminants"] = pd.read_pickle(os.path.join(path_dataset_txt, "contaminants.gzip"))
+    init.reader_data["mqreader"]["evidence"] = pd.read_pickle(os.path.join(path_dataset_txt, "evidence.gzip"))
+    init.reader_data["mqreader"]["msmsScans"] = pd.read_pickle(os.path.join(path_dataset_txt, "msmsScans.gzip"))
+    init.reader_data["mqreader"]["msScans"] = pd.read_pickle(os.path.join(path_dataset_txt, "msScans.gzip"))
+    init.reader_data["mqreader"]["parameters"] = pd.read_pickle(os.path.join(path_dataset_txt, "parameters.gzip"))
+    init.reader_data["mqreader"]["peptides"] = pd.read_pickle(os.path.join(path_dataset_txt, "peptides.gzip"))
+    init.reader_data["mqreader"]["proteinGroups"] = pd.read_pickle(os.path.join(path_dataset_txt, "proteinGroups.gzip"))
+    init.reader_data["mqreader"]["summary"] = pd.read_pickle(os.path.join(path_dataset_txt, "summary.gzip"))
+    return init
+
+
 if __name__ == "__main__":
     msparser = MSPParser()
     UIHandler(**msparser.args_dict)
diff --git a/mspypeline/config/ms_analysis_adjustable_options.yml b/mspypeline/config/ms_analysis_adjustable_options.yml
new file mode 100644
index 0000000..915fdaa
--- /dev/null
+++ b/mspypeline/config/ms_analysis_adjustable_options.yml
@@ -0,0 +1,177 @@
+# ##### MAIN SETTINGS ########
+# settings that affect data processing
+
+selected_reader: mqreader       # which file reader should be used
+selected_normalizer: null       # which normalizer should be used
+
+has_techrep: true               # does the file have technical replicates (can be "true" or "false")
+
+use_protein_id: false           # should the protein id be used (can be "true" or "false"), or TODO
+
+equal_variance: false           # should equal variance be assumed for the t-test? (can be "true" or "false")
+
+pathways: []                    # list of pathways which should be analyzed
+go_terms: []                    # list of go_terms which should be analyzed
+
+mqreader:
+  index_col: "Gene name"        # default and so far only option that works stabely
+  duplicate_handling: "sum"     # how should proteins with duplicate index_col be treated ? can be sum or drop
+  drop_columns: []              # string or list of samples taht should be dropped
+  all_replicates: []            # list of all replicates
+  analysis_design: null         # mapping of the analysis design organized ad tree structure
+  levels: null                  # int giving the number of levels
+  level_names: null             # list of level names (e.g. 0, 1, 2, 3)
+
+# ###### PLOT CREATION SETTINGS #######
+# settings that determine which results will be created
+# required arguments to create a plot are only the plot function "plot_...", create_plot, dfs_to_use, and levels.
+plot_normalization_overview_all_normalizers_settings:
+  create_plot: false
+  dfs_to_use: []
+  levels: []
+  quantile_range: null          # Optional[np.array] e.g.: np.arange(0.05, 1, 0.05)
+  height: 15                    # height if the figure
+  intensity_label: "Intensity"  # name of the experiment
+
+plot_heatmap_overview_all_normalizers_settings:
+  create_plot: false
+  dfs_to_use: []
+  levels: []
+  sort_index: false             # should proteins be sorted alphanumerically
+  sort_index_by_missing: true   # should proteins be sorted by missing values
+  sort_columns_by_missing: true # should samples be sorted by missing values
+  cmap: "autum_r"               # color map to use for heatmap coloring
+  cmap_bad: "dimgray"           # color for missing values
+  cax: null                     # plt.Axes, axis for the color bar
+  plot: null                    # Optional[Tuple[plt.Figure, plt.Axes]]  --> figure to put plot
+  vmax: null                    # Optional[float]
+  vmin: null                    # Optional[float]
+  intensity_label: "Intensity"  # name of the experiment
+  show_suptitle: true           # should a figure title be shown
+
+plot_detection_counts_settings:
+  create_plot: false
+  dfs_to_use: []
+  levels: []
+  intensity_label: "Intensity"  # name of the experiment
+  show_suptitle: true           # should a figure title be shown
+
+plot_detected_proteins_per_replicate_settings:
+  create_plot: false
+  dfs_to_use: []
+  levels: []
+  intensity_label: "Intensity"  # name of the experiment
+  show_suptitle: true           # should a figure title be shown
+
+plot_venn_results_settings:
+  create_plot: false
+  dfs_to_use: []
+  levels: []
+  show_suptitle: true           # should a figure title be shown
+  title_font_size: 20           # font size of the figure title
+  set_label_font_size: 16       # font size of the text labels
+  subset_label_font_size: 14    # font size of the numbers
+
+plot_venn_groups_settings:
+  create_plot: false
+  dfs_to_use: []
+  levels: []
+  show_suptitle: true           # should a figure title be shown
+  title_font_size: 20           # font size of the figure title
+  set_label_font_size: 16       # font size of the text labels
+  subset_label_font_size: 14    # font size of the numbers
+
+plot_pca_overview_settings:
+  create_plot: false
+  dfs_to_use: []
+  levels: []
+  no_missing_values: true       # should missing values be neglected? (can be "true" or "false")
+  n_components: 2               # how many principal components should be calculated
+  fill_na_before_norm: false    # if data should be interpolated, should this be done before normalisation
+  fill_value:  0                # if data should be interpolated, which fill value should be used
+  normalize: true               # should transformed data be normalized with the singular values before plotting
+  intensity_label: "Intensity"  # name of the experiment
+  color_map: null               # Optional[dict]: a mapping from the column names to a color
+  show_suptitle: true           # should a figure title be shown
+  marker_size: 150              # size of the points in the scatter plots
+  legend_marker_size: 12        # size of the legend marker
+
+
+plot_intensity_histograms_settings:
+  create_plot: false
+  dfs_to_use: []
+  levels: []
+  intensity_label: "Intensity"  # name of the experiment
+  show_suptitle: true           # should a figure title be shown
+  compare_to_remaining: false   # should the sample be compared to the overall samples
+  legend: false                 # should a legend for the samples be displayed
+  n_bins: 25                    # how many bins should the histograms have
+  show_mean: true               # should the mean intensity be indicated
+  histtype: "bar"               # type of histogram: can be "bar", "barstacked" "step", "stepfilled"
+  color: null                   # string or list of any matplotlib supported color
+  plot: null                    # Optional[Tuple[plt.Figure, plt.Axes]]  --> figure to put plot
+
+plot_relative_std_settings:
+  create_plot: false
+  dfs_to_use: []
+  levels: []
+  experiment_name: ""           # string: name of the overall experiment
+  intensity_label: "Intensity"  # name of the intensities for the x label
+  show_suptitle: true           # should a figure title be shown
+  bins: (10, 20, 30)            # in which bins should the standard deviations be categorized
+  cmap: null                    # dict: mapping for the digitized labels to a color
+                                # example: default_cm = {0: "navy", 1: "royalblue", 2: "skyblue", 3: "darkgray"}
+
+plot_scatter_replicates_settings:
+  create_plot: false
+  dfs_to_use: []
+  levels: []
+  intensity_label: "Intensity"  # name of the experiment
+  show_suptitle: false          # should a figure title be shown
+
+plot_experiment_comparison_settings:
+  create_plot: false
+  dfs_to_use: []
+  levels: []
+  intensity_label: "Intensity"  # name of the experiment
+  show_suptitle: true           # should a figure title be shown
+  plot: null                    # Optional[Tuple[plt.Figure, plt.Axes]]  --> figure to put plot
+
+plot_rank_settings:
+  create_plot: false
+  dfs_to_use: []
+  levels: []
+  intensity_label: "Intensity"  # name of the experiment
+  full_name: "Experiment"       # which data node/group of samples should be compared
+  show_suptitle: true           # should a figure title be shown
+
+plot_pathway_analysis_settings:
+  create_plot: false
+  dfs_to_use: []
+  levels: []
+  equal_var: true
+  show_suptitle: true           # should a figure title be shown
+  threshold: 0.05               # maximum p value indicating significance
+  intensity_label: "Intensity"  # name of the intensities for the x label
+  color_map: null               # Optional[dict]: a mapping from the column names to a color
+
+plot_go_analysis_settings:
+  create_plot: false
+  dfs_to_use: []
+  levels: []
+  show_suptitle: true           # should a figure title be shown
+  intensity_label: "Intensity"  # name of the experiment
+
+plot_r_volcano_settings:
+  create_plot: false
+  dfs_to_use: []
+  levels: []
+  adj_pval: false               # should the adjusted p-val be used? (can be "true" or "false")
+  sample1: null                 # string of the sample that should be analysed (left side/ downregulated)
+  sample2: null                 # string of the sample that should be analysed (right side/ upregulated)
+  intensity_label: "Intensity"  # name of the experiment
+  show_suptitle: true           # should a figure title be shown
+  pval_threshold: 0.05          # float: maximum p value indicating significance
+  fchange_threshold: 2          # float: min fold change threshold (before log2 transformation) to be labelled significant
+  scatter_size: 20              # float: size of the points in the scatter plots
+  n_labelled_proteins: 10       # int: number of points that will be marked in th plot
diff --git a/mspypeline/config/ms_analysis_default.yml b/mspypeline/config/ms_analysis_default.yml
index 93c82c4..e90f016 100644
--- a/mspypeline/config/ms_analysis_default.yml
+++ b/mspypeline/config/ms_analysis_default.yml
@@ -1,21 +1,22 @@
 # ##### MAIN SETTINGS ########
-# settings that effect which results will be created
+# settings that affect data processing
 
-selected_reader: mqreader
-selected_normalizer: None
+selected_reader: mqreader  # which file reader should be used
+selected_normalizer: None  # which normalizer should be used
 
-pathways: []
-# list of pathways which should be analyzed
+has_techrep: true  # does the file have technical replicates (can be "true" or "false")
 
-go_terms: []
-# list of go_terms which should be analyzed
+use_protein_id: false   # should the protein id be used (can be "true" or "false"), or TODO
 
-has_techrep: true
-# does the file have technical replicates
-# can be "true" or "false"
+equal_variance: false   # should equal variance be assumed for the t-test? (can be "true" or "false")
 
-# ###### PLOT CREATION SETTINGS #######
+pathways: []       # list of pathways which should be analyzed
+go_terms: []       # list of go_terms which should be analyzed
+
+mqreader: {}
 
+# ###### PLOT CREATION SETTINGS #######
+# settings that determine which results will be created
 plot_normalization_overview_all_normalizers_settings:
   create_plot: false
   dfs_to_use: []
@@ -31,77 +32,65 @@ plot_detection_counts_settings:
   dfs_to_use: []
   levels: []
 
-plot_number_of_detected_proteins_settings:
+plot_detected_proteins_per_replicate_settings:
   create_plot: false
   dfs_to_use: []
   levels: []
 
-plot_intensity_histograms_settings:
+plot_venn_results_settings:
   create_plot: false
   dfs_to_use: []
   levels: []
 
-plot_relative_std_settings:
+plot_venn_groups_settings:
   create_plot: false
   dfs_to_use: []
   levels: []
 
-plot_rank_settings:
+plot_pca_overview_settings:
   create_plot: false
   dfs_to_use: []
   levels: []
+  no_missing_values: true      # should missing values be neglected? (can be "true" or "false")
 
-plot_pathway_analysis_settings:
+plot_intensity_histograms_settings:
   create_plot: false
   dfs_to_use: []
   levels: []
 
-plot_scatter_replicates_settings:
+plot_relative_std_settings:
   create_plot: false
   dfs_to_use: []
   levels: []
 
-plot_experiment_comparison_settings:
+plot_scatter_replicates_settings:
   create_plot: false
   dfs_to_use: []
   levels: []
 
-plot_go_analysis_settings:
+plot_experiment_comparison_settings:
   create_plot: false
   dfs_to_use: []
   levels: []
 
-plot_venn_results_settings:
+plot_rank_settings:
   create_plot: false
   dfs_to_use: []
   levels: []
 
-plot_r_volcano_settings:
+plot_pathway_analysis_settings:
   create_plot: false
   dfs_to_use: []
   levels: []
-  adj_pval: false
-  fchange_threshold: 2
 
-
-plot_venn_groups_settings:
+plot_go_analysis_settings:
   create_plot: false
   dfs_to_use: []
   levels: []
 
-plot_pca_overview_settings:
+plot_r_volcano_settings:
   create_plot: false
   dfs_to_use: []
   levels: []
-  no_missing_values: true
-  fill_na_before_norm: false
-  fill_value:  0
-
-
-use_protein_id: false
-# should the protein id be used, or TODO
-# can be "true" or "false"
+  adj_pval: false # should the adjusted p-val be used? (can be "true" or "false")
 
-equal_variance: false
-# should equal variance be assumed for the t-test?
-# can be "true" or "false"
diff --git a/mspypeline/config/pathways/CUSTOM_AXL_PATHWAY.txt b/mspypeline/config/pathways/CUSTOM_AXL_PATHWAY.txt
deleted file mode 100644
index bd6fcd1..0000000
--- a/mspypeline/config/pathways/CUSTOM_AXL_PATHWAY.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-Gas6
-UFO
-AXL
-GRB2
-ERK1
-ERK2
-PI3K
-MAPK14
-MAPK11
-MAPK12
-MAPK13
-HSP25
-AKT
-CASP3
-S6K
-BAD
-NFKB
-SHP2STAT1
-SOCS1
-SOCS3
-TWIST1
diff --git a/mspypeline/config/pathways/GO_APOPTOTIC_SIGNALING_PATHWAY.txt b/mspypeline/config/pathways/GO_APOPTOTIC_SIGNALING_PATHWAY.txt
deleted file mode 100644
index af9d5c0..0000000
--- a/mspypeline/config/pathways/GO_APOPTOTIC_SIGNALING_PATHWAY.txt
+++ /dev/null
@@ -1,597 +0,0 @@
-GO_APOPTOTIC_SIGNALING_PATHWAY
-> A series of molecular signals which triggers the apoptotic death of a cell. The pathway starts with reception of a signal, and ends when the execution phase of apoptosis is triggered. [GOC:mtg_apoptosis]
-ABL1
-AC005840.1
-AC074143.1
-ACAA2
-ACKR3
-ACVR1
-ACVR1B
-ADORA1
-ADORA2A
-AEN
-AGT
-AGTR2
-AIFM1
-AKT1
-ANKRD2
-ANXA6
-APAF1
-APOPT1
-APPL1
-AR
-ARHGEF2
-ARL6IP5
-ARRB2
-ASAH2
-ATAD5
-ATF3
-ATF4
-ATM
-ATP2A1
-ATP5IF1
-AVP
-BAD
-BAG3
-BAG5
-BAG6
-BAK1
-BAX
-BBC3
-BCAP31
-BCL10
-BCL2
-BCL2A1
-BCL2L1
-BCL2L10
-BCL2L11
-BCL2L12
-BCL2L2
-BCL3
-BCLAF1
-BDKRB2
-BEX3
-BID
-BIK
-BIRC6
-BLOC1S2
-BMF
-BMP4
-BMP5
-BMPR1B
-BNIP3
-BNIP3L
-BOK
-BRCA1
-BRCA2
-BRSK2
-BTK
-CAAP1
-CASP1
-CASP10
-CASP12
-CASP14
-CASP2
-CASP3
-CASP4
-CASP5
-CASP8
-CASP8AP2
-CASP9
-CAV1
-CCAR2
-CCK
-CD14
-CD24
-CD27
-CD28
-CD38
-CD3E
-CD44
-CD5
-CD70
-CD74
-CDIP1
-CDKN1A
-CDKN2D
-CEBPB
-CFLAR
-CHAC1
-CHCHD10
-CHEK2
-CIB1
-CIDEB
-CLU
-COL2A1
-CRADD
-CREB3
-CREB3L1
-CRH
-CRIP1
-CSF2
-CSNK2A1
-CSNK2A2
-CTH
-CTNNA1
-CTNNB1
-CTSC
-CTSH
-CTTN
-CUL1
-CUL2
-CUL3
-CUL4A
-CUL5
-CX3CL1
-CX3CR1
-CXCL12
-CYLD
-CYP1B1
-DAB2IP
-DAP
-DAP3
-DAPK1
-DAPK2
-DAPK3
-DAPL1
-DAXX
-DBH
-DCC
-DDIAS
-DDIT3
-DDIT4
-DDX3X
-DDX47
-DDX5
-DEDD
-DEDD2
-DELE1
-DEPTOR
-DIABLO
-DIDO1
-DNAJA1
-DNAJC10
-DNM1L
-DPF2
-DYRK2
-E2F1
-E2F2
-EDA2R
-EIF2AK3
-ELL3
-ENO1
-EP300
-EPHA2
-EPO
-ERBB3
-ERCC6
-ERN1
-ERN2
-ERO1A
-ERP29
-EYA1
-EYA2
-EYA3
-EYA4
-FADD
-FAF1
-FAIM2
-FAM162A
-FAS
-FASLG
-FASTK
-FBH1
-FBXW7
-FEM1B
-FGA
-FGB
-FGF10
-FGFR1
-FGFR3
-FGG
-FHIT
-FIGNL1
-FIS1
-FLCN
-FNIP2
-FOXO3
-FXN
-FYN
-FZD9
-G0S2
-GABARAP
-GATA1
-GCLC
-GCLM
-GDNF
-GFRAL
-GGCT
-GNAI2
-GNAI3
-GPER1
-GPX1
-GRINA
-GSDME
-GSK3A
-GSK3B
-GSKIP
-GSN
-GSTP1
-GZMB
-GZMH
-HDAC1
-HERPUD1
-HGF
-HIC1
-HIF1A
-HIGD1A
-HINT1
-HIP1
-HIP1R
-HIPK1
-HIPK2
-HMGB2
-HMOX1
-HNRNPK
-HRAS
-HRK
-HSPA1A
-HSPA1B
-HSPB1
-HTRA2
-HTT
-HYAL2
-HYOU1
-ICAM1
-IFI16
-IFI27
-IFI6
-IFNB1
-IFNG
-IGF1
-IKBKE
-IL12A
-IL19
-IL1A
-IL1B
-IL2
-IL20RA
-IL33
-IL6R
-IL7
-INCA1
-ING2
-ING5
-INHBA
-INHBB
-INS
-ITGA6
-ITGAM
-ITGAV
-ITM2C
-ITPR1
-IVNS1ABP
-JAK2
-JMY
-JUN
-KDM1A
-KITLG
-KRT18
-KRT8
-LAMP1
-LCK
-LCN2
-LGALS12
-LGALS3
-LGALS9
-LMNA
-LRRK2
-LY96
-MADD
-MAEL
-MAGEA3
-MAGED1
-MAL
-MAP2K5
-MAP3K5
-MAPK7
-MAPK8
-MAPK8IP1
-MAPK8IP2
-MAPK9
-MARCH7
-MAZ
-MCL1
-MDM2
-MEIS3
-MELK
-METTL21C
-MFF
-MIF
-MIR15A
-MIR16-1
-MIR16-2
-MIR17
-MIR21
-MIR221
-MIR222
-MIR449A
-MKNK2
-MLH1
-MLLT11
-MMP9
-MNT
-MOAP1
-MPV17L
-MSH2
-MSH6
-MSX1
-MUC1
-MUL1
-MYBBP1A
-NACC2
-NANOS3
-NBN
-NCK1
-NCK2
-NDUFA13
-NDUFS3
-NF1
-NFATC4
-NFE2L2
-NGF
-NKX3-1
-NLE1
-NME5
-NMT1
-NOC2L
-NOG
-NONO
-NOS3
-NOX1
-NR4A2
-NRP1
-NUPR1
-OPA1
-P2RX4
-P2RX7
-P4HB
-PAK2
-PAK5
-PAM16
-PARK7
-PARP1
-PARP2
-PAWR
-PCGF2
-PDCD10
-PDCD5
-PDCD6
-PDIA3
-PDK1
-PDK2
-PDPK1
-PDX1
-PEA15
-PELI3
-PERP
-PF4
-PHIP
-PHLDA3
-PIAS4
-PIDD1
-PIH1D1
-PIK3R1
-PINK1
-PLA2G6
-PLAGL2
-PLAUR
-PLEKHF1
-PMAIP1
-PML
-POLB
-POU4F1
-POU4F2
-PPARD
-PPIF
-PPM1F
-PPP1CA
-PPP1R13B
-PPP1R15A
-PPP2R1A
-PPP2R1B
-PPP3CC
-PPP3R1
-PRDX2
-PRELID1
-PRKCA
-PRKCD
-PRKDC
-PRKN
-PRKRA
-PRODH
-PRR7
-PSEN1
-PSMD10
-PSME3
-PTEN
-PTGIS
-PTGS2
-PTH
-PTPMT1
-PTPN1
-PTPN2
-PTPRC
-PTTG1IP
-PYCARD
-QARS
-RACK1
-RAD9A
-RAF1
-RB1CC1
-RBCK1
-RELA
-RET
-RFFL
-RHOT1
-RHOT2
-RIPK1
-RIPK3
-RNF183
-RNF186
-RNF34
-RNF41
-RPL11
-RPL26
-RPS27L
-RPS3
-RPS6KB1
-RPS7
-RRM2B
-RRN3
-RRP8
-RTKN2
-RTL10
-S100A8
-S100A9
-SCG2
-SCN2A
-SCRT2
-SELENOK
-SELENOS
-SENP1
-SEPT4
-SERINC3
-SERPINE1
-SFN
-SFPQ
-SFRP1
-SFRP2
-SGK3
-SGMS1
-SGPL1
-SGPP1
-SH3RF1
-SHH
-SHISA5
-SIAH1
-SIAH2
-SIRT1
-SIVA1
-SKIL
-SLC25A5
-SLC35F6
-SLC9A3R1
-SMAD3
-SNAI1
-SNAI2
-SNW1
-SOD1
-SOD2
-SORT1
-SP100
-SRC
-SRGN
-SRPX
-SST
-SSTR3
-ST18
-ST20
-STK11
-STK24
-STK25
-STK3
-STK4
-STRADB
-STX4
-STYXL1
-SYVN1
-TAF9
-TAF9B
-TCF7L2
-TERT
-TFAP4
-TFDP1
-TFDP2
-TFPT
-TGFB1
-TGFB2
-TGFBR1
-THBS1
-TICAM1
-TICAM2
-TIMM50
-TIMP3
-TLR3
-TLR4
-TM2D1
-TMBIM1
-TMBIM6
-TMC8
-TMEM102
-TMEM109
-TMEM117
-TMEM14A
-TMEM161A
-TNF
-TNFAIP3
-TNFRSF10A
-TNFRSF10B
-TNFRSF10C
-TNFRSF12A
-TNFRSF1A
-TNFRSF1B
-TNFRSF25
-TNFRSF4
-TNFSF10
-TNFSF12
-TOPORS
-TP53
-TP53BP2
-TP63
-TP73
-TPD52L1
-TPT1
-TRADD
-TRAF1
-TRAF2
-TRAF7
-TRAP1
-TRIAP1
-TRIB3
-TRIM32
-TRIM39
-TXNDC12
-TYROBP
-UACA
-UBB
-UBE2K
-UBE4B
-UBQLN1
-UNC5B
-URI1
-USP28
-USP47
-VDAC2
-VNN1
-WDR35
-WFS1
-WNT4
-WWOX
-XBP1
-XPA
-YAP1
-YBX3
-YWHAB
-YWHAE
-YWHAG
-YWHAH
-YWHAQ
-YWHAZ
-ZC3HC1
-ZMYND11
-ZNF205
-ZNF385A
-ZNF385B
-ZNF622
-ZSWIM2
\ No newline at end of file
diff --git a/mspypeline/config/pathways/GO_CYTOKINE_PRODUCTION.txt b/mspypeline/config/pathways/GO_CYTOKINE_PRODUCTION.txt
deleted file mode 100644
index 429095e..0000000
--- a/mspypeline/config/pathways/GO_CYTOKINE_PRODUCTION.txt
+++ /dev/null
@@ -1,761 +0,0 @@
-GO_CYTOKINE_PRODUCTION
-> The appearance of a cytokine due to biosynthesis or secretion following a cellular stimulus, resulting in an increase in its intracellular or extracellular levels. [GOC:add, ISBN:0781735149]
-ABCA1
-ABCC8
-ABCD1
-ABCD2
-ABL1
-AC129492.1
-ACE2
-ACKR1
-ACOD1
-ACP5
-ADAM17
-ADAM8
-ADAMTS3
-ADCY7
-ADCYAP1
-ADGRG1
-ADIPOQ
-ADORA2B
-ADRA2A
-AFAP1L2
-AGER
-AGPAT1
-AGPAT2
-AGT
-AGTR2
-AIF1
-AIM2
-AIRE
-AKAP8
-AKIRIN2
-ALOX15B
-ANGPT1
-ANKRD17
-ANKRD2
-ANXA1
-ANXA4
-APOA1
-APOA2
-APOD
-APP
-APPL1
-APPL2
-ARFGEF2
-ARG1
-ARG2
-ARHGEF2
-ARNT
-ARRB1
-ARRB2
-ASB1
-ASH1L
-ATF2
-ATF4
-ATG5
-ATP6AP2
-AVPR2
-AXL
-AZI2
-AZU1
-B2M
-BANK1
-BAP1
-BATF
-BCL10
-BCL3
-BCL6
-BIRC2
-BIRC3
-BPI
-BRCA1
-BST2
-BTK
-BTN2A2
-BTN3A1
-BTN3A2
-C1QBP
-C1QTNF3
-C1QTNF4
-C3
-C3AR1
-C5
-C5AR1
-C5AR2
-C5orf30
-CACTIN
-CADM1
-CAPN2
-CARD11
-CARD16
-CARD17
-CARD18
-CARD8
-CARD9
-CASP1
-CCBE1
-CCDC88B
-CCL1
-CCL19
-CCL3
-CCM2L
-CCR2
-CCR7
-CD14
-CD160
-CD2
-CD200
-CD200R1
-CD226
-CD24
-CD244
-CD247
-CD274
-CD276
-CD28
-CD2AP
-CD300H
-CD34
-CD36
-CD3E
-CD4
-CD40
-CD40LG
-CD46
-CD47
-CD55
-CD58
-CD6
-CD74
-CD80
-CD83
-CD84
-CD86
-CD96
-CDH3
-CEACAM1
-CEACAM20
-CEBPB
-CEBPE
-CEBPG
-CGAS
-CHGA
-CHI3L1
-CHIA
-CHID1
-CHRNA7
-CHUK
-CIDEA
-CLC
-CLEC4A
-CLEC4E
-CLEC5A
-CLEC6A
-CLEC9A
-CLECL1
-CLU
-CMA1
-CMKLR1
-CPTP
-CRCP
-CREB1
-CREBBP
-CRLF2
-CRP
-CRTAM
-CRYBA1
-CSF1R
-CSF2
-CSK
-CTNNB1
-CUEDC2
-CX3CL1
-CX3CR1
-CXCL17
-CXCL6
-CYBA
-CYBB
-CYLD
-CYP1B1
-DBH
-DDIT3
-DDT
-DDX1
-DDX21
-DDX3X
-DDX41
-DDX58
-DDX60
-DEFB114
-DENND1B
-DHX33
-DHX36
-DHX58
-DHX9
-DICER1
-DLG1
-DLL1
-DRD2
-DTX4
-DYSF
-EBI3
-EGR1
-EIF2AK2
-EIF2AK3
-ELANE
-ELF1
-EOMES
-EP300
-EPHA2
-EPX
-ERBIN
-EREG
-ERRFI1
-EZR
-F11R
-F2
-F2R
-F2RL1
-FABP4
-FADD
-FAM49B
-FCER1G
-FCGR2B
-FCN1
-FERMT1
-FFAR2
-FFAR3
-FFAR4
-FGFR1
-FGR
-FLOT1
-FLT4
-FN1
-FOXJ1
-FOXP1
-FOXP3
-FURIN
-FZD5
-GAPDH
-GAS6
-GATA3
-GATA4
-GATA6
-GBA
-GBP1
-GBP5
-GDF2
-GHRL
-GHSR
-GLMN
-GPAM
-GPATCH3
-GPNMB
-GPR18
-GPRC5B
-GPSM3
-GSDMD
-GSTP1
-HAVCR2
-HDAC2
-HDAC7
-HDAC9
-HEG1
-HERC5
-HFE
-HGF
-HHLA2
-HIF1A
-HILPDA
-HK1
-HLA-DPA1
-HLA-DPB1
-HLA-E
-HLA-F
-HLA-G
-HMGB1
-HMGB2
-HMGB4
-HMHB1
-HMOX1
-HOMER2
-HOMER3
-HPSE
-HRAS
-HSF1
-HSP90AB1
-HSPA1A
-HSPA1B
-HSPB1
-HSPD1
-HTR2B
-HYAL2
-IDO1
-IFI16
-IFIH1
-IFNA2
-IFNB1
-IFNG
-IFNL1
-IGF1
-IGF2BP1
-IGF2BP2
-IGF2BP3
-IGHD
-IKBKE
-IL10
-IL12A
-IL12B
-IL12RB1
-IL12RB2
-IL13
-IL15
-IL17A
-IL17B
-IL17D
-IL17F
-IL17RA
-IL17RB
-IL17RC
-IL18
-IL18R1
-IL18RAP
-IL19
-IL1A
-IL1B
-IL1F10
-IL1R1
-IL1R2
-IL1RAP
-IL1RL1
-IL1RL2
-IL1RN
-IL2
-IL20RB
-IL21
-IL23A
-IL23R
-IL25
-IL26
-IL27
-IL27RA
-IL31RA
-IL33
-IL36A
-IL36B
-IL36G
-IL36RN
-IL37
-IL4
-IL4R
-IL5RA
-IL6
-IL6R
-IL6ST
-IL7
-IL9
-INAVA
-INHA
-INHBA
-INHBB
-INPP5D
-INS
-IQGAP1
-IRAK1
-IRAK3
-IRAK4
-IRF1
-IRF3
-IRF4
-IRF5
-IRF7
-IRF8
-ISG15
-ISL1
-ITCH
-ITGAV
-ITGB6
-ITGB8
-ITK
-JAK2
-JAK3
-JPH4
-KARS
-KAT2A
-KAT5
-KDELR1
-KIR2DL4
-KIT
-KLF2
-KLF4
-KLRC4-KLRK1
-KLRF2
-KLRK1
-LAG3
-LAPTM4B
-LBP
-LCP2
-LEF1
-LEP
-LGALS9
-LGR4
-LILRA2
-LILRA4
-LILRA5
-LILRB1
-LILRB2
-LIPA
-LITAF
-LPL
-LRP1
-LRRC32
-LRRFIP1
-LRRK2
-LSM14A
-LTA
-LTB
-LTBP1
-LTBP3
-LTF
-LUM
-LURAP1
-LY9
-LY96
-LYN
-MAF
-MALT1
-MAP2K3
-MAP2K5
-MAP3K7
-MAPK11
-MAPK13
-MAPK14
-MAPK3
-MAPKAPK2
-MAPKBP1
-MAST2
-MAVS
-MBP
-MC1R
-MCOLN2
-MEFV
-MERTK
-MIF
-MIR125B1
-MIR125B2
-MIR130A
-MIR146B
-MIR155
-MIR16-1
-MIR16-2
-MIR17
-MIR182
-MIR200C
-MIR206
-MIR20A
-MIR21
-MIR221
-MIR222
-MIR24-1
-MIR24-2
-MIR590
-MIR92A1
-MIR92A2
-MIRLET7F1
-MIRLET7F2
-MMP12
-MMP8
-MR1
-MRE11
-MUL1
-MYB
-MYD88
-NAV3
-NCKAP1L
-NDFIP1
-NDRG2
-NFAM1
-NFAT5
-NFATC1
-NFATC2
-NFATC2IP
-NFATC3
-NFATC4
-NFKB1
-NFKB2
-NFKBIL1
-NLRC3
-NLRC4
-NLRC5
-NLRP1
-NLRP10
-NLRP12
-NLRP2
-NLRP3
-NLRP4
-NLRP7
-NLRP9
-NLRX1
-NMI
-NOD1
-NOD2
-NODAL
-NOP53
-NOS2
-NOTCH1
-NOX1
-NOX5
-NPLOC4
-NR1H4
-NR4A3
-NRROS
-ORM1
-ORM2
-OSM
-OTUD5
-OTUD7B
-P2RX7
-PAEP
-PANX1
-PANX2
-PANX3
-PARK7
-PAWR
-PCBP2
-PCSK5
-PDCD1LG2
-PDCD4
-PDE4B
-PDE4D
-PELI1
-PF4
-PGLYRP1
-PGLYRP2
-PGLYRP3
-PGLYRP4
-PIBF1
-PIK3CD
-PIK3CG
-PIK3R1
-PIN1
-PLA2G1B
-PLA2R1
-PLCB1
-PLCG2
-PML
-PNP
-POLR1C
-POLR2E
-POLR2F
-POLR2H
-POLR2K
-POLR2L
-POLR3A
-POLR3B
-POLR3C
-POLR3D
-POLR3E
-POLR3F
-POLR3G
-POLR3GL
-POLR3H
-POLR3K
-POMC
-POSTN
-PPM1B
-PPP1R11
-PQBP1
-PRG3
-PRKCD
-PRKCQ
-PRKCZ
-PRKD2
-PRKDC
-PRNP
-PTAFR
-PTGER4
-PTGS2
-PTPN11
-PTPN22
-PTPN6
-PTPRC
-PTPRJ
-PTPRS
-PUM1
-PUM2
-PYCARD
-PYDC1
-PYDC2
-RAB1A
-RAB7B
-RAC1
-RAET1G
-RARA
-RASGRP1
-RBPJ
-REL
-RELA
-RELB
-RFTN1
-RGCC
-RIOK3
-RIPK1
-RIPK2
-RIPK3
-RNF125
-RNF128
-RNF135
-RNF216
-RNF26
-ROCK2
-RORA
-RPS3
-RPS6KA4
-RPS6KA5
-RSAD2
-RUNX1
-S100A12
-S100A13
-S100A8
-S100A9
-S1PR3
-SAA1
-SARS
-SASH3
-SCAMP5
-SCGB1A1
-SEC14L1
-SEH1L
-SELENOK
-SELENOS
-SEMA7A
-SERPINB7
-SERPINE1
-SERPINF2
-SETD2
-SFTPD
-SIGIRR
-SIGLEC16
-SIRPA
-SIRT1
-SLAMF1
-SLAMF6
-SLC11A1
-SMAD3
-SMAD4
-SMAD7
-SNAI2
-SOCS1
-SOCS5
-SOD1
-SPHK1
-SPN
-SPON2
-SPTBN1
-SRC
-SRGN
-SSC5D
-STAT1
-STAT3
-STAT5B
-STAT6
-STOML2
-SUCNR1
-SULF1
-SULF2
-SYK
-SYT11
-TAX1BP1
-TBC1D23
-TBK1
-TBX21
-TGFB1
-TGFB2
-TGFB3
-THBS1
-TIA1
-TICAM1
-TIGIT
-TIRAP
-TKFC
-TLR1
-TLR10
-TLR2
-TLR3
-TLR4
-TLR5
-TLR6
-TLR7
-TLR8
-TLR9
-TMEM173
-TMF1
-TMIGD2
-TMSB4X
-TNF
-TNFAIP3
-TNFRSF13C
-TNFRSF14
-TNFRSF1B
-TNFRSF21
-TNFRSF4
-TNFRSF8
-TNFSF4
-TRAF2
-TRAF3
-TRAF3IP1
-TRAF6
-TRAIP
-TREM2
-TREX1
-TRIB2
-TRIL
-TRIM15
-TRIM16
-TRIM21
-TRIM25
-TRIM27
-TRIM32
-TRIM38
-TRIM56
-TRIM6
-TRPM4
-TRPV4
-TSLP
-TSPAN6
-TSPO
-TUSC2
-TWIST1
-TWSG1
-TXK
-TYROBP
-UBA7
-UBASH3A
-UBE2J1
-UBE2L6
-UCN
-UFD1
-USP17L2
-USP50
-VSIG4
-VSIR
-VTCN1
-WNT11
-WNT3A
-WNT5A
-XBP1
-XCL1
-XRCC5
-XRCC6
-YY1
-ZBP1
-ZBTB20
-ZBTB7B
-ZC3H12A
-ZCCHC3
-ZFP36
-ZFPM1
-ZNF287
-ZNF580
-ZP3
\ No newline at end of file
diff --git a/mspypeline/config/pathways/GO_INFLAMMATORY_RESPONSE.txt b/mspypeline/config/pathways/GO_INFLAMMATORY_RESPONSE.txt
deleted file mode 100644
index f4566f0..0000000
--- a/mspypeline/config/pathways/GO_INFLAMMATORY_RESPONSE.txt
+++ /dev/null
@@ -1,724 +0,0 @@
-GO_INFLAMMATORY_RESPONSE
-> The immediate defensive reaction (by vertebrate tissue) to infection or injury caused by chemical or physical agents. The process is characterized by local vasodilation, extravasation of plasma into intercellular spaces and accumulation of white blood cells and macrophages. [GO_REF:0000022, GOC:mtg_15nov05, ISBN:0198506732]
-ABCD1
-ABCD2
-ABCF1
-ABR
-AC129492.1
-ACE2
-ACER3
-ACKR1
-ACKR2
-ACOD1
-ACP5
-ACVR1
-ADA
-ADAM8
-ADAMTS12
-ADCY1
-ADCY7
-ADCY8
-ADCYAP1
-ADGRE2
-ADGRE5
-ADIPOQ
-ADM
-ADORA1
-ADORA2A
-ADORA2B
-ADORA3
-AFAP1L2
-AGER
-AGT
-AGTR1
-AGTR2
-AHCY
-AHSG
-AIF1
-AIM2
-AIMP1
-AKT1
-ALOX15
-ALOX5
-ANO6
-ANXA1
-AOC3
-APCS
-APOA1
-APOA2
-APOD
-APOE
-APOL2
-APOL3
-APP
-APPL1
-APPL2
-ASH1L
-ASS1
-ATM
-ATRN
-AXL
-AZU1
-B4GALT1
-BACE2
-BAP1
-BCL6
-BCR
-BDKRB1
-BDKRB2
-BIRC2
-BIRC3
-BLNK
-BMP2
-BMP6
-BMPR1B
-BRD4
-BST1
-BTK
-C1QA
-C1QTNF12
-C1QTNF3
-C2CD4A
-C2CD4B
-C3
-C3AR1
-C4A
-C4B
-C5
-C5AR1
-C5AR2
-C5orf30
-CALCA
-CALCRL
-CAMK1D
-CAMK4
-CARD18
-CASP4
-CCL1
-CCL11
-CCL13
-CCL14
-CCL15
-CCL16
-CCL17
-CCL18
-CCL19
-CCL2
-CCL20
-CCL21
-CCL22
-CCL23
-CCL24
-CCL25
-CCL26
-CCL3
-CCL3L1
-CCL3L3
-CCL4
-CCL5
-CCL7
-CCL8
-CCN3
-CCR1
-CCR2
-CCR3
-CCR4
-CCR5
-CCR6
-CCR7
-CCRL2
-CD14
-CD163
-CD180
-CD200
-CD200R1
-CD200R1L
-CD28
-CD36
-CD40
-CD40LG
-CD44
-CD47
-CD5L
-CD6
-CD68
-CD96
-CDH5
-CDK19
-CDO1
-CEBPA
-CEBPB
-CELA1
-CHI3L1
-CHIA
-CHID1
-CHST1
-CHST2
-CHST4
-CHUK
-CIITA
-CLEC7A
-CLOCK
-CLU
-CMA1
-CMKLR1
-CNR1
-CNR2
-CNTF
-CREB3L3
-CRH
-CRHBP
-CRP
-CSF1
-CSF1R
-CTNNBIP1
-CUEDC2
-CX3CL1
-CXCL1
-CXCL10
-CXCL11
-CXCL13
-CXCL17
-CXCL2
-CXCL3
-CXCL5
-CXCL6
-CXCL8
-CXCL9
-CXCR2
-CXCR3
-CXCR4
-CXCR6
-CYBA
-CYBB
-CYLD
-CYP19A1
-CYP26B1
-CYP4F11
-CYSLTR1
-DAB2IP
-DDT
-DEFB114
-DHX9
-DNASE1
-DNASE1L3
-DROSHA
-DUOXA1
-DUOXA2
-DUSP10
-ECM1
-EDNRB
-EGFR
-EIF2AK1
-ELANE
-ELF3
-ENPP3
-EPHA2
-EPHX2
-EPO
-ESR1
-ETS1
-F11R
-F12
-F2
-F2R
-F2RL1
-F3
-F8
-FABP4
-FANCA
-FANCD2
-FCER1G
-FCGR2B
-FEM1A
-FFAR2
-FFAR3
-FFAR4
-FN1
-FNDC4
-FOLR2
-FOS
-FOXF1
-FOXP1
-FOXP3
-FPR1
-FPR2
-FPR3
-GAL
-GATA3
-GBA
-GBP5
-GGT1
-GGT2
-GGT3P
-GGT5
-GHRL
-GHSR
-GPER1
-GPR17
-GPR32
-GPR32P1
-GPR33
-GPR68
-GPRC5B
-GPS2
-GPSM3
-GPX1
-GPX4
-GRN
-GSDMD
-GSTP1
-HAMP
-HAVCR2
-HCK
-HDAC4
-HDAC5
-HDAC9
-HFE
-HGF
-HIF1A
-HIST1H2BA
-HLA-E
-HMGB1
-HMGB2
-HMOX1
-HNRNPA0
-HP
-HPR
-HRH1
-HRH4
-HSPG2
-HYAL1
-HYAL2
-HYAL3
-ICAM1
-IDO1
-IFI16
-IFNA2
-IGF1
-IGFBP4
-IKBKB
-IKBKG
-IL10
-IL10RB
-IL12B
-IL13
-IL15
-IL17A
-IL17B
-IL17C
-IL17D
-IL17F
-IL17RA
-IL17RB
-IL17RC
-IL17RE
-IL18
-IL18R1
-IL18RAP
-IL1A
-IL1B
-IL1F10
-IL1R1
-IL1R2
-IL1RAP
-IL1RL1
-IL1RL2
-IL1RN
-IL2
-IL20
-IL20RB
-IL21
-IL22
-IL22RA2
-IL23A
-IL23R
-IL25
-IL27
-IL2RA
-IL31RA
-IL33
-IL34
-IL36A
-IL36B
-IL36G
-IL36RN
-IL37
-IL4
-IL4R
-IL5
-IL5RA
-IL6
-IL6R
-IL6ST
-IL9
-INS
-IRAK2
-IRF3
-IRGM
-ISL1
-ITCH
-ITGA2
-ITGAL
-ITGAM
-ITGB2
-ITGB6
-ITIH4
-JAK2
-JAM3
-JUN
-KARS
-KDM6B
-KIT
-KLF4
-KLKB1
-KLRG1
-KNG1
-KRT1
-KRT16
-LAT
-LBP
-LDLR
-LEP
-LGALS9
-LIAS
-LILRA5
-LIPA
-LOXL3
-LPL
-LRFN5
-LRP1
-LRRK2
-LTA
-LTB4R
-LTB4R2
-LXN
-LY75
-LY86
-LY96
-LYN
-LYZ
-MAP2K3
-MAPK13
-MAPK14
-MAPK7
-MAPKAPK2
-MAPT
-MAS1
-MBL2
-MCPH1
-MEFV
-MEP1B
-METRNL
-MFHAS1
-MGLL
-MGST2
-MIF
-MIR124-1
-MIR124-2
-MIR124-3
-MIR126
-MIR128-1
-MIR128-2
-MIR141
-MIR142
-MIR149
-MIR155
-MIR15A
-MIR16-1
-MIR16-2
-MIR17
-MIR181B1
-MIR181B2
-MIR181C
-MIR187
-MIR206
-MIR20A
-MIR21
-MIR22
-MIR221
-MIR222
-MIR223
-MIR30C2
-MIR31
-MIR590
-MIR92A1
-MIR92A2
-MIRLET7G
-MMP25
-MMP26
-MMP3
-MMP8
-MMP9
-MRGPRX1
-MS4A2
-MVK
-MYD88
-MYLK3
-NAIP
-NAMPT
-NAPEPLD
-NCR3
-NDFIP1
-NDST1
-NFAM1
-NFATC3
-NFATC4
-NFE2L1
-NFE2L2
-NFKB1
-NFKBIA
-NFKBID
-NFKBIZ
-NFRKB
-NFX1
-NLRC3
-NLRC4
-NLRP1
-NLRP10
-NLRP12
-NLRP2
-NLRP3
-NLRP4
-NLRP6
-NLRP7
-NLRP9
-NLRX1
-NMI
-NOD1
-NOD2
-NOS2
-NOTCH1
-NOX1
-NOX4
-NPFF
-NPPA
-NPY5R
-NR1D2
-NR1H3
-NR1H4
-NRROS
-NT5E
-NUPR1
-ODAM
-OGG1
-OLR1
-OPRM1
-ORM1
-ORM2
-OSM
-OSMR
-OTULIN
-P2RX1
-P2RX7
-PARK7
-PARP4
-PBK
-PDCD4
-PDE2A
-PF4
-PF4V1
-PGLYRP1
-PGLYRP2
-PIK3AP1
-PIK3CD
-PIK3CG
-PJA2
-PLA2G2A
-PLA2G2D
-PLA2G2E
-PLA2G4B
-PLA2G4C
-PLA2G5
-PLA2G7
-PLAA
-PLGRKT
-PLP1
-PLSCR1
-PNMA1
-POLB
-PPARA
-PPARD
-PPARG
-PPBP
-PRCP
-PRDX2
-PRDX5
-PRKCD
-PRKCQ
-PRKCZ
-PRKD1
-PROC
-PROK2
-PSEN1
-PSMA1
-PSMA6
-PSMB4
-PSTPIP1
-PTAFR
-PTGDR
-PTGER1
-PTGER2
-PTGER3
-PTGER4
-PTGES
-PTGFR
-PTGIR
-PTGIS
-PTGS1
-PTGS2
-PTPN2
-PTPRC
-PTX3
-PXK
-PYCARD
-PYDC2
-RAC1
-RARRES2
-RASGRP1
-RB1
-RBPJ
-REG3A
-REG3G
-REL
-RELA
-RELB
-RHBDD3
-RICTOR
-RIPK2
-RORA
-RPS19
-RPS6KA4
-RPS6KA5
-S100A12
-S100A8
-S100A9
-S1PR3
-SAA1
-SAA2
-SAA4
-SBNO2
-SCG2
-SCGB1A1
-SCN9A
-SCUBE1
-SDC1
-SEH1L
-SELE
-SELENOS
-SELP
-SEMA7A
-SERPINA1
-SERPINA3
-SERPINC1
-SERPINE1
-SERPINF1
-SERPINF2
-SETD6
-SGMS1
-SHARPIN
-SHPK
-SIGIRR
-SIGLEC1
-SIGLEC10
-SIRPA
-SLAMF8
-SLC11A1
-SLC7A2
-SMAD1
-SMAD3
-SMO
-SMPDL3B
-SNAP23
-SNCA
-SNX4
-SOCS3
-SOCS5
-SOD1
-SPATA2
-SPHK1
-SPP1
-STAB1
-STAP1
-STAT3
-STAT5B
-STK39
-SUCNR1
-SYK
-TAC1
-TAC4
-TACR1
-TAFA3
-TBC1D23
-TBK1
-TBXA2R
-TEK
-TFR2
-TGFB1
-TGM2
-THBS1
-THEMIS2
-TICAM1
-TICAM2
-TIMP1
-TIRAP
-TLR1
-TLR10
-TLR2
-TLR3
-TLR4
-TLR5
-TLR6
-TLR7
-TLR8
-TLR9
-TMEM173
-TMIGD3
-TMSB4X
-TNF
-TNFAIP3
-TNFAIP6
-TNFAIP8L2
-TNFRSF11A
-TNFRSF1A
-TNFRSF1B
-TNFRSF4
-TNFSF11
-TNFSF4
-TNIP1
-TNIP2
-TNIP3
-TOLLIP
-TPST1
-TRADD
-TREM1
-TREM2
-TREX1
-TRIL
-TRPV1
-TRPV4
-TSLP
-TSPAN2
-TTBK1
-TUSC2
-TYRO3
-TYROBP
-UCN
-UGT1A1
-UNC13D
-USP18
-VAMP7
-VAMP8
-VCAM1
-VNN1
-VPS35
-WFDC1
-WNT5A
-XCL1
-XCL2
-XCR1
-XIAP
-ZC3H12A
-ZNF580
-ZP3
-ZYX
\ No newline at end of file
diff --git a/mspypeline/config/pathways/GO_NEGATIVE_REGULATION_OF_INFLAMMATORY_RESPONSE.txt b/mspypeline/config/pathways/GO_NEGATIVE_REGULATION_OF_INFLAMMATORY_RESPONSE.txt
deleted file mode 100644
index 35e1a2b..0000000
--- a/mspypeline/config/pathways/GO_NEGATIVE_REGULATION_OF_INFLAMMATORY_RESPONSE.txt
+++ /dev/null
@@ -1,158 +0,0 @@
-GO_NEGATIVE_REGULATION_OF_INFLAMMATORY_RESPONSE
-> Any process that stops, prevents, or reduces the frequency, rate or extent of the inflammatory response. [GOC:ai]
-ABCD1
-ABCD2
-ABR
-ACOD1
-ACP5
-ADA
-ADCY7
-ADCYAP1
-ADIPOQ
-ADORA1
-ADORA2A
-AGER
-APCS
-APOA1
-APOD
-APOE
-APPL2
-ASH1L
-BCR
-C1QTNF12
-C1QTNF3
-C5orf30
-CALCRL
-CCN3
-CD200
-CD200R1
-CDH5
-CHID1
-CNR2
-CUEDC2
-CX3CL1
-CXCL17
-CYP19A1
-DUSP10
-ELANE
-ENPP3
-ETS1
-F2
-FCGR2B
-FEM1A
-FFAR4
-FNDC4
-FOXF1
-FOXP3
-GATA3
-GBA
-GHRL
-GHSR
-GPER1
-GPR17
-GPS2
-GPX1
-GRN
-GSTP1
-HGF
-IGF1
-IL10
-IL12B
-IL1R2
-IL2
-IL20RB
-IL22RA2
-IL2RA
-IL4
-INS
-ISL1
-KLF4
-KRT1
-LDLR
-LRFN5
-MAPK7
-MEFV
-METRNL
-MFHAS1
-MIR124-1
-MIR124-2
-MIR124-3
-MIR126
-MIR141
-MIR149
-MIR155
-MIR15A
-MIR16-1
-MIR16-2
-MIR181B1
-MIR181B2
-MIR181C
-MIR187
-MIR20A
-MIR221
-MIR222
-MIR223
-MIR30C2
-MIR31
-MIR590
-MIR92A1
-MIR92A2
-MIRLET7G
-MMP26
-MVK
-NDFIP1
-NFKB1
-NLRC3
-NLRP12
-NLRP3
-NLRP6
-NLRP7
-NLRX1
-NPY5R
-NR1H3
-NR1H4
-NT5E
-OTULIN
-PBK
-PDCD4
-PGLYRP1
-PLA2G5
-PPARA
-PPARD
-PPARG
-PRKCD
-PROC
-PSMA1
-PSMB4
-PTGER4
-PTGIS
-PTPN2
-PTPRC
-PYCARD
-PYDC2
-RB1
-RORA
-RPS19
-SAA1
-SELENOS
-SERPINF1
-SHARPIN
-SIGLEC10
-SIRPA
-SLAMF8
-SMAD3
-SMPDL3B
-SOCS3
-SOCS5
-SOD1
-TAFA3
-TEK
-TNFAIP3
-TNFAIP6
-TNFAIP8L2
-TNFRSF1A
-TNFRSF1B
-TYRO3
-VPS35
-WFDC1
-ZC3H12A
\ No newline at end of file
diff --git a/mspypeline/config/pathways/GO_POSITIVE_REGULATION_OF_CYTOKINE_PRODUCTION.txt b/mspypeline/config/pathways/GO_POSITIVE_REGULATION_OF_CYTOKINE_PRODUCTION.txt
deleted file mode 100644
index 15fed3d..0000000
--- a/mspypeline/config/pathways/GO_POSITIVE_REGULATION_OF_CYTOKINE_PRODUCTION.txt
+++ /dev/null
@@ -1,451 +0,0 @@
-GO_POSITIVE_REGULATION_OF_CYTOKINE_PRODUCTION
-> Any process that activates or increases the frequency, rate or extent of production of a cytokine. [GOC:add, ISBN:0781735149]
-ABCC8
-ABL1
-ADAM17
-ADAM8
-ADCYAP1
-ADIPOQ
-ADORA2B
-ADRA2A
-AFAP1L2
-AGER
-AGPAT1
-AGPAT2
-AGT
-AGTR2
-AIF1
-AIM2
-AKIRIN2
-ALOX15B
-ANKRD17
-ANXA1
-APOA2
-APP
-APPL1
-ARFGEF2
-ARHGEF2
-ARNT
-ATF2
-ATF4
-ATP6AP2
-AZU1
-B2M
-BCL10
-BCL3
-BIRC2
-BIRC3
-BRCA1
-C1QBP
-C1QTNF3
-C1QTNF4
-C3
-C3AR1
-C5
-C5AR1
-CADM1
-CARD11
-CARD8
-CARD9
-CASP1
-CCBE1
-CCDC88B
-CCL1
-CCL19
-CCL3
-CCM2L
-CCR2
-CCR7
-CD14
-CD160
-CD2
-CD200
-CD226
-CD244
-CD274
-CD276
-CD28
-CD34
-CD36
-CD3E
-CD4
-CD40
-CD40LG
-CD46
-CD58
-CD6
-CD74
-CD80
-CD83
-CD86
-CEACAM20
-CEBPB
-CEBPG
-CGAS
-CHIA
-CHUK
-CLEC4E
-CLEC5A
-CLEC6A
-CLEC9A
-CLU
-CRCP
-CREB1
-CREBBP
-CRLF2
-CRTAM
-CSF1R
-CSF2
-CTNNB1
-CX3CL1
-CXCL17
-CYBA
-CYBB
-CYP1B1
-DDIT3
-DDT
-DDX1
-DDX21
-DDX3X
-DDX41
-DDX58
-DDX60
-DHX33
-DHX36
-DHX58
-DHX9
-DRD2
-EBI3
-EGR1
-EIF2AK2
-EIF2AK3
-ELANE
-EP300
-EPX
-EREG
-F2R
-F2RL1
-FADD
-FAM49B
-FCER1G
-FCN1
-FERMT1
-FFAR2
-FFAR3
-FGR
-FLOT1
-FLT4
-FOXP3
-FURIN
-FZD5
-GAPDH
-GATA3
-GATA4
-GBP5
-GDF2
-GLMN
-GPATCH3
-GPRC5B
-GPSM3
-GSDMD
-HAVCR2
-HDAC2
-HEG1
-HGF
-HHLA2
-HIF1A
-HILPDA
-HK1
-HLA-DPA1
-HLA-DPB1
-HLA-E
-HLA-F
-HLA-G
-HMGB1
-HMGB2
-HMGB4
-HMHB1
-HMOX1
-HPSE
-HRAS
-HSPA1A
-HSPA1B
-HSPB1
-HSPD1
-HTR2B
-HYAL2
-IDO1
-IFI16
-IFIH1
-IFNG
-IFNL1
-IGHD
-IL10
-IL12A
-IL12B
-IL12RB1
-IL12RB2
-IL13
-IL15
-IL17A
-IL17B
-IL17D
-IL17F
-IL17RA
-IL17RB
-IL17RC
-IL18
-IL18R1
-IL1A
-IL1B
-IL1F10
-IL1R1
-IL1RAP
-IL1RL1
-IL1RL2
-IL1RN
-IL2
-IL20RB
-IL21
-IL23A
-IL23R
-IL26
-IL27
-IL27RA
-IL33
-IL36A
-IL36B
-IL36G
-IL36RN
-IL37
-IL4
-IL4R
-IL6
-IL6R
-IL6ST
-IL7
-IL9
-INAVA
-INS
-IRAK1
-IRF1
-IRF3
-IRF4
-IRF5
-IRF7
-IRF8
-ISL1
-JAK2
-KARS
-KIR2DL4
-KLRC4-KLRK1
-KLRK1
-LBP
-LEP
-LGALS9
-LILRA2
-LILRA5
-LILRB1
-LILRB2
-LPL
-LRP1
-LRRFIP1
-LRRK2
-LSM14A
-LTA
-LTB
-LUM
-LURAP1
-LY9
-LY96
-MALT1
-MAP3K7
-MAPK11
-MAPK13
-MAPK14
-MAPK3
-MAPKAPK2
-MAVS
-MBP
-MCOLN2
-MIF
-MIR155
-MIR17
-MIR182
-MIR206
-MIR21
-MIR92A1
-MIR92A2
-MMP12
-MMP8
-MRE11
-MYB
-MYD88
-NFAM1
-NFATC4
-NFKB1
-NFKB2
-NLRP1
-NLRP10
-NLRP12
-NLRP2
-NLRP3
-NLRP7
-NLRP9
-NLRX1
-NOD1
-NOD2
-NODAL
-NOP53
-NOX1
-NPLOC4
-NR4A3
-ORM1
-ORM2
-OSM
-P2RX7
-PAEP
-PANX1
-PANX2
-PANX3
-PARK7
-PDE4B
-PDE4D
-PELI1
-PF4
-PIBF1
-PIK3R1
-PLCB1
-PLCG2
-POLR1C
-POLR2E
-POLR2F
-POLR2H
-POLR2K
-POLR2L
-POLR3A
-POLR3B
-POLR3C
-POLR3D
-POLR3E
-POLR3F
-POLR3G
-POLR3GL
-POLR3H
-POLR3K
-POSTN
-PQBP1
-PRG3
-PRKCQ
-PRKCZ
-PRKD2
-PRKDC
-PTAFR
-PTGER4
-PTGS2
-PTPN11
-PTPN22
-PTPRC
-PTPRJ
-PUM1
-PUM2
-PYCARD
-PYDC1
-RAB7B
-RAET1G
-RARA
-RASGRP1
-RELA
-RGCC
-RIOK3
-RIPK1
-RIPK2
-RNF125
-RNF135
-ROCK2
-RORA
-RPS3
-RSAD2
-RUNX1
-SAA1
-SASH3
-SCAMP5
-SEC14L1
-SELENOK
-SEMA7A
-SERPINB7
-SERPINE1
-SERPINF2
-SETD2
-SIGLEC16
-SLAMF6
-SLC11A1
-SMAD3
-SOD1
-SPN
-SPON2
-SPTBN1
-SRC
-STAT1
-STAT3
-STAT5B
-STAT6
-SULF1
-SULF2
-SYK
-TBC1D23
-TBK1
-TGFB1
-THBS1
-TICAM1
-TIGIT
-TIRAP
-TKFC
-TLR1
-TLR2
-TLR3
-TLR4
-TLR5
-TLR6
-TLR7
-TLR8
-TLR9
-TMEM173
-TMF1
-TMIGD2
-TNF
-TNFRSF13C
-TNFRSF14
-TNFRSF8
-TNFSF4
-TRAF2
-TRAF6
-TRIM15
-TRIM16
-TRIM32
-TRIM6
-TRPV4
-TSLP
-TSPAN6
-TUSC2
-TWIST1
-TXK
-TYROBP
-UCN
-UFD1
-USP17L2
-USP50
-VTCN1
-WNT11
-WNT3A
-WNT5A
-XBP1
-XCL1
-XRCC5
-XRCC6
-ZBP1
-ZBTB20
-ZCCHC3
-ZFPM1
-ZNF580
-ZP3
\ No newline at end of file
diff --git a/mspypeline/config/pathways/GO_RESPONSE_TO_HEPATOCYTE_GROWTH_FACTOR.txt b/mspypeline/config/pathways/GO_RESPONSE_TO_HEPATOCYTE_GROWTH_FACTOR.txt
deleted file mode 100644
index c55b73d..0000000
--- a/mspypeline/config/pathways/GO_RESPONSE_TO_HEPATOCYTE_GROWTH_FACTOR.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-GO_RESPONSE_TO_HEPATOCYTE_GROWTH_FACTOR
-> Any process that results in a change in state or activity of a cell or an organism (in terms of movement, secretion, enzyme production, gene expression, etc.) as a result of a hepatocyte growth factor stimulus. [GOC:bf]
-ADAMTS12
-APPL1
-APPL2
-BCAR1
-CASR
-CREB1
-CRK
-GAB1
-GCLC
-GCLM
-HGF
-IL10
-LGMN
-MED1
-NRP1
-RELA
-SIRT2
-TDGF1
-VIL1
\ No newline at end of file
diff --git a/mspypeline/config/pathways/GO_Regeneration.txt b/mspypeline/config/pathways/GO_Regeneration.txt
deleted file mode 100644
index be921d7..0000000
--- a/mspypeline/config/pathways/GO_Regeneration.txt
+++ /dev/null
@@ -1,197 +0,0 @@
-GO_REGENERATION
-> The regrowth of a lost or destroyed body part, such as an organ or tissue. This process may occur via renewal, repair, and/or growth alone (i.e. increase in size or mass). [GOC:mah, GOC:pr]
-ADAM15
-ADM
-AKIRIN1
-ANGPT2
-ANXA1
-ANXA3
-APOA1
-APOA2
-APOA5
-APOD
-ATIC
-AURKA
-AXL
-BAAT
-BAK1
-BCL2
-BCL9
-BIN3
-BRAF
-C5AR1
-CAD
-CAPN3
-CCN3
-CCNA2
-CCNB1
-CCND1
-CDK1
-CDK4
-CDKN1A
-CDKN1B
-CEBPB
-CERS2
-CFLAR
-CLDN1
-CNTF
-CPB2
-CPQ
-CSNK2A2
-CSNK2B
-CTNNA1
-CXCL12
-DAG1
-DHFR
-DHFRP1
-DUSP10
-DYSF
-EGFR
-ENO3
-EPHA4
-EPPK1
-ERBB4
-EYS
-EZH2
-F7
-FGF10
-FKBP1B
-FLT3
-FOLR1
-FPGS
-FZD7
-FZD9
-GAP43
-GAS6
-GFAP
-GJD4
-GLI1
-GLI3
-GPX1
-GRN
-GSN
-GSTP1
-HAMP
-HFE
-HGF
-HMOX1
-IFRD1
-IGF1
-IGF2R
-IGFBP1
-IHH
-IL10
-INPP5F
-ISL1
-JAK2
-JAM3
-JUN
-KLF4
-KLK6
-KLK8
-KREMEN1
-LAMB2
-LARGE1
-LCP1
-LGR6
-LPIN1
-LRIG2
-LRP1
-MAG
-MAP2K1
-MAP4K4
-MAPK8IP3
-MATN2
-MED1
-MIR199A1
-MIR199A2
-MIR199B
-MIR221
-MIR222
-MIR29B1
-MIR29B2
-MIR431
-MIR590
-MSTN
-MT-CYB
-MTPN
-MTR
-MUSTN1
-MYF6
-MYMK
-MYMX
-MYOD1
-MYOG
-MYOZ1
-NDEL1
-NEFL
-NINJ1
-NINJ2
-NNMT
-NOTCH1
-NR0B2
-NR4A3
-NREP
-NTRK3
-OMG
-PAX7
-PCNA
-PDX1
-PFKFB1
-PGF
-PKM
-PNPT1
-POSTN
-PPARD
-PPARG
-PPAT
-PPP3CA
-PRMT5
-PRPS2
-PRRX1
-PTCH1
-PTEN
-PTPN12
-PTPN3
-PTPRF
-PTPRS
-PTPRU
-RAP1A
-REG1A
-RGMA
-RGN
-RPL19
-RTN4R
-RTN4RL1
-RTN4RL2
-SCARF1
-SGCA
-SOX15
-SOX2
-SPAAR
-SPP1
-SRSF1
-SRSF5
-STK24
-SULF2
-TARBP2
-TEC
-TGFB1
-TGFBR2
-TGFBR3
-THY1
-TM4SF4
-TNC
-TNR
-TSPO
-TYMS
-UCP2
-UGT1A1
-ULK1
-UPF2
-VTN
-WDR35
-WNT1
-WNT10B
-WNT7A
-YAP1
\ No newline at end of file
diff --git a/mspypeline/config/pathways/NABA_MATRISOME.txt b/mspypeline/config/pathways/NABA_MATRISOME.txt
deleted file mode 100644
index 3605c3f..0000000
--- a/mspypeline/config/pathways/NABA_MATRISOME.txt
+++ /dev/null
@@ -1,1028 +0,0 @@
-NABA_MATRISOME
-> Ensemble of genes encoding extracellular matrix and extracellular matrix-associated proteins
-A2M
-A2ML1
-ABI3BP
-AC010330.1
-ACAN
-ADAM10
-ADAM11
-ADAM12
-ADAM15
-ADAM17
-ADAM18
-ADAM19
-ADAM2
-ADAM20
-ADAM21
-ADAM22
-ADAM23
-ADAM28
-ADAM29
-ADAM30
-ADAM32
-ADAM33
-ADAM7
-ADAM8
-ADAM9
-ADAMDEC1
-ADAMTS1
-ADAMTS10
-ADAMTS12
-ADAMTS13
-ADAMTS14
-ADAMTS15
-ADAMTS16
-ADAMTS17
-ADAMTS18
-ADAMTS19
-ADAMTS2
-ADAMTS20
-ADAMTS3
-ADAMTS4
-ADAMTS5
-ADAMTS6
-ADAMTS7
-ADAMTS8
-ADAMTS9
-ADAMTSL1
-ADAMTSL2
-ADAMTSL3
-ADAMTSL4
-ADAMTSL5
-ADIPOQ
-AEBP1
-AGRN
-AGT
-AMBN
-AMBP
-AMELX
-AMELY
-AMH
-ANGPT1
-ANGPT2
-ANGPT4
-ANGPTL1
-ANGPTL2
-ANGPTL3
-ANGPTL4
-ANGPTL5
-ANGPTL6
-ANGPTL7
-ANOS1
-ANXA1
-ANXA10
-ANXA11
-ANXA13
-ANXA2
-ANXA3
-ANXA4
-ANXA5
-ANXA6
-ANXA7
-ANXA8
-ANXA8L1
-ANXA9
-AREG
-ARTN
-ASPN
-ASTL
-BCAN
-BDNF
-BGLAP
-BGN
-BMP1
-BMP10
-BMP15
-BMP2
-BMP3
-BMP4
-BMP5
-BMP6
-BMP7
-BMP8A
-BMP8B
-BMPER
-BRINP2
-BRINP3
-BSPH1
-BTC
-C17orf58
-C1QA
-C1QB
-C1QC
-C1QL1
-C1QL2
-C1QL3
-C1QL4
-C1QTNF1
-C1QTNF2
-C1QTNF3
-C1QTNF4
-C1QTNF5
-C1QTNF6
-C1QTNF7
-C1QTNF8
-C1QTNF9
-C1QTNF9B
-CBLN1
-CBLN2
-CBLN3
-CBLN4
-CCBE1
-CCL1
-CCL11
-CCL13
-CCL14
-CCL15
-CCL16
-CCL17
-CCL18
-CCL19
-CCL2
-CCL20
-CCL21
-CCL22
-CCL23
-CCL24
-CCL25
-CCL26
-CCL27
-CCL28
-CCL3
-CCL3L3
-CCL4
-CCL4L2
-CCL5
-CCL7
-CCL8
-CCN1
-CCN2
-CCN3
-CCN4
-CCN5
-CCN6
-CD109
-CD209
-CDCP2
-CELA1
-CELA2A
-CELA2B
-CELA3A
-CELA3B
-CFC1
-CFC1B
-CHAD
-CHADL
-CHRD
-CHRDL1
-CHRDL2
-CILP
-CILP2
-CLC
-CLCF1
-CLEC10A
-CLEC11A
-CLEC12A
-CLEC12B
-CLEC14A
-CLEC17A
-CLEC18A
-CLEC18B
-CLEC18C
-CLEC19A
-CLEC1A
-CLEC1B
-CLEC2A
-CLEC2B
-CLEC2D
-CLEC2L
-CLEC3A
-CLEC3B
-CLEC4A
-CLEC4C
-CLEC4D
-CLEC4E
-CLEC4F
-CLEC4G
-CLEC4M
-CLEC5A
-CLEC6A
-CLEC7A
-CLEC9A
-CNTF
-COCH
-COL10A1
-COL11A1
-COL11A2
-COL12A1
-COL13A1
-COL14A1
-COL15A1
-COL16A1
-COL17A1
-COL18A1
-COL19A1
-COL1A1
-COL1A2
-COL20A1
-COL21A1
-COL22A1
-COL23A1
-COL24A1
-COL25A1
-COL26A1
-COL27A1
-COL28A1
-COL2A1
-COL3A1
-COL4A1
-COL4A2
-COL4A3
-COL4A4
-COL4A5
-COL4A6
-COL5A1
-COL5A2
-COL5A3
-COL6A1
-COL6A2
-COL6A3
-COL6A5
-COL6A6
-COL7A1
-COL8A1
-COL8A2
-COL9A1
-COL9A2
-COL9A3
-COLEC10
-COLEC11
-COLEC12
-COLQ
-COMP
-CPAMD8
-CPN2
-CRELD1
-CRELD2
-CRHBP
-CRIM1
-CRISPLD1
-CRISPLD2
-CRLF1
-CRLF3
-CRNN
-CSF1
-CSF2
-CSF3
-CSH1
-CSH2
-CSHL1
-CSPG4
-CSPG5
-CST1
-CST11
-CST2
-CST3
-CST4
-CST5
-CST6
-CST7
-CST8
-CST9
-CST9L
-CSTA
-CSTB
-CSTL1
-CTF1
-CTHRC1
-CTSA
-CTSB
-CTSC
-CTSD
-CTSE
-CTSF
-CTSG
-CTSH
-CTSK
-CTSL
-CTSO
-CTSS
-CTSV
-CTSW
-CTSZ
-CX3CL1
-CXCL1
-CXCL10
-CXCL11
-CXCL12
-CXCL13
-CXCL14
-CXCL2
-CXCL3
-CXCL5
-CXCL6
-CXCL8
-CXCL9
-DCN
-DHH
-DMBT1
-DMP1
-DPT
-DSPP
-EBI3
-ECM1
-ECM2
-EDA
-EDIL3
-EFEMP1
-EFEMP2
-EGF
-EGFL6
-EGFL7
-EGFL8
-EGFLAM
-EGLN1
-EGLN2
-EGLN3
-ELANE
-ELFN1
-ELFN2
-ELN
-EMCN
-EMID1
-EMILIN1
-EMILIN2
-EMILIN3
-EPGN
-EPO
-EPYC
-EREG
-ESM1
-EYS
-F10
-F12
-F13A1
-F13B
-F2
-F7
-F9
-FAM20A
-FAM20B
-FAM20C
-FASLG
-FBLN1
-FBLN2
-FBLN5
-FBLN7
-FBN1
-FBN2
-FBN3
-FCN1
-FCN2
-FCN3
-FGA
-FGB
-FGF1
-FGF10
-FGF11
-FGF12
-FGF13
-FGF14
-FGF16
-FGF17
-FGF18
-FGF19
-FGF2
-FGF20
-FGF21
-FGF22
-FGF23
-FGF3
-FGF4
-FGF5
-FGF6
-FGF7
-FGF8
-FGF9
-FGFBP1
-FGFBP2
-FGFBP3
-FGG
-FGL1
-FGL2
-FLG
-FLG2
-FLT3LG
-FMOD
-FN1
-FNDC1
-FNDC7
-FNDC8
-FRAS1
-FREM1
-FREM2
-FREM3
-FRZB
-FST
-FSTL1
-FSTL3
-GAS6
-GDF1
-GDF10
-GDF11
-GDF15
-GDF2
-GDF3
-GDF5
-GDF6
-GDF7
-GDF9
-GDNF
-GH1
-GH2
-GLDN
-GPC1
-GPC2
-GPC3
-GPC4
-GPC5
-GPC6
-GREM1
-GRIFIN
-HABP2
-HAPLN1
-HAPLN2
-HAPLN3
-HAPLN4
-HBEGF
-HCFC1
-HCFC2
-HGF
-HGFAC
-HHIP
-HMCN1
-HMCN2
-HMSD
-HPSE
-HPSE2
-HPX
-HRG
-HRNR
-HSPG2
-HTRA1
-HTRA3
-HTRA4
-HYAL1
-HYAL2
-HYAL3
-HYAL4
-IBSP
-IFNA1
-IFNA10
-IFNA13
-IFNA14
-IFNA16
-IFNA17
-IFNA2
-IFNA21
-IFNA4
-IFNA5
-IFNA6
-IFNA7
-IFNA8
-IFNB1
-IFNE
-IFNG
-IFNK
-IFNW1
-IGF1
-IGF2
-IGFALS
-IGFBP1
-IGFBP2
-IGFBP3
-IGFBP4
-IGFBP5
-IGFBP6
-IGFBP7
-IGFBPL1
-IGSF10
-IHH
-IL10
-IL11
-IL12A
-IL12B
-IL13
-IL15
-IL16
-IL17A
-IL17B
-IL17C
-IL17D
-IL17F
-IL18
-IL19
-IL1A
-IL1B
-IL1F10
-IL1RN
-IL2
-IL20
-IL22
-IL23A
-IL24
-IL25
-IL26
-IL3
-IL34
-IL36A
-IL36B
-IL36G
-IL36RN
-IL37
-IL4
-IL5
-IL6
-IL7
-IL9
-IMPG1
-IMPG2
-INHA
-INHBA
-INHBB
-INHBC
-INHBE
-INS
-INS-IGF2
-INSL3
-INSL5
-INSL6
-INTS14
-INTS6L
-ISM1
-ISM2
-ITIH1
-ITIH2
-ITIH3
-ITIH4
-ITIH5
-ITIH6
-ITLN1
-ITLN2
-KAZALD1
-KCP
-KERA
-KITLG
-KNG1
-KY
-LAMA1
-LAMA2
-LAMA3
-LAMA4
-LAMA5
-LAMB1
-LAMB2
-LAMB3
-LAMB4
-LAMC1
-LAMC2
-LAMC3
-LEFTY1
-LEFTY2
-LEP
-LGALS1
-LGALS12
-LGALS13
-LGALS14
-LGALS16
-LGALS2
-LGALS3
-LGALS4
-LGALS7
-LGALS8
-LGALS9
-LGALS9B
-LGALS9C
-LGALSL
-LGI1
-LGI2
-LGI3
-LGI4
-LIF
-LMAN1
-LMAN1L
-LOX
-LOXL1
-LOXL2
-LOXL3
-LOXL4
-LPA
-LRG1
-LTA
-LTB
-LTBP1
-LTBP2
-LTBP3
-LTBP4
-LUM
-MASP1
-MASP2
-MATN1
-MATN2
-MATN3
-MATN4
-MBL2
-MDK
-MEGF10
-MEGF11
-MEGF6
-MEGF8
-MEGF9
-MEP1A
-MEP1B
-MEPE
-MFAP1
-MFAP2
-MFAP3
-MFAP4
-MFAP5
-MFGE8
-MGP
-MMP1
-MMP10
-MMP11
-MMP12
-MMP13
-MMP14
-MMP15
-MMP16
-MMP17
-MMP19
-MMP2
-MMP20
-MMP21
-MMP23B
-MMP24
-MMP25
-MMP26
-MMP27
-MMP28
-MMP3
-MMP7
-MMP8
-MMP9
-MMRN1
-MMRN2
-MST1
-MST1L
-MSTN
-MUC1
-MUC12
-MUC13
-MUC15
-MUC16
-MUC17
-MUC19
-MUC2
-MUC20
-MUC21
-MUC22
-MUC3A
-MUC4
-MUC5AC
-MUC5B
-MUC6
-MUC7
-MUCL1
-MXRA5
-NCAN
-NDNF
-NELL1
-NELL2
-NGF
-NGLY1
-NID1
-NID2
-NODAL
-NPNT
-NRG1
-NRG2
-NRG3
-NRG4
-NRTN
-NTF3
-NTF4
-NTN1
-NTN3
-NTN4
-NTN5
-NTNG1
-NTNG2
-NYX
-OGFOD1
-OGFOD2
-OGN
-OIT3
-OMD
-OPRPN
-OPTC
-OSM
-OTOG
-OTOL1
-OVGP1
-P3H1
-P3H2
-P3H3
-P4HA1
-P4HA2
-P4HA3
-P4HTM
-PAMR1
-PAPLN
-PAPPA
-PAPPA2
-PARM1
-PCOLCE
-PCOLCE2
-PCSK5
-PCSK6
-PDGFA
-PDGFB
-PDGFC
-PDGFD
-PF4
-PF4V1
-PGF
-PI3
-PIK3IP1
-PLAT
-PLAU
-PLG
-PLOD1
-PLOD2
-PLOD3
-PLXDC1
-PLXDC2
-PLXNA1
-PLXNA2
-PLXNA3
-PLXNA4
-PLXNB1
-PLXNB2
-PLXNB3
-PLXNC1
-PLXND1
-PODN
-PODNL1
-POMZP3
-POSTN
-PPBP
-PRELP
-PRG2
-PRG3
-PRG4
-PRL
-PRSS1
-PRSS12
-PRSS2
-PRSS3
-PSPN
-PTN
-PXDN
-PXDNL
-PZP
-REG1A
-REG1B
-REG3A
-REG3G
-REG4
-RELN
-RPTN
-RSPO1
-RSPO2
-RSPO3
-RSPO4
-S100A1
-S100A10
-S100A11
-S100A12
-S100A13
-S100A14
-S100A16
-S100A2
-S100A3
-S100A4
-S100A5
-S100A6
-S100A7
-S100A7A
-S100A7L2
-S100A8
-S100A9
-S100B
-S100G
-S100P
-S100Z
-SBSPON
-SCUBE1
-SCUBE2
-SCUBE3
-SDC1
-SDC2
-SDC3
-SDC4
-SEMA3A
-SEMA3B
-SEMA3C
-SEMA3D
-SEMA3E
-SEMA3F
-SEMA3G
-SEMA4A
-SEMA4B
-SEMA4C
-SEMA4D
-SEMA4F
-SEMA4G
-SEMA5A
-SEMA5B
-SEMA6A
-SEMA6B
-SEMA6C
-SEMA6D
-SEMA7A
-SERPINA1
-SERPINA10
-SERPINA11
-SERPINA12
-SERPINA2
-SERPINA3
-SERPINA4
-SERPINA5
-SERPINA6
-SERPINA7
-SERPINA9
-SERPINB1
-SERPINB10
-SERPINB11
-SERPINB12
-SERPINB13
-SERPINB2
-SERPINB3
-SERPINB4
-SERPINB5
-SERPINB6
-SERPINB7
-SERPINB8
-SERPINB9
-SERPINC1
-SERPIND1
-SERPINE1
-SERPINE2
-SERPINE3
-SERPINF1
-SERPINF2
-SERPING1
-SERPINH1
-SERPINI1
-SERPINI2
-SFRP1
-SFRP2
-SFRP4
-SFRP5
-SFTA2
-SFTA3
-SFTPA1
-SFTPA2
-SFTPB
-SFTPC
-SFTPD
-SHH
-SLIT1
-SLIT2
-SLIT3
-SLPI
-SMOC1
-SMOC2
-SNED1
-SPAM1
-SPARC
-SPARCL1
-SPOCK1
-SPOCK2
-SPOCK3
-SPON1
-SPON2
-SPP1
-SRGN
-SRPX
-SRPX2
-SSPO
-ST14
-SULF1
-SULF2
-SVEP1
-TCHH
-TCHHL1
-TDGF1
-TECTA
-TECTB
-TGFA
-TGFB1
-TGFB2
-TGFB3
-TGFBI
-TGM1
-TGM2
-TGM3
-TGM4
-TGM5
-TGM6
-TGM7
-THBS1
-THBS2
-THBS3
-THBS4
-THPO
-THSD4
-TIMP1
-TIMP2
-TIMP3
-TIMP4
-TINAG
-TINAGL1
-TLL1
-TLL2
-TMPRSS15
-TNC
-TNF
-TNFAIP6
-TNFSF10
-TNFSF11
-TNFSF12
-TNFSF13
-TNFSF13B
-TNFSF14
-TNFSF15
-TNFSF18
-TNFSF4
-TNFSF8
-TNFSF9
-TNN
-TNR
-TNXB
-TPO
-TSKU
-TSPEAR
-USH2A
-VCAN
-VEGFA
-VEGFB
-VEGFC
-VEGFD
-VIT
-VTN
-VWA1
-VWA2
-VWA3A
-VWA3B
-VWA5A
-VWA5B1
-VWA5B2
-VWA7
-VWC2
-VWC2L
-VWCE
-VWDE
-VWF
-WFIKKN1
-WFIKKN2
-WIF1
-WNT1
-WNT10A
-WNT10B
-WNT11
-WNT16
-WNT2
-WNT2B
-WNT3
-WNT3A
-WNT4
-WNT5A
-WNT5B
-WNT6
-WNT7A
-WNT7B
-WNT8A
-WNT8B
-WNT9A
-WNT9B
-XCL1
-XCL2
-ZFP91
-ZP1
-ZP2
-ZP3
-ZP4
-ZPLD1
\ No newline at end of file
diff --git a/mspypeline/config/pathways/NABA_MATRISOME_ASSOCIATED.txt b/mspypeline/config/pathways/NABA_MATRISOME_ASSOCIATED.txt
deleted file mode 100644
index a6e8f0a..0000000
--- a/mspypeline/config/pathways/NABA_MATRISOME_ASSOCIATED.txt
+++ /dev/null
@@ -1,753 +0,0 @@
-NABA_MATRISOME_ASSOCIATED
-> Ensemble of genes encoding ECM-associated proteins including ECM-affilaited proteins, ECM regulators and secreted factors
-A2M
-A2ML1
-ADAM10
-ADAM11
-ADAM12
-ADAM15
-ADAM17
-ADAM18
-ADAM19
-ADAM2
-ADAM20
-ADAM21
-ADAM22
-ADAM23
-ADAM28
-ADAM29
-ADAM30
-ADAM32
-ADAM33
-ADAM7
-ADAM8
-ADAM9
-ADAMDEC1
-ADAMTS1
-ADAMTS10
-ADAMTS12
-ADAMTS13
-ADAMTS14
-ADAMTS15
-ADAMTS16
-ADAMTS17
-ADAMTS18
-ADAMTS19
-ADAMTS2
-ADAMTS20
-ADAMTS3
-ADAMTS4
-ADAMTS5
-ADAMTS6
-ADAMTS7
-ADAMTS8
-ADAMTS9
-ADAMTSL1
-ADAMTSL2
-ADAMTSL3
-ADAMTSL4
-ADAMTSL5
-AGT
-AMBP
-AMH
-ANGPT1
-ANGPT2
-ANGPT4
-ANGPTL1
-ANGPTL2
-ANGPTL3
-ANGPTL4
-ANGPTL5
-ANGPTL6
-ANGPTL7
-ANXA1
-ANXA10
-ANXA11
-ANXA13
-ANXA2
-ANXA3
-ANXA4
-ANXA5
-ANXA6
-ANXA7
-ANXA8
-ANXA8L1
-ANXA9
-AREG
-ARTN
-ASTL
-BDNF
-BMP1
-BMP10
-BMP15
-BMP2
-BMP3
-BMP4
-BMP5
-BMP6
-BMP7
-BMP8A
-BMP8B
-BRINP2
-BRINP3
-BTC
-C17orf58
-C1QA
-C1QB
-C1QC
-C1QL1
-C1QL2
-C1QL3
-C1QL4
-C1QTNF1
-C1QTNF2
-C1QTNF3
-C1QTNF4
-C1QTNF5
-C1QTNF6
-C1QTNF7
-C1QTNF8
-C1QTNF9
-C1QTNF9B
-CBLN1
-CBLN2
-CBLN3
-CBLN4
-CCBE1
-CCL1
-CCL11
-CCL13
-CCL14
-CCL15
-CCL16
-CCL17
-CCL18
-CCL19
-CCL2
-CCL20
-CCL21
-CCL22
-CCL23
-CCL24
-CCL25
-CCL26
-CCL27
-CCL28
-CCL3
-CCL3L3
-CCL4
-CCL4L2
-CCL5
-CCL7
-CCL8
-CD109
-CD209
-CELA1
-CELA2A
-CELA2B
-CELA3A
-CELA3B
-CFC1
-CFC1B
-CHRD
-CHRDL1
-CHRDL2
-CLC
-CLCF1
-CLEC10A
-CLEC11A
-CLEC12A
-CLEC12B
-CLEC14A
-CLEC17A
-CLEC18A
-CLEC18B
-CLEC18C
-CLEC19A
-CLEC1A
-CLEC1B
-CLEC2A
-CLEC2B
-CLEC2D
-CLEC2L
-CLEC3A
-CLEC3B
-CLEC4A
-CLEC4C
-CLEC4D
-CLEC4E
-CLEC4F
-CLEC4G
-CLEC4M
-CLEC5A
-CLEC6A
-CLEC7A
-CLEC9A
-CNTF
-COLEC10
-COLEC11
-COLEC12
-CPAMD8
-CPN2
-CRHBP
-CRLF1
-CRLF3
-CRNN
-CSF1
-CSF2
-CSF3
-CSH1
-CSH2
-CSHL1
-CSPG4
-CSPG5
-CST1
-CST11
-CST2
-CST3
-CST4
-CST5
-CST6
-CST7
-CST8
-CST9
-CST9L
-CSTA
-CSTB
-CSTL1
-CTF1
-CTSA
-CTSB
-CTSC
-CTSD
-CTSE
-CTSF
-CTSG
-CTSH
-CTSK
-CTSL
-CTSO
-CTSS
-CTSV
-CTSW
-CTSZ
-CX3CL1
-CXCL1
-CXCL10
-CXCL11
-CXCL12
-CXCL13
-CXCL14
-CXCL2
-CXCL3
-CXCL5
-CXCL6
-CXCL8
-CXCL9
-DHH
-EBI3
-EDA
-EGF
-EGFL6
-EGFL7
-EGFL8
-EGLN1
-EGLN2
-EGLN3
-ELANE
-ELFN1
-ELFN2
-EMCN
-EPGN
-EPO
-EREG
-F10
-F12
-F13A1
-F13B
-F2
-F7
-F9
-FAM20A
-FAM20B
-FAM20C
-FASLG
-FCN1
-FCN2
-FCN3
-FGF1
-FGF10
-FGF11
-FGF12
-FGF13
-FGF14
-FGF16
-FGF17
-FGF18
-FGF19
-FGF2
-FGF20
-FGF21
-FGF22
-FGF23
-FGF3
-FGF4
-FGF5
-FGF6
-FGF7
-FGF8
-FGF9
-FGFBP1
-FGFBP2
-FGFBP3
-FLG
-FLG2
-FLT3LG
-FREM1
-FREM2
-FREM3
-FRZB
-FST
-FSTL1
-FSTL3
-GDF1
-GDF10
-GDF11
-GDF15
-GDF2
-GDF3
-GDF5
-GDF6
-GDF7
-GDF9
-GDNF
-GH1
-GH2
-GPC1
-GPC2
-GPC3
-GPC4
-GPC5
-GPC6
-GREM1
-GRIFIN
-HABP2
-HBEGF
-HCFC1
-HCFC2
-HGF
-HGFAC
-HHIP
-HMSD
-HPSE
-HPSE2
-HPX
-HRG
-HRNR
-HTRA1
-HTRA3
-HTRA4
-HYAL1
-HYAL2
-HYAL3
-HYAL4
-IFNA1
-IFNA10
-IFNA13
-IFNA14
-IFNA16
-IFNA17
-IFNA2
-IFNA21
-IFNA4
-IFNA5
-IFNA6
-IFNA7
-IFNA8
-IFNB1
-IFNE
-IFNG
-IFNK
-IFNW1
-IGF1
-IGF2
-IHH
-IL10
-IL11
-IL12A
-IL12B
-IL13
-IL15
-IL16
-IL17A
-IL17B
-IL17C
-IL17D
-IL17F
-IL18
-IL19
-IL1A
-IL1B
-IL1F10
-IL1RN
-IL2
-IL20
-IL22
-IL23A
-IL24
-IL25
-IL26
-IL3
-IL34
-IL36A
-IL36B
-IL36G
-IL36RN
-IL37
-IL4
-IL5
-IL6
-IL7
-IL9
-INHA
-INHBA
-INHBB
-INHBC
-INHBE
-INS
-INS-IGF2
-INSL3
-INSL5
-INSL6
-ISM1
-ISM2
-ITIH1
-ITIH2
-ITIH3
-ITIH4
-ITIH5
-ITIH6
-ITLN1
-ITLN2
-KAZALD1
-KITLG
-KNG1
-KY
-LEFTY1
-LEFTY2
-LEP
-LGALS1
-LGALS12
-LGALS13
-LGALS14
-LGALS16
-LGALS2
-LGALS3
-LGALS4
-LGALS7
-LGALS8
-LGALS9
-LGALS9B
-LGALS9C
-LGALSL
-LIF
-LMAN1
-LMAN1L
-LOX
-LOXL1
-LOXL2
-LOXL3
-LOXL4
-LPA
-LTA
-LTB
-MASP1
-MASP2
-MBL2
-MDK
-MEGF10
-MEGF11
-MEGF6
-MEGF8
-MEGF9
-MEP1A
-MEP1B
-MMP1
-MMP10
-MMP11
-MMP12
-MMP13
-MMP14
-MMP15
-MMP16
-MMP17
-MMP19
-MMP2
-MMP20
-MMP21
-MMP23B
-MMP24
-MMP25
-MMP26
-MMP27
-MMP28
-MMP3
-MMP7
-MMP8
-MMP9
-MST1
-MST1L
-MSTN
-MUC1
-MUC12
-MUC13
-MUC15
-MUC16
-MUC17
-MUC19
-MUC2
-MUC20
-MUC21
-MUC22
-MUC3A
-MUC4
-MUC5AC
-MUC5B
-MUC6
-MUC7
-MUCL1
-NGF
-NGLY1
-NODAL
-NRG1
-NRG2
-NRG3
-NRG4
-NRTN
-NTF3
-NTF4
-OGFOD1
-OGFOD2
-OPRPN
-OSM
-OVGP1
-P3H1
-P3H2
-P3H3
-P4HA1
-P4HA2
-P4HA3
-P4HTM
-PAMR1
-PAPPA
-PAPPA2
-PARM1
-PCSK5
-PCSK6
-PDGFA
-PDGFB
-PDGFC
-PDGFD
-PF4
-PF4V1
-PGF
-PI3
-PIK3IP1
-PLAT
-PLAU
-PLG
-PLOD1
-PLOD2
-PLOD3
-PLXDC1
-PLXDC2
-PLXNA1
-PLXNA2
-PLXNA3
-PLXNA4
-PLXNB1
-PLXNB2
-PLXNB3
-PLXNC1
-PLXND1
-PPBP
-PRL
-PRSS1
-PRSS12
-PRSS2
-PRSS3
-PSPN
-PTN
-PZP
-REG1A
-REG1B
-REG3A
-REG3G
-REG4
-RPTN
-S100A1
-S100A10
-S100A11
-S100A12
-S100A13
-S100A14
-S100A16
-S100A2
-S100A3
-S100A4
-S100A5
-S100A6
-S100A7
-S100A7A
-S100A7L2
-S100A8
-S100A9
-S100B
-S100G
-S100P
-S100Z
-SCUBE1
-SCUBE2
-SCUBE3
-SDC1
-SDC2
-SDC3
-SDC4
-SEMA3A
-SEMA3B
-SEMA3C
-SEMA3D
-SEMA3E
-SEMA3F
-SEMA3G
-SEMA4A
-SEMA4B
-SEMA4C
-SEMA4D
-SEMA4F
-SEMA4G
-SEMA5A
-SEMA5B
-SEMA6A
-SEMA6B
-SEMA6C
-SEMA6D
-SEMA7A
-SERPINA1
-SERPINA10
-SERPINA11
-SERPINA12
-SERPINA2
-SERPINA3
-SERPINA4
-SERPINA5
-SERPINA6
-SERPINA7
-SERPINA9
-SERPINB1
-SERPINB10
-SERPINB11
-SERPINB12
-SERPINB13
-SERPINB2
-SERPINB3
-SERPINB4
-SERPINB5
-SERPINB6
-SERPINB7
-SERPINB8
-SERPINB9
-SERPINC1
-SERPIND1
-SERPINE1
-SERPINE2
-SERPINE3
-SERPINF1
-SERPINF2
-SERPING1
-SERPINH1
-SERPINI1
-SERPINI2
-SFRP1
-SFRP2
-SFRP4
-SFRP5
-SFTA2
-SFTA3
-SFTPA1
-SFTPA2
-SFTPB
-SFTPC
-SFTPD
-SHH
-SLPI
-SPAM1
-ST14
-SULF1
-SULF2
-TCHH
-TCHHL1
-TDGF1
-TGFA
-TGFB1
-TGFB2
-TGFB3
-TGM1
-TGM2
-TGM3
-TGM4
-TGM5
-TGM6
-TGM7
-THPO
-TIMP1
-TIMP2
-TIMP3
-TIMP4
-TLL1
-TLL2
-TMPRSS15
-TNF
-TNFSF10
-TNFSF11
-TNFSF12
-TNFSF13
-TNFSF13B
-TNFSF14
-TNFSF15
-TNFSF18
-TNFSF4
-TNFSF8
-TNFSF9
-TPO
-VEGFA
-VEGFB
-VEGFC
-VEGFD
-VWC2
-VWC2L
-WFIKKN1
-WFIKKN2
-WIF1
-WNT1
-WNT10A
-WNT10B
-WNT11
-WNT16
-WNT2
-WNT2B
-WNT3
-WNT3A
-WNT4
-WNT5A
-WNT5B
-WNT6
-WNT7A
-WNT7B
-WNT8A
-WNT8B
-WNT9A
-WNT9B
-XCL1
-XCL2
-ZFP91
\ No newline at end of file
diff --git a/mspypeline/config/pathways/NABA_SECRETED_FACTORS.txt b/mspypeline/config/pathways/NABA_SECRETED_FACTORS.txt
deleted file mode 100644
index 132272a..0000000
--- a/mspypeline/config/pathways/NABA_SECRETED_FACTORS.txt
+++ /dev/null
@@ -1,345 +0,0 @@
-NABA_SECRETED_FACTORS
-> Genes encoding secreted soluble factors
-AMH
-ANGPT1
-ANGPT2
-ANGPT4
-ANGPTL1
-ANGPTL2
-ANGPTL3
-ANGPTL4
-ANGPTL5
-ANGPTL6
-ANGPTL7
-AREG
-ARTN
-BDNF
-BMP10
-BMP15
-BMP2
-BMP3
-BMP4
-BMP5
-BMP6
-BMP7
-BMP8A
-BMP8B
-BRINP2
-BRINP3
-BTC
-C1QTNF9B
-CBLN1
-CBLN2
-CBLN3
-CBLN4
-CCBE1
-CCL1
-CCL11
-CCL13
-CCL14
-CCL15
-CCL16
-CCL17
-CCL18
-CCL19
-CCL2
-CCL20
-CCL21
-CCL22
-CCL23
-CCL24
-CCL25
-CCL26
-CCL27
-CCL28
-CCL3
-CCL3L3
-CCL4
-CCL4L2
-CCL5
-CCL7
-CCL8
-CFC1
-CFC1B
-CHRD
-CHRDL1
-CHRDL2
-CLCF1
-CNTF
-CRHBP
-CRLF1
-CRLF3
-CRNN
-CSF1
-CSF2
-CSF3
-CSH1
-CSH2
-CSHL1
-CTF1
-CX3CL1
-CXCL1
-CXCL10
-CXCL11
-CXCL12
-CXCL13
-CXCL14
-CXCL2
-CXCL3
-CXCL5
-CXCL6
-CXCL8
-CXCL9
-DHH
-EBI3
-EDA
-EGF
-EGFL6
-EGFL7
-EGFL8
-EPGN
-EPO
-EREG
-FASLG
-FGF1
-FGF10
-FGF11
-FGF12
-FGF13
-FGF14
-FGF16
-FGF17
-FGF18
-FGF19
-FGF2
-FGF20
-FGF21
-FGF22
-FGF23
-FGF3
-FGF4
-FGF5
-FGF6
-FGF7
-FGF8
-FGF9
-FGFBP1
-FGFBP2
-FGFBP3
-FLG
-FLG2
-FLT3LG
-FRZB
-FST
-FSTL1
-FSTL3
-GDF1
-GDF10
-GDF11
-GDF15
-GDF2
-GDF3
-GDF5
-GDF6
-GDF7
-GDF9
-GDNF
-GH1
-GH2
-HBEGF
-HCFC1
-HCFC2
-HGF
-HGFAC
-HHIP
-HRNR
-IFNA1
-IFNA10
-IFNA13
-IFNA14
-IFNA16
-IFNA17
-IFNA2
-IFNA21
-IFNA4
-IFNA5
-IFNA6
-IFNA7
-IFNA8
-IFNB1
-IFNE
-IFNG
-IFNK
-IFNW1
-IGF1
-IGF2
-IHH
-IL10
-IL11
-IL12A
-IL12B
-IL13
-IL15
-IL16
-IL17A
-IL17B
-IL17C
-IL17D
-IL17F
-IL18
-IL19
-IL1A
-IL1B
-IL1F10
-IL1RN
-IL2
-IL20
-IL22
-IL23A
-IL24
-IL25
-IL26
-IL3
-IL34
-IL36A
-IL36B
-IL36G
-IL36RN
-IL37
-IL4
-IL5
-IL6
-IL7
-IL9
-INHA
-INHBA
-INHBB
-INHBC
-INHBE
-INS
-INS-IGF2
-INSL3
-INSL5
-INSL6
-ISM1
-ISM2
-KITLG
-LEFTY1
-LEFTY2
-LEP
-LIF
-LTA
-LTB
-MDK
-MEGF10
-MEGF11
-MEGF6
-MEGF8
-MEGF9
-MST1
-MST1L
-MSTN
-NGF
-NODAL
-NRG1
-NRG2
-NRG3
-NRG4
-NRTN
-NTF3
-NTF4
-OSM
-PDGFA
-PDGFB
-PDGFC
-PDGFD
-PF4
-PF4V1
-PGF
-PIK3IP1
-PPBP
-PRL
-PSPN
-PTN
-RPTN
-S100A1
-S100A10
-S100A11
-S100A12
-S100A13
-S100A14
-S100A16
-S100A2
-S100A3
-S100A4
-S100A5
-S100A6
-S100A7
-S100A7A
-S100A7L2
-S100A8
-S100A9
-S100B
-S100G
-S100P
-S100Z
-SCUBE1
-SCUBE2
-SCUBE3
-SFRP1
-SFRP2
-SFRP4
-SFRP5
-SHH
-TCHH
-TCHHL1
-TDGF1
-TGFA
-TGFB1
-TGFB2
-TGFB3
-THPO
-TNF
-TNFSF10
-TNFSF11
-TNFSF12
-TNFSF13
-TNFSF13B
-TNFSF14
-TNFSF15
-TNFSF18
-TNFSF4
-TNFSF8
-TNFSF9
-TPO
-VEGFA
-VEGFB
-VEGFC
-VEGFD
-VWC2
-VWC2L
-WFIKKN1
-WFIKKN2
-WIF1
-WNT1
-WNT10A
-WNT10B
-WNT11
-WNT16
-WNT2
-WNT2B
-WNT3
-WNT3A
-WNT4
-WNT5A
-WNT5B
-WNT6
-WNT7A
-WNT7B
-WNT8A
-WNT8B
-WNT9A
-WNT9B
-XCL1
-XCL2
-ZFP91
\ No newline at end of file
diff --git a/mspypeline/config/pathways/REACTOME_MET_RECEPTOR_ACTIVATION.txt b/mspypeline/config/pathways/REACTOME_MET_RECEPTOR_ACTIVATION.txt
deleted file mode 100644
index 96f1dea..0000000
--- a/mspypeline/config/pathways/REACTOME_MET_RECEPTOR_ACTIVATION.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-REACTOME_MET_RECEPTOR_ACTIVATION
-> MET Receptor Activation
-HGF
-HGFAC
-HPN
-MET
-SPINT1
-SPINT2
\ No newline at end of file
diff --git a/mspypeline/core/MSPInitializer.py b/mspypeline/core/MSPInitializer.py
index ae0bef1..d13ef5c 100644
--- a/mspypeline/core/MSPInitializer.py
+++ b/mspypeline/core/MSPInitializer.py
@@ -14,6 +14,11 @@
 
 
 class MSPInitializer:
+    """
+    | An initializer class which is responsible for creating the directory to save the default YAML configuration
+      file as well as reading and saving the specified settings.
+    | The initializer also operates as a means of passing stored configurations to the plotter classes.
+    """
     # set all file names that are required
     yml_file_name_tmp = "config_tmp.yml"
     yml_file_name = "config.yml"
@@ -25,16 +30,27 @@ class MSPInitializer:
     possible_pathways = sorted([x for x in os.listdir(os.path.join(path_package_config, pathway_path))
                                 if x.endswith(".txt")])
 
-    def __init__(self, dir_: str, file_path_yml: Optional[str] = None, loglevel=logging.DEBUG):
+    def __init__(self, path: str, file_path_yml: Optional[str] = None, loglevel=logging.DEBUG):
+        """
+        Parameters
+        ----------
+        path
+            location where the directory/txt folder to the data can be found.
+        file_path_yml
+            path to the yaml config file
+        loglevel
+            level of the logger
+        """
         self.logger = get_logger(self.__class__.__name__, loglevel=loglevel)
         # create a yaml file reader
         self.yaml = YAML()
-        # self.yaml.indent(mapping=2, sequence=4, offset=2)
-        self.yaml.indent(offset=2)
+        self.yaml.indent(mapping=2, sequence=4, offset=2)
+        # self.yaml.indent(offset=2)
         self.yaml.default_flow_style = False
         self.yaml.width = 4096
 
         # attributes that change upon changing the starting dir
+        #: configurations for the run. also saved configurations for the reader under the respective reader name
         self.configs = {}
         self.reader_data = {}
 
@@ -45,7 +61,7 @@ def __init__(self, dir_: str, file_path_yml: Optional[str] = None, loglevel=logg
         self._file_path_yaml = None
 
         # set the specified dirs
-        self.start_dir = dir_
+        self.start_dir = path
         if file_path_yml is not None:
             self.file_path_yaml = file_path_yml
 
@@ -74,19 +90,16 @@ def path_config(self):
 
     @property
     def file_path_yaml(self):
-        return self._file_path_yaml
-
-    @file_path_yaml.setter
-    def file_path_yaml(self, file_path_yml: str):
         """
+        Setting the yaml file path will set the configurations of the class to the ones specified in the file.
 
-        Parameters
-        ----------
-        file_path_yml
-            can be either:
-                - "default"
-                - "file"
-                - a path to a yml file
+        Note
+        -----
+        The value can be set to either:
+
+        - "default"
+        - "file"
+        - a path to a yml file
 
         Raises
         ------
@@ -96,6 +109,10 @@ def file_path_yaml(self, file_path_yml: str):
             if the file specified by the file_path_yml was not found
 
         """
+        return self._file_path_yaml
+
+    @file_path_yaml.setter
+    def file_path_yaml(self, file_path_yml: str):
         if file_path_yml.lower() == "default":
             self._file_path_yaml = self.get_default_yml_path()
         elif file_path_yml.lower() == "file":
@@ -117,12 +134,15 @@ def file_path_yaml(self, file_path_yml: str):
 
     def init_config(self):
         """
-        Creates the directory to save the configuration file and saves the configuration
+        | Creates the directory to save the configuration file if not present, updates and saves the configuration.
+        | The function is usually applied to ensure that configs are provided to the initializer in order to avoid
+          problems initializing the file reader with :meth:`read_data`.
         """
         os.makedirs(self.path_config, exist_ok=True)
         self.update_config_file()
 
     def has_yml_file(self) -> bool:
+
         if not os.path.isdir(self.start_dir):
             return False
         if "config" in os.listdir(self.start_dir):
@@ -134,7 +154,7 @@ def has_yml_file(self) -> bool:
         return False
 
     def get_default_yml_path(self) -> str:
-        self.logger.debug("Loading default yml file from: %s, since no (valid) file was selected",
+        self.logger.debug("Loading default yml file from: %s, since 'default' or no (valid) file was selected",
                           path_package)
         return os.path.join(path_package_config, MSPInitializer.default_yml_name)
 
@@ -185,6 +205,12 @@ def update_config_file(self):
         os.rename(yml_file_loc_tmp, yml_file_loc)
 
     def read_data(self):
+        """
+        | Initiates the file reader by providing the directory and the configs to the reader.
+        | The configs for the reader are taken from the configs from the name of the reader as key. E.g. mqreader.
+        | In turn a :class:`~mspypeline.helpers.Utils.DataDict` is generated to provide the mapping to the input data
+          (*reader_data*) for the further analysis with the :ref:`mspypeline plotters <plotters>`.
+        """
         for Reader in BaseReader.__subclasses__():
             Reader: Type[BaseReader]  # for IDE hints
             try:
@@ -196,6 +222,6 @@ def read_data(self):
                 self.logger.debug("No files found for reader: %s", Reader.name)
 
         # read all proteins and receptors of interest from the config dir
-        self.logger.info("Reading proteins and receptors of interest")
+        self.logger.info("Reading pathway and GO list of interest")
         self.interesting_proteins, self.go_analysis_gene_names = self.init_interest_from_txt()
         self.update_config_file()
diff --git a/mspypeline/core/MSPPlots/BasePlotter.py b/mspypeline/core/MSPPlots/BasePlotter.py
index d01c47d..f05a515 100644
--- a/mspypeline/core/MSPPlots/BasePlotter.py
+++ b/mspypeline/core/MSPPlots/BasePlotter.py
@@ -16,14 +16,11 @@
 from mspypeline.file_reader import BaseReader
 from mspypeline.plotting_backend import matplotlib_plots
 from mspypeline.modules import default_normalizers, Normalization, DataTree
-from mspypeline.helpers import get_number_rows_cols_for_fig, get_number_of_non_na_values, \
-    get_intersection_and_unique, get_logger, dict_depth, add_end_docstrings, make_contrasts
+from mspypeline.helpers import get_number_of_non_na_values, get_intersection_and_unique, \
+    get_logger, dict_depth, add_end_docstrings, make_contrasts
 
 # TODO VALIDATE descriptive plots not changing between log2 and non log2
 
-FIG_FORMAT = ".pdf"
-
-
 def validate_input(f):
     """
     Ensures that the function input, dfs_to_use and levels are passed as lists.
@@ -32,7 +29,6 @@ def validate_input(f):
     ----------
     f
         method that will be decorated
-
     """
     @functools.wraps(f)
     def wrapper(self, *args, **kwargs):
@@ -62,9 +58,9 @@ def wrapper(self, *args, **kwargs):
 Parameters
 ----------
 dfs_to_use
-    which DataFrames should be plotted
+    which dataframes/intensities should be plotted
 levels
-    which levels should be plotted
+    at which level of the data tree should the data be compared
 kwargs
     accepts kwargs
 
@@ -81,6 +77,13 @@ def wrapper(self, *args, **kwargs):
 
 
 class BasePlotter:
+    """
+    | Base plotter to create plots.
+    | The two main methods of the Base plotter comprise *"get_"* functions to calculate and provide the data for the
+      *"plot_"* functions. The latter incorporates the *"get_"* functions as well as functions from the matplotlib
+      backend to combine data calculation, plotting and saving of the results in one method.
+    """
+
     possible_plots = [
         "plot_detection_counts", "plot_detected_proteins_per_replicate", "plot_intensity_histograms",
         "plot_relative_std", "plot_rank", "plot_pathway_analysis",
@@ -98,12 +101,10 @@ def __init__(
             go_analysis_gene_names: Optional[Dict[str, pd.Series]] = None,
             configs: Optional[dict] = None,
             required_reader: Optional[str] = None,
-            intensity_entries=(),
-            loglevel=logging.DEBUG
+            intensity_entries: Tuple[str, str, str] = (),
+            loglevel: int = logging.DEBUG
     ):
         """
-        Base plotter to create plots.
-
         Parameters
         ----------
         start_dir
@@ -111,7 +112,7 @@ def __init__(
         reader_data
             mapping to provide input data
         intensity_df_name
-            name of the key with input data
+            name/key to input data
         interesting_proteins
             mapping with pathway proteins to analyze
         go_analysis_gene_names
@@ -119,7 +120,7 @@ def __init__(
         configs
             mapping of configuration
         required_reader
-            name of the reader
+            name of the file reader
         intensity_entries
             tuple of (key in all_tree_dict, prefix in data, name in plot). See :meth:`add_intensity_column`.
         loglevel
@@ -178,14 +179,14 @@ def __init__(
     @classmethod
     def from_MSPInitializer(cls, mspinit_instance: MSPInitializer, **kwargs) -> "BasePlotter":
         """
-        Creates a BasePlotter from a MSPInitializer.
+        | Creates a BasePlotter from a :class:`~MSPInitializer`.
 
         Parameters
         ----------
         mspinit_instance
-            Instance of an :class:`MSPInitializer` used to get correct inputs for the plotter.
+            instance of a :class:`~MSPInitializer` used to get correct inputs for the plotter.
         kwargs
-            All kwargs, which are passed to the :func:`BasePlotter.__init__` can be overwritten by passing as kwargs.
+            all kwargs, which are passed to the :func:`BasePlotter.__init__` can be overwritten by passing as kwargs.
 
         Returns
         -------
@@ -210,15 +211,14 @@ def from_MSPInitializer(cls, mspinit_instance: MSPInitializer, **kwargs) -> "Bas
     @classmethod
     def from_file_reader(cls, reader_instance: BaseReader, **kwargs):
         """
-        Creates a BasePlotter from a BaseReader.
+        | Creates a BasePlotter from a :class:`~BaseReader` (BasePlotter or MaxQuantPlotter).
 
         Parameters
         ----------
         reader_instance
-            Instance of an :class:`BaseReader` used to get correct inputs for the plotter.
+            instance of a :class:`~BaseReader` used to get correct inputs for the plotter.
         kwargs
-            All kwargs, which are passed to the :func:`BasePlotter.__init__` can be overwritten by passing as kwargs.
-
+            all kwargs, which are passed to the :func:`BasePlotter.__init__` can be overwritten by passing as kwargs.
 
         Returns
         -------
@@ -242,7 +242,7 @@ def from_file_reader(cls, reader_instance: BaseReader, **kwargs):
 
     def create_results(self):
         """
-        Creates all plots that where the "create_plot" setting is set to True.
+        Creates all plots that where chosen/set to True in the settings "create plot" (see :ref:`default-yaml`).
         """
         global_settings = self.configs.get("global_settings", {})
         self.logger.debug(f"got global settings: %s", global_settings)
@@ -262,20 +262,21 @@ def create_results(self):
     def add_intensity_column(self, option_name: str, name_in_file: str, name_in_plot: str,
                              scale: str = "normal", df: Optional[pd.DataFrame] = None):
         """
-        Adds a two options to all_intensities_dict and all_tree_dict, called option_name and option_name_log2.
+        | Adds two options to all_intensities_dict and all_tree_dict, called option_name and option_name_log2.
 
         Parameters
         ----------
         option_name
-            The name that the added data has internally, can be referred to via the df_to_use option
+            the name that the added data has internally, can be referred to via the df_to_use option e.g. *lfq* or
+            *ibaq*
         name_in_file
-            Prefix of the columns.
+            prefix of the columns e.g. *Intensity* or *LFQ intensity*
         name_in_plot
-            Shown name in the plots.
+            shown name in the plots e.g. *LFQ Intensity* or "iBAQ values"
         scale
-            Is the data in "normal" or in "log2" scale.
+            is the data in "normal" or in "log2" scale
         df
-            Can be passed to use instead of :attr:`BasePlotter.intensity_df`.
+            can be passed to use instead of :attr:`BasePlotter.intensity_df`
 
         """
         if df is None:
@@ -290,7 +291,8 @@ def add_intensity_column(self, option_name: str, name_in_file: str, name_in_plot
         if scale == "log2":
             option_name.replace("_log2", "")
         self.int_mapping.update({option_name: name_in_file, f"{option_name}_log2": name_in_file})
-        self.intensity_label_names.update({option_name: name_in_plot, f"{option_name}_log2": rf"$Log_2$ {name_in_plot}"})
+        self.intensity_label_names.update({option_name: name_in_plot,
+                                           f"{option_name}_log2": rf"$Log_2$ {name_in_plot}"})
 
         # extract all raw intensities from the dataframe
         # replace all 0 with nan and remove the prefix from the columns
@@ -321,16 +323,17 @@ def add_intensity_column(self, option_name: str, name_in_file: str, name_in_plot
             )
         })
 
-    def add_normalized_option(self, df_to_use: str, normalizer: Union[Type[Normalization.BaseNormalizer], Any], norm_option_name: str):
+    def add_normalized_option(self, df_to_use: str, normalizer: Union[Type[Normalization.BaseNormalizer], Any],
+                              norm_option_name: str):
         """
-        Adds new normalized keys to all_intensities_dict and all_tree_dict by getting the data from
-        all_intensities_dict[df_to_use] then applying the normalization and adding the new option with
-        :meth:`add_intensity_column`.
+        | Adds a new option/key of available data sets in all_intensities_dict and all_tree_dict by taking the data set
+          all_intensities_dict[df_to_use], performing the normalization on the data and then adding the new option with
+          :meth:`add_intensity_column`.
 
         Parameters
         ----------
         df_to_use
-            which data should be normalized
+            data set that should be normalized
         normalizer
             normalizer either derived from :class:`~mspypeline.module.Normalization.BaseNormalizer` or a class with a
             :func:`fit_transform`
@@ -357,13 +360,31 @@ def add_normalized_option(self, df_to_use: str, normalizer: Union[Type[Normaliza
         data = self.all_intensities_dict[df_to_use].copy()
         data = normalizer.fit_transform(data)
         self.add_intensity_column(new_option_name, norm_option_name + " ",
-                                  f"{norm_option_name.replace('_', ' ')} {self.intensity_label_names[df_to_use_no_log2]}",
+                                  f"{norm_option_name.replace('_', ' ')} "
+                                  f"{self.intensity_label_names[df_to_use_no_log2]}",
                                   scale="normal", df=data)
 
     def create_report(self):
         raise NotImplementedError
 
     def get_venn_group_data(self, df_to_use: str, level: int, non_na_function=get_number_of_non_na_values):
+        """
+        | Calculates which proteins can be compared between groups or are unique for a group of the selected level (see
+          :ref:`thresholding`) and then counts these proteins per group.
+
+        Parameters
+        ----------
+        df_to_use
+            which dataframe/intensity should be analysed
+        level
+            at which level of the data tree should the data be compared
+        non_na_function
+            threshold function to determine if proteins can be compared, default: :func:`get_number_of_non_na_values`
+        Returns
+        -------
+        Dict
+            Dictionary containing the proteins that can be compared per group
+        """
         n_children = {
             key: self.all_tree_dict[df_to_use][key].get_total_number_children()
             for key in self.all_tree_dict[df_to_use].level_keys_full_name[level]
@@ -376,6 +397,22 @@ def get_venn_group_data(self, df_to_use: str, level: int, non_na_function=get_nu
         return named_sets
 
     def get_venn_data_per_key(self, df_to_use: str, key: str):
+        """
+        | Counts the protein intensity values greater than 0 (number of detected proteins) for each replicate of a group
+          from the selected level.
+
+        Parameters
+        ----------
+        df_to_use
+            which dataframe/intensity should be analysed
+        key
+            which data node/group of samples should be compared
+
+        Returns
+        -------
+        Dict
+            Dictionary containing the proteins detected per sample
+        """
         df = self.all_tree_dict[df_to_use].aggregate(key, method=None) > 0
         per_group_dict = {column: set(df.index[df[column]]) for column in df}
         return per_group_dict
@@ -387,8 +424,24 @@ def get_venn_data_per_key(self, df_to_use: str, key: str):
     @validate_input
     def plot_venn_groups(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[int, Iterable[int]], **kwargs):
         """
-        Creates both a venn diagram and a bar-venn diagram comparing the similarity of groups on the selected level.
+        | Creates both a venn diagram and a bar-venn diagram comparing the similarity of the groups on the selected
+          level (based on protein counts).
+        | Here, the venn diagram depicts the number of identified proteins per group/set as circle. Overlapping areas
+          indicate the number of detected proteins that are shared between the overlapping groups. Non overlapping areas
+          indicate the number of proteins uniquely found in the group/set.
+        | The bar-venn diagram consists of two graphs, an upper bar diagram, tha indicates the number of unique or
+          shared proteins of a set or overlapping sets. The lower graph indicates which set or sets are being compared,
+          respectively, which protein count (upper graph) belongs to which comparison (lower graph).
+
+        .. note::
+            * A venn diagram can compare a maximum of 3 samples.
+            * A bar-venn diagram can compare more than 3 samples.
+            * If the selected level has more than 3 groups, only the bar-venn diagram will be created.
+            * If the selected level has more than 6 groups no diagram will be created
 
+        .. note::
+            To determine which proteins can be compared between the groups and which are unique for one group an
+            internal :ref:`threshold function <thresholding>` is applied.
         """
         plots = []
         for level in levels:
@@ -414,8 +467,20 @@ def plot_venn_groups(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[
     @validate_input
     def plot_venn_results(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[int, Iterable[int]], **kwargs):
         """
-        Creates both a venn diagram and a bar-venn diagram comparing the similarity of each group of the selected level.
+        | Creates both a venn diagram and a bar-venn diagram comparing the similarity of the replicates of each group
+          from the selected level (based on protein counts).
+        | Here, the venn diagram depicts the number of identified proteins per replicate/set as circle. Overlapping
+          areas indicate the number of detected proteins that are shared between the overlapping replicates. Non
+          overlapping areas indicate the number of proteins uniquely found in the replicate/set.
+        | The bar-venn diagram consists of two graphs, an upper bar diagram, tha indicates the number of unique or
+          shared proteins of a set or overlapping sets. The lower graph indicates which set or sets are being compared,
+          respectively, which protein count (upper graph) belongs to which comparison (lower graph).
 
+        .. note::
+            * A venn diagram can compare a maximum of 3 samples.
+            * A bar-venn diagram can compare more than 3 samples.
+            * If a group of the selected level has more than 3 replicates, only the bar-venn diagram will be created.
+            * If the selected level has more than 6 groups no diagram will be created
         """
         plots = []
         for level in levels:
@@ -435,21 +500,21 @@ def plot_venn_results(self, dfs_to_use: Union[str, Iterable[str]], levels: Union
 
     def get_detection_counts_data(self, df_to_use: str, level: int, **kwargs) -> Dict[str, pd.DataFrame]:
         """
-        Counts the number values greater than 0 per protein
+        | Counts the number of intensity values greater than 0 per protein (number of samples that the protein was
+          detected in) per group of the selected level.
 
         Parameters
         ----------
         df_to_use
-            DataFrame to use
+            which dataframes/intensities should be analysed
         level
-            level to use
+            at which level of the data tree should the data be compared
         kwargs
             accepts kwargs
-
         Returns
         -------
-        dict
-            DataFrame containing the counts
+        Dict
+            Dictionary with key *"counts"* to a DataFrame containing the counts of proteins detected in a sample
 
         """
         level_values = self.all_tree_dict[df_to_use].level_keys_full_name[level]
@@ -469,7 +534,7 @@ def get_detection_counts_data(self, df_to_use: str, level: int, **kwargs) -> Dic
     @validate_input
     def plot_detection_counts(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[int, Iterable[int]], **kwargs):
         """
-        Shows for each group of the selected level how often proteins were detected.
+        | Bar diagram showing how often proteins were detected in a number of replicates for each group.
 
         """
         plots = []
@@ -484,7 +549,25 @@ def plot_detection_counts(self, dfs_to_use: Union[str, Iterable[str]], levels: U
                     plots.append(plot)
         return plots
 
-    def get_detected_proteins_per_replicate_data(self, df_to_use: str, level: int, **kwargs) -> Dict[str, Dict[str, pd.Series]]:
+    def get_detected_proteins_per_replicate_data(self, df_to_use: str, level: int, **kwargs
+                                                 ) -> Dict[str, Dict[str, pd.Series]]:
+        """
+        | Counts the number of protein intensity values greater than 0 (number of detected proteins) per sample of a
+          group from the selected level.
+
+        Parameters
+        ----------
+        df_to_use
+            which dataframes/intensities should be analysed
+        level
+            at which level of the data tree should the data be compared
+        kwargs
+            accepts kwargs
+        Returns
+        -------
+        Dict
+            Dictionary with key *"all_height"* to a mapping of protein counts as Series per group
+        """
         # determine number of rows and columns in the plot based on the number of experiments
         level_values = self.all_tree_dict[df_to_use].level_keys_full_name[level]
         all_heights = {}
@@ -496,17 +579,21 @@ def get_detected_proteins_per_replicate_data(self, df_to_use: str, level: int, *
             for col in intensities:
                 h = len(intensities[col][intensities[col] > 0])
                 heights.append(h)
-            all_heights[experiment] = pd.Series(heights, index=["Total"] + intensities.columns.to_list(), name=experiment)
+            all_heights[experiment] = pd.Series(heights, index=["Total"] + intensities.columns.to_list(),
+                                                name=experiment)
         return {"all_heights": all_heights}
 
     @add_end_docstrings(plot_para_return_docstring.format(
         ":func:`~mspypeline.plotting_backend.matplotlib_plots.save_detected_proteins_per_replicate_results`"
     ))
     @validate_input
-    def plot_detected_proteins_per_replicate(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[int, Iterable[int]], **kwargs):
+    def plot_detected_proteins_per_replicate(self, dfs_to_use: Union[str, Iterable[str]],
+                                             levels: Union[int, Iterable[int]], **kwargs):
         """
-        Shows for each group the number of detected proteins per sample, as well as the overall total of detected
-        proteins. The average number of detected proteins is indicated as gray dashed line.
+        | Bar diagram showing the number of detected proteins per sample as well as the total number of detected proteins
+          for each group of a selected level.
+        | The average number of detected proteins per group is indicated as gray
+          dashed line.
 
         """
         plots = []
@@ -522,16 +609,35 @@ def plot_detected_proteins_per_replicate(self, dfs_to_use: Union[str, Iterable[s
         return plots
 
     def get_intensity_histograms_data(self, df_to_use: str, level: int, **kwargs):
+        """
+        | Get protein intensity values for each sample per group of the selected level.
+
+        Parameters
+        ----------
+        df_to_use
+            which dataframes/intensities should be analysed
+        level
+            at which level of the data tree should the data be compared
+        kwargs
+            accepts kwargs
+        Returns
+        -------
+        Dict
+            Dictionary with key *"hist_data"* to a DataFrame containing the protein intensity values per group
+        """
         return {"hist_data": self.all_tree_dict[df_to_use].groupby(level, method=None)}
 
     @add_end_docstrings(plot_para_return_docstring.format(
         ":func:`~mspypeline.plotting_backend.matplotlib_plots.save_intensity_histogram_results`"
     ))
     @validate_input
-    def plot_intensity_histograms(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[int, Iterable[int]], **kwargs):
+    def plot_intensity_histograms(self, dfs_to_use: Union[str, Iterable[str]],
+                                  levels: Union[int, Iterable[int]], **kwargs):
         """
-        Shows for each group a histogram of all intensities.
-
+        | For each group of the selected level a histogram is created that counts the occurrence of the binned intensity
+          values of each sample.
+        | If *"show_mean"* is set to True in the :ref:`configs <default-yaml>` the mean intensity of the plotted samples
+          of a group will be shown as gray dashed line.
         """
         plots = []
         for level in levels:
@@ -546,6 +652,20 @@ def plot_intensity_histograms(self, dfs_to_use: Union[str, Iterable[str]], level
         return plots
 
     def get_scatter_replicates_data(self, df_to_use: str, full_name: str) -> Dict[str, pd.DataFrame]:
+        """
+        | Get protein intensity values for each sample of a selected group.
+
+        Parameters
+        ----------
+        df_to_use
+            which dataframes/intensities should be analysed
+        full_name
+            which data node/group of samples should be compared
+        Returns
+        -------
+        Dict
+            Dictionary with key *"scatter_data"* to a DataFrame containing the protein intensity values per replicate
+        """
         data = self.all_tree_dict[df_to_use][full_name].aggregate(None)
         if data.empty:
             return {}
@@ -555,10 +675,14 @@ def get_scatter_replicates_data(self, df_to_use: str, full_name: str) -> Dict[st
         ":func:`~mspypeline.plotting_backend.matplotlib_plots.save_scatter_replicates_results`"
     ))
     @validate_input
-    def plot_scatter_replicates(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[int, Iterable[int]], **kwargs):
+    def plot_scatter_replicates(self, dfs_to_use: Union[str, Iterable[str]],
+                                levels: Union[int, Iterable[int]], **kwargs):
         """
-        For each group, scatters all samples against each other. Also shows unique proteins in the bottom and right
-        section of the plot. The legend also shows the r² of each pair wise scatter.
+        | For each group of the selected level, pairwise scatter comparisons of all replicates of a group are plotted
+          above each other in one graph (based on protein intensities).
+        | Unique proteins per replicate are shown at the bottom and right side of the graph (substitution of na values
+          by min value of data set). Pearsons's Correlation Coefficient r² is given in the legend and calculated based
+          on proteins of diagonal scatter/proteins that have a non na value in both samples compared.
 
         """
         plots = []
@@ -575,6 +699,21 @@ def plot_scatter_replicates(self, dfs_to_use: Union[str, Iterable[str]], levels:
         return plots
 
     def get_rank_data(self, df_to_use: str, full_name: str, **kwargs) -> Dict[str, pd.Series]:
+        """
+        | Get protein intensity values of the selected group and rank the proteins by their intensity value.
+
+        Parameters
+        ----------
+        df_to_use
+            which dataframes/intensities should be analysed
+        full_name
+            which data node/group of samples should be compared
+        Returns
+        -------
+        Dict
+            Dictionary with key *"rank_data"* to Series containing the protein intensities of the group ranked by
+            intensity value
+        """
         return {"rank_data": self.all_tree_dict[df_to_use][full_name].aggregate().sort_values(ascending=False)}
 
     @add_end_docstrings(plot_para_return_docstring.format(
@@ -583,11 +722,13 @@ def get_rank_data(self, df_to_use: str, full_name: str, **kwargs) -> Dict[str, p
     @validate_input
     def plot_rank(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[int, Iterable[int]], **kwargs):
         """
-        Creates one plot per group, where all intensities are sorted and plotted against their rank.
-        The highest intensity is rank 0 the lowest intensity is the number of proteins - 1. Additionally, if a protein
-        is part of a selected pathway it will get colored and the median rank of all proteins, which are part of a
-        pathway is indicated.
-
+        | Creates one plot per group (mean intensity of samples), where all proteins are sorted by intensity value and
+          plotted against their rank.
+        | The highest intensity accounts for rank 0 the lowest intensity for the number of proteins - 1 whereby proteins
+          with missing values are neglected. The median intensity of all proteins is given in the legend.
+        | Additionally, if a protein is part of a selected :ref:`pathway <pathway-proteins>` it will be presented in
+          color and the median rank of all proteins of a given pathway is indicated. Multiple pathways can be selected
+          and will be represented in the same graph as distinct groups.
         """
         plots = []
         for level in levels:
@@ -605,20 +746,19 @@ def plot_rank(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[int, It
 
     def get_relative_std_data(self, df_to_use: str, full_name: str, **kwargs) -> Dict[str, pd.DataFrame]:
         """
-        Provides the data for the relative_std_plot
+        | Calculate which proteins of a group can be used for the analysis (see :ref:`thresholding`) and filters proteins
+          below the threshold out.
 
         Parameters
         ----------
         df_to_use
-            which dataframe/intensity should be used
+            which dataframes/intensities should be analysed
         full_name
-            name of the experiment which should be accepted
-        kwargs
-            accepts kwargs
-
+            which data node/group of samples should be compared
         Returns
         -------
-        Dictionary with the intensity of the experiment and the relative standard deviations
+        Dict
+            Dictionary with key *"intensities"* to a DataFrame containing the protein intensities of the group
 
         """
         intensities = self.all_tree_dict[df_to_use][full_name].aggregate(None)
@@ -636,10 +776,14 @@ def get_relative_std_data(self, df_to_use: str, full_name: str, **kwargs) -> Dic
     @validate_input
     def plot_relative_std(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[int, Iterable[int]], **kwargs):
         """
-        Creates on plot per group with the relative standard deviation of each protein. Low deviation shows that
-        measured intensities are stable over multiple samples.
+        | Creates one plot per group of the selected level with the relative standard deviation of each protein between
+          the samples of a group. Low deviation shows that measured intensities are stable over multiple samples.
 
+        .. note::
+            To determine which proteins can be compared between the two samples an internal :ref:`threshold function
+            <thresholding>` is applied.
         """
+
         plots = []
         # TODO check with log2 thresholds
         for level in levels:
@@ -647,14 +791,39 @@ def plot_relative_std(self, dfs_to_use: Union[str, Iterable[str]], levels: Union
                 for full_name in self.all_tree_dict[df_to_use].level_keys_full_name[level]:
                     data = self.get_relative_std_data(df_to_use=df_to_use, full_name=full_name, **kwargs)
                     if data:
-                        plot_kwargs = dict(intensity_label=self.intensity_label_names[df_to_use], experiment_name=full_name,
-                                           df_to_use=df_to_use, level=level, save_path=self.file_dir_descriptive)
+                        plot_kwargs = dict(intensity_label=self.intensity_label_names[df_to_use],
+                                           experiment_name=full_name, df_to_use=df_to_use, level=level,
+                                           save_path=self.file_dir_descriptive)
                         plot_kwargs.update(**kwargs)
                         plot = matplotlib_plots.save_relative_std_results(**data, **plot_kwargs)
                         plots.append(plot)
         return plots
 
     def get_pathway_analysis_data(self, df_to_use: str, level: int, pathway: str, equal_var=True, **kwargs):
+        """
+        | Filters out all proteins of the given pathways for all samples per group of the selected level, then
+          calculates the pairwise significances between the groups with an independent t-test (see
+          :meth:`plot_pathway_analysis`) for all those proteins that can be compared (see :ref:`thresholding`).
+
+        Parameters
+        ----------
+        df_to_use
+            which dataframes/intensities should be analysed
+        level
+            at which level of the data tree should the data be compared
+        pathway
+            which pathway should be analysed
+        equal_var
+            should equal variance be assumed
+        kwargs
+            accepts kwargs
+        Returns
+        -------
+        Dict
+            Dictionary with keys *"protein_intensities"* to a DataFrame containing the protein intensities of detected
+            proteins from all given pathways per group and *"significances"* to a DataFrame containing the calculated
+            significances between groups for each protein of all given pathways
+        """
         level_keys = self.all_tree_dict[df_to_use].level_keys_full_name[level]
         found_proteins = set(self.interesting_proteins[pathway])
         found_proteins &= set(self.all_intensities_dict[df_to_use].index)
@@ -683,7 +852,8 @@ def get_pathway_analysis_data(self, df_to_use: str, level: int, pathway: str, eq
                     per_protein_significant.append(test[1])
             significances.append(per_protein_significant)
         significances = pd.DataFrame(significances, index=protein_intensities.index,
-                                     columns=pd.MultiIndex.from_tuples([(e1, e2) for e1, e2 in combinations(level_keys, 2)]))
+                                     columns=pd.MultiIndex.from_tuples([(e1, e2) for e1, e2 in
+                                                                        combinations(level_keys, 2)]))
         return {"protein_intensities": protein_intensities, "significances": significances}
 
     @add_end_docstrings(plot_para_return_docstring.format(
@@ -692,10 +862,17 @@ def get_pathway_analysis_data(self, df_to_use: str, level: int, pathway: str, eq
     @validate_input
     def plot_pathway_analysis(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[int, Iterable[int]], **kwargs):
         """
-        Creates one Plot per selected pathway. Then for each group one row is added and all pairwise comparisons
-        between groups are calculated with an independent
-        `t-test <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.ttest_ind.html>`__.
+        | Creates two plots per selected :ref:`pathway <pathway-proteins>`, one indicating significances and the other
+          without.
+        | For each protein of the pathway a subplot is created displaying the intensities of the protein for all
+          groups and significances are calculated for each pairwise comparison between groups with an independent
+          `t-test <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.ttest_ind.html>`__.
+        | For a group of multiple samples, the protein intensity per sample is shown as a single scatter dot colored
+          per group.
 
+        .. note::
+            To determine which proteins can be compared between two groups an internal :ref:`threshold function
+            <thresholding>` is applied.
         """
         plots = []
         for level in levels:
@@ -713,9 +890,10 @@ def plot_pathway_analysis(self, dfs_to_use: Union[str, Iterable[str]], levels: U
     def get_pathway_timeline_data(self):
         pass
 
-    def plot_pathway_timecourse(self, df_to_use: str = "raw", show_suptitle: bool = False, levels: Iterable = (2,), **kwargs):
+    def plot_pathway_timecourse(self, df_to_use: str = "raw", show_suptitle: bool = False,
+                                levels: Iterable = (2,), **kwargs):
         """
-        not yet implemented - will advance code later
+        not yet implemented
         """
         """
         group_colors = {
@@ -728,12 +906,14 @@ def plot_pathway_timecourse(self, df_to_use: str = "raw", show_suptitle: bool =
             level_keys = self.all_tree_dict[df_to_use].level_keys_full_name[level]
             groups = {k: "SD" if "SD" in k else k.split("_")[1] for k in level_keys}
             if len(set(groups.values()) - set(group_colors.keys())):
-                self.logger.warning("Skipping pathway timeline plot because of incorrect match between found groups and target groups")
+                self.logger.warning("Skipping pathway timeline plot because of incorrect match between found groups and 
+                target groups")
                 continue
             x_values = {}
             # for key in level_keys:
             #     sample_names = self.all_tree_dict[df_to_use][key].aggregate(None).columns
-            #     x_values.update({sample: sum([int(s.replace("W", "")) for s in sample.split("_") if s.endswith("W")]) for sample in sample_names})
+            #     x_values.update({sample: sum([int(s.replace("W", "")) for s in sample.split("_") if s.endswith("W")]) 
+            for sample in sample_names})
             for key in level_keys:
                 x_values.update({key: sum([int(s.replace("W", "")) for s in key.split("_") if s.endswith("W")])})
             max_time = max(x_values.values())
@@ -743,14 +923,38 @@ def plot_pathway_timecourse(self, df_to_use: str = "raw", show_suptitle: bool =
                 found_proteins &= set(self.all_intensities_dict[df_to_use].index)
                 found_proteins = sorted(list(found_proteins))
                 if len(found_proteins) < 1:
-                    self.logger.warning("Skipping pathway %s in pathway timeline because no proteins were found", pathway)
+                    self.logger.warning("Skipping pathway %s in pathway timeline because no proteins were found", 
+                    pathway)
                     continue
         """
 
     def get_experiment_comparison_data(self, df_to_use: str, full_name1: str, full_name2: str):
+        """
+        | Gets protein intensities for all samples of a given group, then calculates the proteins that can be compared
+          between groups and those that are unique for each group (see :ref:`thresholding`) and takes the mean intensity
+          of these proteins.
+
+        Parameters
+        ----------
+        df_to_use
+            which dataframes/intensities should be analysed
+        full_name1
+            name of the first data node/group that should be compared to 'full_name2'
+        full_name2
+            name of the second data node/group that should be compared to 'full_name1'
+
+        Returns
+        -------
+        Dict
+            Dictionary with keys *"protein_intensities_sample1"* and *"protein_intensities_sample2"* to Series
+            containing the mean protein intensities of sample 1 and sample 2  and *"exclusive_sample1"* and
+            *"exclusive_sample2"* to Series containing the mean intensities of unique proteins for sample 1 and
+            sample 2.
+        """
         protein_intensities_sample1 = self.all_tree_dict[df_to_use][full_name1].aggregate(None)
         protein_intensities_sample2 = self.all_tree_dict[df_to_use][full_name2].aggregate(None)
-        mask, exclusive_1, exclusive_2 = get_intersection_and_unique(protein_intensities_sample1, protein_intensities_sample2)
+        mask, exclusive_1, exclusive_2 = get_intersection_and_unique(protein_intensities_sample1,
+                                                                     protein_intensities_sample2)
         # flatten all replicates
         exclusive_sample1 = protein_intensities_sample1[exclusive_1].mean(axis=1)
         exclusive_sample2 = protein_intensities_sample2[exclusive_2].mean(axis=1)
@@ -769,11 +973,19 @@ def get_experiment_comparison_data(self, df_to_use: str, full_name1: str, full_n
         ":func:`~mspypeline.plotting_backend.matplotlib_plots.save_experiment_comparison_results`"
     ))
     @validate_input
-    def plot_experiment_comparison(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[int, Iterable[int]], **kwargs):
-        # TODO correlation of log2 and not log 2 data is different
+    def plot_experiment_comparison(self, dfs_to_use: Union[str, Iterable[str]],
+                                   levels: Union[int, Iterable[int]], **kwargs):
         """
-        Creates all pairwise comparisons between available groups and shows r² of the data.
+        | Creates a pairwise scatter comparison between each combination of the groups of the selected level (based on
+          protein intensities).
+        | For each comparison a new plot is created. Unique proteins per replicate are shown at the bottom and right
+          side of the graph (substitution of na values by min*0.95 value of sample data set). Pearsons's Correlation
+          Coefficient r² is given in the legend and calculated based on proteins of diagonal scatter/proteins that have
+          a non na value in both samples.
 
+        .. note::
+            To determine which proteins can be compared between the two groups and which are unique for one group an
+            internal :ref:`threshold function <thresholding>` is applied.
         """
         plots = []
         for level in levels:
@@ -781,19 +993,39 @@ def plot_experiment_comparison(self, dfs_to_use: Union[str, Iterable[str]], leve
                 for ex1, ex2 in combinations(self.all_tree_dict[df_to_use].level_keys_full_name[level], 2):
                     data = self.get_experiment_comparison_data(df_to_use=df_to_use, full_name1=ex1, full_name2=ex2)
                     if data:
-                        plot_kwargs = dict(intensity_label=self.intensity_label_names[df_to_use], sample1=ex1, sample2=ex2,
-                                           df_to_use=df_to_use, level=level, save_path=self.file_dir_descriptive)
+                        plot_kwargs = dict(intensity_label=self.intensity_label_names[df_to_use], sample1=ex1,
+                                           sample2=ex2, df_to_use=df_to_use, level=level,
+                                           save_path=self.file_dir_descriptive)
                         plot_kwargs.update(**kwargs)
                         plot = matplotlib_plots.save_experiment_comparison_results(**data, **plot_kwargs)
                         plots.append(plot)
         return plots
 
     def get_go_analysis_data(self, df_to_use: str, level: int):
+        """
+        | Calculates an enrichment analysis for all samples per group of the selected level and for each given GO list
+          (see :meth:`plot_go_analysis`). Significances are calculated with a fisher exact test.
+
+        Parameters
+        ----------
+        df_to_use
+            which dataframes/intensities should be analysed
+        level
+            at which level of the data tree should the data be compared
+        Returns
+        -------
+        Dict
+            Dictionary with keys *"heights"* to a ddict containing the counts of proteins per sample of each given
+            GO list, *"test_results"* to a ddict containing the corresponding Fisher's exact test results and
+            *"go_length"* to a list containing the total number of proteins of each chosen GO list
+
+        """
         if not self.go_analysis_gene_names:
             return {}
         background = set(self.all_intensities_dict[df_to_use].index)
         heights = ddict(list)
         test_results = ddict(list)
+        go_length = []
         for compartiment, all_pathway_genes in self.go_analysis_gene_names.items():
             all_pathway_genes = set(all_pathway_genes)
             # get all pathway genes that were detected throughout all experiments
@@ -802,7 +1034,8 @@ def get_go_analysis_data(self, df_to_use: str, level: int):
             not_pathway_genes = background - pathway_genes
             # sanity check
             assert pathway_genes | not_pathway_genes == background
-            heights["background"].append(len(pathway_genes))
+            heights["Total"].append(len(pathway_genes))
+            go_length.append(len(all_pathway_genes))
             for experiment in self.all_tree_dict[df_to_use].level_keys_full_name[level]:
                 # create df with intensity means for specific experiment over all replicates
                 mean_intensity = self.all_tree_dict[df_to_use][experiment].aggregate()
@@ -823,7 +1056,7 @@ def get_go_analysis_data(self, df_to_use: str, level: int):
                 # self.logger.debug(f"{chi2}, {dof}, {ex}")
                 # self.logger.debug(f"{compartiment} {experiment}: table: {table} fisher: {pvalue:.4f}, chi2: {p:.4f}")
                 test_results[experiment].append(pvalue)
-        return {"heights": heights, "test_results": test_results}
+        return {"heights": heights, "test_results": test_results, "go_length": go_length}
 
     @add_end_docstrings(plot_para_return_docstring.format(
         ":func:`~mspypeline.plotting_backend.matplotlib_plots.save_go_analysis_results`"
@@ -831,13 +1064,16 @@ def get_go_analysis_data(self, df_to_use: str, level: int):
     @validate_input
     def plot_go_analysis(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[int, Iterable[int]], **kwargs):
         """
-        Creates an enrichment analysis for each selected GO Term file. For each go term list a list pathway genes
-        is created by taking all detected proteins and taking the intersection with the proteins from the file. Then
-        a list of non pathway genes is created by taking all detected proteins and removing the pathway genes.
-        Then a list of experiment genes and non experiment genes is created in a similar fashion.
-        Lastly, a
-        `fisher exact test <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.fisher_exact.html>`__
-        is calculated with the following contingency table and the "greater" alternative.
+        | Creates an enrichment analysis for each selected GO Term file (based on protein counts).
+        | First, for each GO term list a list *"pathway_genes"* is created by taking the intersection of the proteins
+          from the GO list and the total detected proteins.
+        | Secondly, a list of *"non_pathway_genes"* is created which comprises total detected proteins but proteins in
+          *"pathway_genes"*.
+        | Third, a list of *"experiment_genes"* and *"non_experiment_genes"* is created in a similar fashion where an
+          experiment references to a sample/group of samples of the data set.
+        | Lastly, a `fisher exact test
+          <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.fisher_exact.html>`__ is calculated with the
+          following contingency table and the "greater" alternative.
 
         +------------------------+--------------------------------------+------------------------------------------+
         |                        | in pathway                           | not in pathway                           |
@@ -847,6 +1083,7 @@ def plot_go_analysis(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[
         | **not in experiment**  | not_experiment_genes & pathway_genes | not_experiment_genes & not_pathway_genes |
         +------------------------+--------------------------------------+------------------------------------------+
 
+        | The resulting p-value is thus, also dependent on the overall protein count of the sample/group of samples.
         """
         plots = []
         for level in levels:
@@ -861,7 +1098,35 @@ def plot_go_analysis(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[
                     plots.append(plot)
         return plots
 
-    def get_r_volcano_data(self, g1: str, g2: str, df_to_use: str, level: int):
+    def get_r_volcano_data(self, g1: str, g2: str, df_to_use: str):
+        """
+        | Gets the protein intensities for all samples of the two given groups, then calculates the proteins that can be
+          compared between groups and those unique for each group (see :ref:`thresholding`).
+        | Hands over the protein intensities to be compared to the R package ``limma`` that outputs the logFC, p-value,
+          adjusted p value and other data which is calculated based on a `moderated t-statistic
+          <https://bioconductor.org/packages/release/bioc/vignettes/limma/inst/doc/usersguide.pdf>`__.
+        | Results are converted back to python format afterwards.
+
+        .. note::
+            This function uses the R package limma which will be automatically downloaded the first time this analysis
+            is performed
+
+        Parameters
+        ----------
+        g1
+            first sample that should be analysed (downregulated)
+        g2
+            second sample that should be analysed (upregulated)
+        df_to_use
+            which dataframes/intensities should be analysed
+
+        Returns
+        -------
+        Dict
+            Dictionary with keys *"volcano_data"* to a DataFrame containing processed output of the ``limma.eBayes``
+            analysis, *"unique_g1"* and *"unique_g2"* to Series containing the unique protein intensities per group
+
+        """
         # import r interface package
         from rpy2.robjects.packages import importr
         from rpy2.robjects import pandas2ri
@@ -920,38 +1185,93 @@ def get_r_volcano_data(self, g1: str, g2: str, df_to_use: str, level: int):
 
         return {"volcano_data": plot_data, "unique_g1": unique_g1, "unique_g2": unique_g2}
 
-    @add_end_docstrings(plot_para_return_docstring.format(
-        ":func:`~mspypeline.plotting_backend.matplotlib_plots.save_volcano_results`"
-    ))
     @validate_input
-    def plot_r_volcano(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[int, Iterable[int]], **kwargs):
+    def plot_r_volcano(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[int, Iterable[int]],
+                       sample1: str = None, sample2: str = None, **kwargs):
         """
-        Creates a plot for each pairwise comparison of the available groups. The volcano plot shows the log fold change
-        between the two different conditions against the p value. The p value is determined using the R limma package.
-        A p value and fold change cutoff are applied and all proteins below the cutoff are considered non significant.
-        Additionally, the unique proteins of both conditions are shown next to the volcano plot.
+        | Creates two plots for each pairwise comparison of the groups of the selected level where one plot has a set of
+          proteins annotated and the other does not.
+        | The volcano plot shows the log2 fold change between the two different conditions against the -log10(p value)
+          (based on protein intensities). The p value is determined using the R limma package (`moderated t-statistic
+          <https://bioconductor.org/packages/release/bioc/vignettes/limma/inst/doc/usersguide.pdf>`__).
+          A p value and fold change cutoff are applied and all proteins below the cutoff are considered non significant.
+          Additionally, the intensities of unique proteins of both conditions are shown next to the volcano plot.
 
         .. note::
-           should be used with log2 intensities
+           * should be used with log2 intensities
+           * minimum of 3 samples per group required
 
+        .. note::
+            To determine which proteins can be compared between the two groups and which are unique for one group an
+            internal :ref:`threshold function <thresholding>` is applied.
+
+        Parameters
+        ----------
+        dfs_to_use
+            which dataframes/intensities should be plotted
+        levels
+            at which level of the data tree should the data be compared
+        sample1
+            first sample that should be compared (downregulated)
+        sample2
+            second sample that should be compared (upregulated)
+        kwargs
+            accepts kwargs
+        Returns
+        -------
+        List
+            A list of all created plots.
         """
         plots = []
+        plot_once = False
         for level in levels:
             for df_to_use in dfs_to_use:
-                level_keys = self.all_tree_dict[df_to_use].level_keys_full_name[level]
+                if sample1 and sample2:
+                    level_keys = [sample1, sample2]
+                    plot_once = True
+                else:
+                    level_keys = self.all_tree_dict[df_to_use].level_keys_full_name[level]
                 for g1, g2 in combinations(level_keys, 2):
-                    data = self.get_r_volcano_data(g1, g2, df_to_use, level)
+                    data = self.get_r_volcano_data(g1, g2, df_to_use)
                     if data:
-                        plot_kwargs = dict(g1=g1, g2=g2, save_path=self.file_dir_volcano, df_to_use=df_to_use, level=level,
+                        plot_kwargs = dict(g1=g1, g2=g2, save_path=self.file_dir_volcano, df_to_use=df_to_use,
                                            intensity_label=self.intensity_label_names[df_to_use],
                                            interesting_proteins=self.interesting_proteins, split_files=True)
                         plot_kwargs.update(**kwargs)
                         plot = matplotlib_plots.save_volcano_results(**data, **plot_kwargs)
                         plots.append(plot)
+            if plot_once:
+                break
         return plots
 
     def get_pca_data(self, df_to_use: str, level: int, n_components: int = 2, fill_value: float = 0,
                      no_missing_values: bool = True, fill_na_before_norm: bool = False, **kwargs):
+        """
+        | Gets protein intensities for all samples per group processes data according to given arguments and then
+          performs a dimensionality reduction (PCA) using ``sklearn.decomposition.PCA``.
+
+        Parameters
+        ----------
+        df_to_use
+            which dataframes/intensities should be analysed
+        level
+            at which level of the data tree should the data be compared
+        n_components
+            how many principal components should be calculated
+        fill_value
+            if data should be interpolated, which fill value should be used
+        no_missing_values
+            should missing values be neglected
+        fill_na_before_norm
+            if data should be interpolated, should this be done before normalisation
+        kwargs
+            accepts kwargs
+        Returns
+        -------
+        Dict
+            Dictionary with keys *"pca_data"* to a DataFrame containing the output of a PCA using `
+            ``sklearn.decomposition`` and *"pca_fit"* to a PCA object that was fitted to normalized input data
+        """
         data_input = self.all_tree_dict[df_to_use].groupby(level, method=None)
         if no_missing_values:
             data_input = data_input.dropna(axis=0)
@@ -975,10 +1295,14 @@ def get_pca_data(self, df_to_use: str, level: int, n_components: int = 2, fill_v
     @validate_input
     def plot_pca_overview(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[int, Iterable[int]], **kwargs):
         """
-        Creates a PCA plot comparing all components against each other. The default is 2 components and only compares
-        PC 1 vs PC 2. Each group is colored differently.
-
-        """
+        | Creates a PCA plot comparing all components against each other. The default is 2 components where only PC 1
+          and PC 2 are compared.
+        | The PCA results do not change in dependence on the chosen level, however, determining the level on which the
+          data should be compared influences the coloring of the scatter elements. Each group of the selected level is
+          colored differently.
+        | Multiple different analysis options can be chosen to generate a PCA (see: :ref:`multiple option config
+          <default-yaml>`).
+       """
         plots = []
         for level in levels:
             for df_to_use in dfs_to_use:
@@ -993,21 +1317,22 @@ def plot_pca_overview(self, dfs_to_use: Union[str, Iterable[str]], levels: Union
 
     def get_boxplot_data(self, df_to_use: str, level: int, **kwargs) -> dict:
         """
-        Generates data for the boxplot, where columns are sorted by median intensities.
+        | Get protein intensities for all samples per group of the selected level and then sorts samples by their median
+          intensity.
 
         Parameters
         ----------
         df_to_use
-            which dataframe should be used
+            which dataframes/intensities should be analysed
         level
-            on which level should the data be grouped
+            at which level of the data tree should the data be compared
         kwargs
             accepts kwargs
-
         Returns
         -------
-        dict
-            A dictionary with the the protein intensities
+        Dict
+            Dictionary with key *"protein_intensities"* to a DataFrame containing the protein intensities per group
+            sorted by median intensity
         """
         df = self.all_tree_dict[df_to_use].groupby(level)
         # sort columns by median intensity
@@ -1020,7 +1345,8 @@ def get_boxplot_data(self, df_to_use: str, level: int, **kwargs) -> dict:
     @validate_input
     def plot_boxplot(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[int, Iterable[int]], **kwargs):
         """
-        Creates one boxplot per group sorted by median intensity.
+        | Creates one boxplot per group sorted by median intensity. The boxplot is part of the
+          :ref:`Normalization overview <norm-overview>`.
 
         """
         plots = []
@@ -1035,7 +1361,28 @@ def plot_boxplot(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[int,
                     plots.append(plot)
         return plots
 
-    def get_n_protein_vs_quantile_data(self, df_to_use: str, level: int, quantile_range: Optional[np.array] = None, **kwargs):
+    def get_n_protein_vs_quantile_data(self, df_to_use: str, level: int, quantile_range: Optional[np.array] = None,
+                                       **kwargs):
+        """
+        | Gets protein intensities for all samples per group, counts the number of intensity values greater than 0
+          (total number of detected proteins) and the quantiles per sample.
+
+        Parameters
+        ----------
+        df_to_use
+            which dataframes/intensities should be analysed
+        level
+            at which level of the data tree should the data be compared
+        quantile_range
+            which quantile range should be used for analysis
+        kwargs
+            accepts kwargs
+        Returns
+        -------
+        Dict
+            Dictionary with keys *"quantiles"* to a DataFrame of calculated quantiles per sample and *"n_proteins"* to a
+            Series of total number of identified proteins per sample
+        """
         if quantile_range is None:
             quantile_range = np.arange(0.05, 1, 0.05)
         df = self.all_tree_dict[df_to_use].groupby(level)
@@ -1047,11 +1394,15 @@ def get_n_protein_vs_quantile_data(self, df_to_use: str, level: int, quantile_ra
         ":func:`~mspypeline.plotting_backend.matplotlib_plots.save_n_proteins_vs_quantile_results`"
     ))
     @validate_input
-    def plot_n_proteins_vs_quantile(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[int, Iterable[int]], **kwargs):
+    def plot_n_proteins_vs_quantile(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[int, Iterable[int]],
+                                    **kwargs):
         """
-        Plot the intensity from df_to_use against the number of identified proteins. There should be no correlation
-        (a perpendicular / vertical line) between the x and y axis. Otherwise this indicates that intensity values
-        are probably not missing at random but due to the detection limit.
+        | Plots the protein intensities against the number of identified proteins.
+        | Samples are indicated as a horizontal line of scatter dots where the color anf x position of a dot indicate
+          the intensity value of the respective quantile. The y position of the dots of a sample indicate the total
+          number of detected proteins in that sample.
+        | Solid, rather vertical lines indicate a linear fit of each quantile for all the samples.
+        | This plot is part of the :ref:`Normalization overview <norm-overview>`.
 
         """
         plots = []
@@ -1067,6 +1418,22 @@ def plot_n_proteins_vs_quantile(self, dfs_to_use: Union[str, Iterable[str]], lev
         return plots
 
     def get_kde_data(self, df_to_use: str, level: int, **kwargs) -> Dict[str, pd.DataFrame]:
+        """
+        | Gets the protein intensities for all samples per group of the selected level.
+
+        Parameters
+        ----------
+        df_to_use
+            which dataframes/intensities should be analysed
+        level
+            at which level of the data tree should the data be compared
+        kwargs
+            accepts kwargs
+        Returns
+        -------
+        Dict
+            Dictionary with key *"intensities"* to a DataFrame containing the protein intensities per group
+        """
         intensities = self.all_tree_dict[df_to_use].groupby(level)
         return {"intensities": intensities}
 
@@ -1076,7 +1443,8 @@ def get_kde_data(self, df_to_use: str, level: int, **kwargs) -> Dict[str, pd.Dat
     @validate_input
     def plot_kde(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[int, Iterable[int]], **kwargs):
         """
-        Kernel density estimate plot.
+        | Kernel density estimate plot where one density graph per sample is plotted indicating the Intensity on the x
+          axis and the density on the y axis. The KDE is part of the :ref:`Normalization overview <norm-overview>`.
 
         """
         plots = []
@@ -1099,10 +1467,13 @@ def plot_normalization_overview(
             self, dfs_to_use: Union[str, Iterable[str]], levels: Union[int, Iterable[int]], **kwargs
     ) -> List[Tuple[plt.Figure, Tuple[plt.Axes, plt.Axes, plt.Axes, plt.Axes]]]:
         """
-        Combines three different plots into a single plot to provide an overview of the distribution of the data.
-        This can be useful to compare different normalization methods. The three different combined plots are:
-        :meth:`plot_kde`, :meth:`plot_boxplot`, :meth:`plot_n_proteins_vs_quantile`.
-
+        | The Normalization overview offers the opportunity to examine different aspects of the data in three distinct
+          plots. For each :ref:`normalization method <hyperparameter>` provided an additional page will be attached to
+          the resulting pdf file starting with the raw or not normalized data. That way it is possible to get a better
+          understanding of the effects of the normalization methods on the data, to inspect the different approaches and
+          to find the best suitable normalization for the data.
+        | The normalization overview combines the plots :meth:`~mspypeline.BasePlotter.plot_kde`,
+          :meth:`~mspypeline.BasePlotter.plot_n_proteins_vs_quantile` and :meth:`~mspypeline.BasePlotter.plot_boxplot`.
         """
         plots = []
         for level in levels:
@@ -1123,6 +1494,29 @@ def plot_normalization_overview(
 
     def get_intensity_heatmap_data(self, df_to_use: str, level: int, sort_index: bool = False,
                                    sort_index_by_missing: bool = True, sort_columns_by_missing: bool = True, **kwargs):
+        """
+        | Get the protein intensities for all samples per group of the selected level and sorts samples and proteins
+          according to settings.
+
+        Parameters
+        ----------
+        df_to_use
+            which dataframes/intensities should be analysed
+        level
+            at which level of the data tree should the data be compared
+        sort_index
+            should proteins be sorted alphanumerically
+        sort_index_by_missing
+            should proteins be sorted by number of missing values across samples
+        sort_columns_by_missing
+            should samples be sorted by number of missing values
+        kwargs
+            accepts kwargs
+        Returns
+        -------
+        Dict
+            Dictionary with key *"intensities"* to a DataFrame containing protein intensities of samples
+        """
         intensities = self.all_tree_dict[df_to_use].groupby(level)
         if sort_index_by_missing:
             index = intensities.isna().sum(axis=1).sort_values().index
@@ -1141,10 +1535,20 @@ def get_intensity_heatmap_data(self, df_to_use: str, level: int, sort_index: boo
         ":func:`~mspypeline.plotting_backend.matplotlib_plots.save_intensities_heatmap_result`"
     ))
     @validate_input
-    def plot_intensity_heatmap(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[int, Iterable[int]], **kwargs):
-        """
-        Heatmap for all protein intensities. Adds one row per group. Can be used to spot weird patterns in normalization
-        methods.
+    def plot_intensity_heatmap(self, dfs_to_use: Union[str, Iterable[str]], levels: Union[int, Iterable[int]],
+                               **kwargs):
+        """
+        | The Heatmap overview offers the opportunity to visually inspect how the distribution of protein intensities
+          and missing values for each sample.
+        | The Heatmap shows protein intensities. Samples are shown in rows on the y axis and proteins on the x axis.
+        | Missing values are colored in gray. The heatmap can be used to spot patterns in the different normalization
+          methods and to understand how different intensity types affect the data.
+        | As in the normalization overview, with this method, a separate plot is generated for each normalizer and
+          attached to the document as another page. The heatmap overview can help to understand the differences between
+          the distinct :ref:`protein intensity options <hyperparameter>` and
+          :ref:`normalization methods <hyperparameter>` as it allows for instance to spot patterns between the
+          different plots.
+        | The :ref:`Heatmap-overview <heatmap-overview>` is created from a series of these intensity heatmap plot.
 
         """
         plots = []
@@ -1161,20 +1565,27 @@ def plot_intensity_heatmap(self, dfs_to_use: Union[str, Iterable[str]], levels:
 
     def plot_all_normalizer_overview(self, dfs_to_use, levels, plot_function, file_name, normalizers=None, **kwargs):
         """
-        Helper method to create a plot for all normalization options.
+        | Helper method to create a multipaged file containing one plot per normalization option.
 
         Parameters
         ----------
         dfs_to_use
+            which dataframes/intensities should be plotted
         levels
+            at which level of the data tree should the data be compared
         plot_function
+            which plot should be created
         file_name
+            name of the file that will be crated and saved
         normalizers
+            normalizers either derived from :class:`~mspypeline.module.Normalization.BaseNormalizer` or a class with a
+            :func:`fit_transform`
         kwargs
-
+            accepts kwargs
         Returns
         -------
-
+        list
+            A list of all created plots
         """
         max_depth = dict_depth(self.analysis_design)
         if self.configs.get("has_techrep", False):
@@ -1184,7 +1595,7 @@ def plot_all_normalizer_overview(self, dfs_to_use, levels, plot_function, file_n
         normalizers.update(self.normalizers)
         plot_kwargs = dict()
         plot_kwargs.update(**kwargs)
-        plot_kwargs.update({"save_path": None})
+        save_path = plot_kwargs.pop("save_path", self.file_dir_normalization)
         for df_to_use in dfs_to_use:
             for normaliser_name, normalizer in normalizers.items():
                 self.add_normalized_option(df_to_use, normalizer, normaliser_name)
@@ -1193,15 +1604,25 @@ def plot_all_normalizer_overview(self, dfs_to_use, levels, plot_function, file_n
                 dfs = [x for x in dfs if x.endswith("log2")]
             df_plots = plot_function(dfs, max_depth - 1, **plot_kwargs)
             plots += df_plots
-            save_path, result_name = matplotlib_plots.get_path_and_name_from_kwargs(file_name, **plot_kwargs, df_to_use=df_to_use)
-            matplotlib_plots.collect_plots_to_pdf(os.path.join(self.file_dir_normalization, result_name), *df_plots)
+            if save_path is not None:
+                save_path, result_name = matplotlib_plots.get_path_and_name_from_kwargs(
+                    file_name, **plot_kwargs, df_to_use=df_to_use, save_path=save_path)
+                matplotlib_plots.collect_plots_to_pdf(os.path.join(save_path, result_name), *df_plots)
         return plots
 
     @validate_input
     def plot_normalization_overview_all_normalizers(self, dfs_to_use, levels, **kwargs):
         """
-        Will create the :meth:`plot_normalization_overview` for all normalization methods.
+        | Will create the :meth:`plot_normalization_overview` for all normalization methods.
 
+        Parameters
+        ----------
+        dfs_to_use
+            which dataframes/intensities should be plotted
+        levels
+            at which level of the data tree should the data be compared
+        kwargs
+            accepts kwargs
         """
         plot_kwargs = dict()
         plot_kwargs.update(kwargs)
@@ -1213,10 +1634,18 @@ def plot_normalization_overview_all_normalizers(self, dfs_to_use, levels, **kwar
     @validate_input
     def plot_heatmap_overview_all_normalizers(self, dfs_to_use, levels, **kwargs):
         """
-        Will create the :meth:`plot_intensity_heatmap` for all normalization methods.
+        | Will create the :meth:`plot_intensity_heatmap` for all normalization methods.
 
+        Parameters
+        ----------
+        dfs_to_use
+            which dataframes/intensities should be plotted
+        levels
+            at which level of the data tree should the data be compared
+        kwargs
+            accepts kwargs
         """
-        plot_kwargs = dict(sort_index=True, sort_index_by_missing=False, sort_columns_by_missing=False)
+        plot_kwargs = dict(sort_index=False, sort_index_by_missing=True, sort_columns_by_missing=False)
         plot_kwargs.update(kwargs)
         return self.plot_all_normalizer_overview(
             dfs_to_use=dfs_to_use, levels=levels, plot_function=self.plot_intensity_heatmap,
diff --git a/mspypeline/core/MSPPlots/MaxQuantPlotter.py b/mspypeline/core/MSPPlots/MaxQuantPlotter.py
index eaa6a66..e421bef 100644
--- a/mspypeline/core/MSPPlots/MaxQuantPlotter.py
+++ b/mspypeline/core/MSPPlots/MaxQuantPlotter.py
@@ -9,12 +9,15 @@
 from mspypeline.core.MSPPlots import BasePlotter
 from mspypeline.plotting_backend import matplotlib_plots
 
-
 class MQReader:  # TODO currently circular dependency
     pass
 
 
 class MaxQuantPlotter(BasePlotter):
+    """
+    MaxQuant Plotter is a child class of the :class:`BasePlotter` and inherits all functionality to get data and
+    generate plots.
+    """
     def __init__(
             self,
             start_dir: str,
@@ -27,6 +30,28 @@ def __init__(
             intensity_entries=(("raw", "Intensity ", "Intensity"), ("lfq", "LFQ intensity ", "LFQ intensity"), ("ibaq", "iBAQ ", "iBAQ intensity")),
             loglevel=logging.DEBUG
     ):
+        """
+        Parameters
+        ----------
+        start_dir
+            location to save results
+        reader_data
+            mapping to provide input data
+        intensity_df_name
+            name/key to input data
+        interesting_proteins
+            mapping with pathway proteins to analyze
+        go_analysis_gene_names
+            mapping with go terms to analyze
+        configs
+            mapping of configuration
+        required_reader
+            name of the file reader
+        intensity_entries
+            tuple of (key in all_tree_dict, prefix in data, name in plot). See :meth:`add_intensity_column`.
+        loglevel
+            level of the logger
+        """
         super().__init__(
             start_dir,
             reader_data,
@@ -60,17 +85,21 @@ def from_file_reader(cls, reader_instance: MQReader, **kwargs):
         default_kwargs.update(**kwargs)
         return super().from_file_reader(reader_instance, **default_kwargs)
 
-    def create_report(self):
+    def create_report(self, target_dir: str = None):
         """
-        Creates a MaxQuantReport.pdf, which can be used as quality control.
+        Creates a MaxQuantReport.pdf, which can be used as :ref:`quality control <plotters>`.
 
-        Returns
-        -------
-        None
+        Parameters
+        ----------
+        target_dir
+            directory where report will be written
 
         """
-        def bar_from_counts(ax, counts, compare_counts=None, title=None, relative=False, yscale=None, bar_kwargs=None):
-            if relative:
+        def bar_from_counts(ax, counts, compare_counts=None, title=None, relative=False, yscale=None,
+                            ylabel = None, bar_kwargs=None):
+            if ylabel is not None:
+                ax.set_ylabel(ylabel)
+            elif relative:
                 ax.set_ylabel("Relative counts")
                 counts = counts / counts.sum()
             else:
@@ -99,7 +128,7 @@ def bar_from_counts(ax, counts, compare_counts=None, title=None, relative=False,
                     ax.set_yscale(**yscale)
             return bar_container
 
-        def hist2d_with_hist(xdata, ydata, title=None, xlabel=None, ylabel=None):
+        def hist2d_with_hist(xdata, ydata, title=None, xlabel=None, ylabel=None, max_x=145):
             fig = plt.figure(figsize=(14, 7))
             if title is not None:
                 fig.suptitle(title)
@@ -110,15 +139,15 @@ def hist2d_with_hist(xdata, ydata, title=None, xlabel=None, ylabel=None):
             ax1dhisthor = fig.add_subplot(spec[1, 1])
 
             h, xedges, yedges, image = ax2dhist.hist2d(xdata, ydata,
-                                                       bins=100, range=((0, 145), (0, 2)))  # TODO find ranges/bins
+                                                       bins=100, range=((0, max_x), (0, 2)))  # TODO find bins
             ax2dhist.set_xlabel(xlabel)
             ax2dhist.set_ylabel(ylabel)
 
             ax1dhistvert.hist(xdata, bins=xedges)
-            ax1dhistvert.set_ylabel("Counts")
+            ax1dhistvert.set_ylabel("Peptide Counts")
 
             ax1dhisthor.hist(ydata, bins=yedges, orientation="horizontal")
-            ax1dhisthor.set_xlabel("Counts")
+            ax1dhisthor.set_xlabel("Peptide Counts")
 
             ax1dhistvert.set_xlim(*ax2dhist.get_xlim())
             ax1dhisthor.set_ylim(*ax2dhist.get_ylim())
@@ -246,7 +275,8 @@ def get_plot_data_from_hist(data, density=False, n_bins=16):
             msms_scans = None
 
         self.logger.info("Creating plots")
-        with PdfPages(os.path.join(self.start_dir, "MaxQuantReport.pdf")) as pdf:
+        target_dir = target_dir if target_dir is not None else self.start_dir
+        with PdfPages(os.path.join(target_dir, "MaxQuantReport.pdf")) as pdf:
             self.logger.debug("Creating start page")
             fig = plt.figure(figsize=(14, 7))
             text_conf = dict(transform=fig.transFigure, size=24, ha="center")
@@ -300,8 +330,8 @@ def get_plot_data_from_hist(data, density=False, n_bins=16):
             # ######
 
             # figure stuff
-            self.logger.debug("Creating start ??")  # TODO
-            fig, axarr = plt.subplots(3, 1, figsize=(14, 7))
+            self.logger.debug("Creating technical overview")
+            fig, axarr = plt.subplots(2, 1, figsize=(14, 7))
             if peptides is not None:
                 bar_from_counts(axarr[0], peptides["Charges"].str.split(";").explode().value_counts().sort_index(),
                                 title="Peptide Charges")
@@ -309,10 +339,10 @@ def get_plot_data_from_hist(data, density=False, n_bins=16):
             if evidence is not None:
                 axarr[1].hist(evidence["m/z"])
                 axarr[1].set_xlabel("m/z")
-                axarr[1].set_ylabel("counts")
-                axarr[1].set_title("peptide m/z")
+                axarr[1].set_ylabel("Counts")
+                axarr[1].set_title("Peptide m/z")
 
-            fig.tight_layout(rect=[0, 0.03, 1, 0.95])
+            fig.tight_layout(rect=[0, 0.3, 1, 0.95])
 
             pdf.savefig()
             plt.close(fig)
@@ -324,12 +354,14 @@ def get_plot_data_from_hist(data, density=False, n_bins=16):
             # hist with identified proteins and hist with identified peptides, shared axis
             if prot_groups is not None:
                 identified_proteins = (prot_groups_intensities["Grouped Intensity"] > 0).sum()
-                identified_proteins = identified_proteins.rename(lambda x: x.replace("Intensity ", ""), axis=0)
+                identified_proteins = identified_proteins.rename(lambda x: x.replace("Intensity ", "").replace("_", " ")
+                                                                 , axis=0)
                 bar_from_counts(axarr[0], identified_proteins, title="Identified proteins")
             # proteins from proteinGroups, peptides from peptides file per sample
             if peptides is not None:
                 identified_peptides = (peptides_intensities["Grouped Intensity"] > 0).sum()
-                identified_peptides = identified_peptides.rename(lambda x: x.replace("Intensity ", ""), axis=0)
+                identified_peptides = identified_peptides.rename(lambda x: x.replace("Intensity ", "").replace("_", " ")
+                                                                 , axis=0)
                 bar_from_counts(axarr[1], identified_peptides, title="Identified peptides")
                 axarr[1].xaxis.set_tick_params(rotation=90)
 
@@ -346,17 +378,18 @@ def get_plot_data_from_hist(data, density=False, n_bins=16):
 
                 axarr[0].set_title("MS scans")
                 axarr[0].bar(range(summary.shape[0]), summary["MS"])
-                axarr[0].set_ylabel("count")
+                axarr[0].set_ylabel("Count")
 
                 axarr[1].set_title("MS/MS scans")
                 axarr[1].bar(range(summary.shape[0]), summary["MS/MS"])
-                axarr[1].set_ylabel("count")
+                axarr[1].set_ylabel("Count")
 
                 axarr[2].set_title("MS/MS identified [%]")
                 axarr[2].bar(range(summary.shape[0]), summary["MS/MS Identified [%]"])
-                axarr[2].set_ylabel("percent")
+                axarr[2].set_ylabel("Percent")
                 axarr[2].set_xticks(range(summary.shape[0]))
-                axarr[2].set_xticklabels(summary["Experiment"], rotation=90)
+                labels = [sample.replace("_", " ") for sample in summary["Experiment"]]
+                axarr[2].set_xticklabels(labels, rotation=90)
 
                 fig.tight_layout(rect=[0, 0.03, 1, 0.95])
 
@@ -373,19 +406,18 @@ def get_plot_data_from_hist(data, density=False, n_bins=16):
                     "contaminants": df_contaminants_int.sum(axis=0),
                     "no_contaminants": df_no_contaminants_int.sum(axis=0)})
                 sum_int["total"] = sum_int["contaminants"] + sum_int["no_contaminants"]
-                sum_int["percent_cont"] = sum_int["contaminants"] / sum_int["total"]
-                sum_int["percent_no_cont"] = sum_int["no_contaminants"] / sum_int["total"]
-                fig, ax = plt.subplots(1, 1, sharex=True, figsize=(15, 6))
+                sum_int["percent_cont"] = (sum_int["contaminants"] / sum_int["total"])*100
+                sum_int["percent_no_cont"] = (sum_int["no_contaminants"] / sum_int["total"])*100
+                fig, ax = plt.subplots(1, 1, sharex=True, figsize=(14, 7))
 
                 labels = [label.replace("Intensity ", "").replace("_", " ") for label in sum_int.index.values]
-                labels[0] = "Total samples"
 
                 ax.bar(x=labels, height=sum_int["percent_cont"], width=0.8)
                 ax.set_title("Intensity of contaminants from total intensity", size=14, pad=20)
-                ax.set_ylabel("percent", size=13)
+                ax.set_ylabel("Percent", size=13)
                 ax.set_xticks(range(len(labels)))
                 ax.set_xticklabels(labels, rotation=90)
-                ax.axhline(0.05, linestyle="-", linewidth=2, color="red", alpha=0.6)
+                ax.axhline(5, linestyle="-", linewidth=2, color="red", alpha=0.6)
 
                 fig.tight_layout()
 
@@ -402,10 +434,12 @@ def get_plot_data_from_hist(data, density=False, n_bins=16):
                 colors = prot_groups_intensities["Grouped Intensity"].rename(lambda x: x.replace("Intensity ", ""), axis=1).columns
                 colors = [plot_colors[c] for c in colors]
                 matplotlib_plots.save_intensity_histogram_results(prot_groups_intensities, n_bins=11, histtype="barstacked",
-                                                                  plot=(fig, axarr[0]), color=colors)
+                                                                  plot=(fig, axarr[0]), color=colors, show_mean=False,
+                                                                  legend=False)
                 # overlayed histogram of log2 intensities
                 matplotlib_plots.save_intensity_histogram_results(prot_groups_intensities, n_bins=11, histtype="step",
-                                                                  plot=(fig, axarr[1]), color=colors)
+                                                                  plot=(fig, axarr[1]), color=colors, show_mean=False,
+                                                                  legend=False)
                 fig.legend(bbox_to_anchor=(1.02, 0.5), loc="center left")
 
                 fig.tight_layout()
@@ -423,7 +457,8 @@ def get_plot_data_from_hist(data, density=False, n_bins=16):
 
                 fig, ax = hist2d_with_hist(title="Overall Retention time vs Retention length",
                                            xdata=evidence["Retention time"], ydata=evidence["Retention length"],
-                                           xlabel="Retention time [min]", ylabel="Retention length [min]")
+                                           xlabel="Retention time [min]", ylabel="Retention length [min]",
+                                           max_x=evidence["Retention time"].max())
 
                 pdf.savefig(figure=fig)
                 plt.close(fig)
@@ -442,27 +477,27 @@ def get_plot_data_from_hist(data, density=False, n_bins=16):
                 for experiment in mz.columns:
                     plot_color = plot_colors[experiment]
                     fig, axarr = plt.subplots(3, 2, figsize=(14, 7))
-                    fig.suptitle(experiment)
+                    fig.suptitle(experiment.replace("_", " "))
 
                     axarr[0, 0].hist(mz[experiment], density=True, color=plot_color, bins=mz_bins)
                     axarr[0, 0].plot(mz_x, mz_y, color="black")
                     # axarr[0, 0].hist(mz.drop(experiment, axis=1).values.flatten(), histtype="step", density=True, color="black", bins=bins, linewidth=2)
                     # axarr[0, 0].hist(mz_flat, histtype="step", density=True, color="black", bins=bins, linewidth=2)
                     axarr[0, 0].set_xlabel("m/z")
-                    axarr[0, 0].set_ylabel("density")
-                    axarr[0, 0].set_title("peptide m/z")
+                    axarr[0, 0].set_ylabel("Density")
+                    axarr[0, 0].set_title("Peptide m/z")
 
                     bar_from_counts(axarr[0, 1], charge[experiment],
                                     compare_counts=charge_flat,
                                     relative=True,
-                                    title="peptide charges", bar_kwargs={"color": plot_color})
-                    axarr[0, 1].set_xlabel("peptide charge")
+                                    title="Peptide charges", bar_kwargs={"color": plot_color})
+                    axarr[0, 1].set_xlabel("Peptide charge")
 
                     bar_from_counts(axarr[1, 0], missed_cleavages[experiment],
                                     compare_counts=missed_cleavages_flat,
                                     relative=True,
                                     title="Number of missed cleavages", bar_kwargs={"color": plot_color})
-                    axarr[1, 0].set_xlabel("missed cleavages")
+                    axarr[1, 0].set_xlabel("Missed cleavages")
 
                     # TODO this might be missing
                     bar_from_counts(axarr[1, 1], before_aa_counts[experiment],
@@ -477,6 +512,7 @@ def get_plot_data_from_hist(data, density=False, n_bins=16):
                                     bar_kwargs={"color": plot_color})
                     axarr[2, 0].set_title("Last amino acid")
 
+                    axarr[2, 1].remove()
                     fig.tight_layout()
 
                     pdf.savefig()
@@ -492,7 +528,6 @@ def get_plot_data_from_hist(data, density=False, n_bins=16):
                 b, h, bins = get_plot_data_from_hist(log2_intensities, density=True, n_bins=16)
 
                 n_figures = int(np.ceil(len(log2_intensities.columns) / 9))
-
                 for n_figure in range(n_figures):
                     fig, axarr = plt.subplots(3, 3, figsize=(15, 15))
                     for i, (pos, ax) in enumerate(np.ndenumerate(axarr)):
@@ -504,9 +539,14 @@ def get_plot_data_from_hist(data, density=False, n_bins=16):
                         ax.hist(log2_intensities.loc[:, experiment], bins=bins, density=True,
                                 color=plot_colors[experiment])
                         ax.plot(b, h, color="black")
-                        ax.set_title(experiment)
+                        ax.set_title(experiment.replace("_", " "))
                         ax.set_xlabel("Intensity")
-                        ax.set_ylabel("density")
+                        ax.set_ylabel("Density")
+
+                    if n_figure == (n_figures - 1):
+                        n_empty = n_figures * 9 - len(log2_intensities.columns)
+                        for i in range(1, n_empty + 1):
+                            axarr.flat[-i].remove()
 
                     fig.tight_layout(rect=[0, 0.03, 1, 0.95])
 
@@ -514,43 +554,12 @@ def get_plot_data_from_hist(data, density=False, n_bins=16):
                     plt.close(fig)
             # ################
 
-            def split_plot_to_multiple_figures(fig_rows_cols, total_size, figsize):
-                n_figures = int(np.ceil(total_size / sum(fig_rows_cols)))
-                plots = []
-                for n_figure in range(n_figures):
-                    fig, axarr = plt.subplots(*fig_rows_cols, figsize=figsize)
-                    for i, (pos, ax) in enumerate(np.ndenumerate(axarr)):
-                        idx = n_figure * sum(fig_rows_cols) + i
-                        yield
-                        if idx == sum(fig_rows_cols):
-                            plots += (fig, axarr)
-                            break
-                yield plots
-
-            def split_p(n_rwos, n_cols, figsize=(7, 7), plot_name="", data=None, plot_fn=None):
-                n_figures = int(np.ceil(len(retention_time.columns) / (n_rwos * n_cols)))
-
-                with PdfPages(os.path.join(self.start_dir, plot_name + ".pdf")) as pdf:
-                    for n_figure in range(n_figures):
-                        fig, axarr = plt.subplots(n_rwos, n_cols, figsize=figsize)
-                        for i, (pos, ax) in enumerate(np.ndenumerate(axarr)):
-                            idx = n_figure * (n_rwos * n_cols) + i
-                            try:
-                                experiment = retention_time.columns[idx]
-                            except IndexError:
-                                break
-                            plot_fn(ax, data[experiment], experiment)
-                        fig.tight_layout(rect=[0, 0.03, 1, 0.95])
-
-                        pdf.savefig(fig)
-                        plt.close(fig)
             # Retention time of individuals samples vs remaining
             if evidence is not None:
                 self.logger.debug("Creating individual retention time histograms")
                 b, h, bins = get_plot_data_from_hist(retention_time, density=True, n_bins=25)
 
                 n_figures = int(np.ceil(len(retention_time.columns) / 9))
-
                 for n_figure in range(n_figures):
                     fig, axarr = plt.subplots(3, 3, figsize=(15, 15))
                     for i, (pos, ax) in enumerate(np.ndenumerate(axarr)):
@@ -562,9 +571,14 @@ def split_p(n_rwos, n_cols, figsize=(7, 7), plot_name="", data=None, plot_fn=Non
                         ax.hist(retention_time.loc[:, experiment], bins=bins, density=True,
                                 color=plot_colors[experiment])
                         ax.plot(b, h, color="black")
-                        ax.set_title(experiment)
+                        ax.set_title(experiment.replace("_", " "))
                         ax.set_xlabel("Retention time")
-                        ax.set_ylabel("density")
+                        ax.set_ylabel("Density")
+
+                    if n_figure == (n_figures - 1):
+                        n_empty = n_figures * 9 - len(retention_time.columns)
+                        for i in range(1, n_empty + 1):
+                            axarr.flat[-i].remove()
 
                     fig.tight_layout(rect=[0, 0.03, 1, 0.95])
 
@@ -575,9 +589,9 @@ def split_p(n_rwos, n_cols, figsize=(7, 7), plot_name="", data=None, plot_fn=Non
             if evidence is not None:
                 self.logger.debug("Creating individual retention time vs retention length")
                 for experiment in retention_length.columns:
-                    fig, ax = hist2d_with_hist(title=experiment, xdata=retention_time[experiment],
+                    fig, ax = hist2d_with_hist(title=experiment.replace("_", " "), xdata=retention_time[experiment],
                                                ydata=retention_length[experiment], xlabel="Retention time [min]",
-                                               ylabel="Retention length [min]")
+                                               ylabel="Retention length [min]", max_x=retention_time.max().max())
 
                     pdf.savefig(figure=fig)
                     plt.close(fig)
diff --git a/mspypeline/core/MSPypeline.py b/mspypeline/core/MSPypeline.py
index 5b029ad..d0dbed4 100644
--- a/mspypeline/core/MSPypeline.py
+++ b/mspypeline/core/MSPypeline.py
@@ -12,7 +12,33 @@
 
 
 class UIHandler:
-    def __init__(self, file_dir, yml_file=None, gui=False, host_flask=False, selected_reader=MQReader.MQReader, loglevel=logging.DEBUG, configs: dict = None):
+    """
+    | Used to take the mapping of arguments provided by the :class:`~MSPParser` through the command line to organize
+      through which point of entry the data analysis should be performed.
+    | The UIHandler can initialize the creation of the GUI, perform the whole analysis instantly by running the
+      pipeline and creating all plots according to the configs or (not yet available) host the mspypeline on a flask
+      server.
+    """
+    def __init__(self, file_dir, yml_file=None, gui=False, host_flask=False, selected_reader=MQReader.MQReader,
+                 loglevel=logging.DEBUG, configs: dict = None):
+        """
+        Parameters
+        ----------
+        file_dir
+            location where the directory/txt folder to the data can be found.
+        yml_file
+            path to the yaml config file
+        gui
+            should a GUI be compiled
+        host_flask
+            currently not implemented (should a flsk server be hosted)
+        selected_reader
+            instance of an :class:`~BaseReader` used to process data to an internal format for the plotter.
+        loglevel
+            level of the logger
+        configs
+            mapping of configuration
+        """
         base_config = {
             "has_techrep": False,
             "has_groups": False,
@@ -42,7 +68,22 @@ def __init__(self, file_dir, yml_file=None, gui=False, host_flask=False, selecte
 
 
 class MSPGUI(tk.Tk):
+    """
+    | This class is called from the :class:`~UIHandler` to create the GUI.
+    """
     def __init__(self, file_dir, yml_file=None, loglevel=logging.DEBUG, configs: dict = None):
+        """
+        Parameters
+        ----------
+        file_dir
+            location where the directory/txt folder to the data can be found.
+        yml_file
+            path to the yaml config file
+        loglevel
+            level of the logger
+        configs
+            mapping containing the configurations
+        """
         super().__init__()
         self.yaml_options = ["default"]
         self.reader_options = {reader.name: reader for reader in BaseReader.__subclasses__()}
@@ -274,7 +315,8 @@ def update_button(self):
             additional_settings = {k: v for k, v in additional_settings.items()
                                    if k != "create_plot" and k != "dfs_to_use" and k != "levels"}
             selected_settings.update(additional_settings)
-            self.mspinit.configs.update({plot_settings: selected_settings})
+            for k, v in selected_settings.items():
+                self.mspinit.configs[plot_settings][k] = v
         gos = self.go_proteins_list.curselection()
         gos = [MSPInitializer.possible_gos[int(go)] for go in gos]
         pathways = self.pathway_list.curselection()
@@ -363,6 +405,10 @@ def get_selection(self):
 
 
 class MSPParser(argparse.ArgumentParser):
+    """
+    | Uses the ``argparse`` module to provide a parser for command line options, arguments and sub-commands through
+      which the analysis can be started or the GUI can be called (see :ref:`get-started`).
+    """
     def __init__(self):
         super().__init__(description="A pipeline to analyze result files from a MaxQuant report. "
                                      "The required result files are in the txt directory.")
diff --git a/mspypeline/file_reader/BaseReader.py b/mspypeline/file_reader/BaseReader.py
index 24f3ac6..a8f359d 100644
--- a/mspypeline/file_reader/BaseReader.py
+++ b/mspypeline/file_reader/BaseReader.py
@@ -1,4 +1,5 @@
 import logging
+from logging import Logger
 from abc import abstractmethod, ABC
 from typing import Iterable
 try:
@@ -10,11 +11,43 @@
 
 
 class BaseReader(ABC):
-    def __init__(self, start_dir: str, reader_config: dict, loglevel=logging.DEBUG):
-        self.full_data = DataDict(data_source=self)
-        self.start_dir = start_dir
-        self.reader_config = reader_config
-        self.logger = get_logger(self.__class__.__name__, loglevel)
+    """
+    | Base reader to provide a data dictionary with keys to the data. Data stored on system hardware, is thus only
+      loaded on demand. This is the parent class of any file reader that will be use to preprocess data to the
+      internal format.
+
+    Example
+    ---------
+    >>> # example for a new custom reader
+    >>> class CustomReader(BaseReader):
+    ...     name = "reader"  # this is the name of the reader in the yaml file
+    ...     required_files = []  # this is a list of strings of all files that should be parsed
+    ...     plotter = BasePlotter
+    ...
+    ...     def __init__(self, start_dir, reader_config, loglevel):
+    ...         super().__init__(start_dir, reader_config, loglevel)
+    ...         for file in Reader.required_files:
+    ...             self.full_data[file] = [0, 0, 10]  # this should be the data from the file
+    >>> r = Reader("", {}, 10)
+
+    """
+    def __init__(self, start_dir: str, reader_config: dict, loglevel: int = logging.DEBUG):
+        """
+
+        Parameters
+        ----------
+        start_dir
+            location where the directory/txt folder to the data can be found.
+        reader_config
+            mapping of the file reader configuration (as e.g. given in the config.yml file)
+        loglevel
+            level of the logger
+
+        """
+        self.full_data: DataDict = DataDict(data_source=self)
+        self.start_dir: str = start_dir
+        self.reader_config: dict = reader_config
+        self.logger: Logger = get_logger(self.__class__.__name__, loglevel)
 
         # log which files will be read
         self.logger.info("Required files: %s", self.required_files)
@@ -49,11 +82,17 @@ class MissingFilesException(Exception):
     pass
 
 
+# the decorators add to the docstring so it is removed here
+BaseReader.name.__doc__ = ""
+BaseReader.required_files.__doc__ = ""
+BaseReader.plotter.__doc__ = ""
+
 if __name__ == "__main__":
     # minimal example of a class implementing the BaseReader
     class Reader(BaseReader):
         name = "reader"  # this is the name of the reader in the yaml file
         required_files = []  # this is a list of strings of all files that should be parsed
+        #plotter = BasePlotter
 
         def __init__(self, start_dir, reader_config, loglevel):
             super().__init__(start_dir, reader_config, loglevel)
diff --git a/mspypeline/file_reader/MQReader.py b/mspypeline/file_reader/MQReader.py
index 77ac667..b4246af 100644
--- a/mspypeline/file_reader/MQReader.py
+++ b/mspypeline/file_reader/MQReader.py
@@ -10,6 +10,15 @@
 
 
 class MQReader(BaseReader):
+    """
+    | A child class of the :class:`~BaseReader`.
+    | The MQReader preprocesses data from MaxQuant files into the internal data format to provide the correct input
+      for the plotters. Required files to start the MQReader is the **proteinGroups.txt** file from MaxQuant.
+    | Additionally, the file reader can preprocess the *evidence, msmsScans, msScans, parameters, peptides* and
+      *summary* txt files from the MaxQuant output.
+    | The reader also recognizes :ref:`sample_mapping.txt files <sample-mapping>` if provided and corrects the
+      sample naming for instance in the case of naming convention violation (see :ref:`analysis-design`).
+    """
     proteins_txt = "proteinGroups.txt"
     peptides_txt = "peptides.txt"
     mapping_txt = "sample_mapping.txt"
@@ -27,7 +36,25 @@ def __init__(self, start_dir: str,
                  index_col: str = "Gene name",
                  duplicate_handling: str = "sum",
                  drop_columns: Union[list, tuple, str] = None,
-                 loglevel=logging.DEBUG):
+                 loglevel: int = logging.DEBUG):
+        """
+        Parameters
+        ----------
+        start_dir
+            location where the directory/txt folder to the data can be found.
+        reader_config
+            mapping of the file reader configuration (as e.g. given in the config.yml file)
+        index_col
+            with which identification type should detected proteins in the *proteinGroups.txt* file be handled.
+            If provided in the reader_config will be taken from there.
+        duplicate_handling
+            how should proteins with duplicate index_col be treated ? can be "sum" or "drop".
+            If provided in the reader_config will be taken from there.
+        drop_columns
+            samples to be excluded from the analysis. If provided in the reader_config will be taken from there.
+        loglevel
+            level of the logger
+        """
         super().__init__(start_dir, reader_config, loglevel=loglevel)
 
         if os.path.split(self.start_dir)[1] != "txt":
@@ -36,7 +63,7 @@ def __init__(self, start_dir: str,
             self.data_dir = self.start_dir
         self.index_col = self.reader_config.get("index_col", index_col)
         self.duplicate_handling = self.reader_config.get("duplicate_handling", duplicate_handling)
-        to_drop = self.reader_config.get("drop_columns", drop_columns if drop_columns is not None else [])
+        self.to_drop = self.reader_config.get("drop_columns", drop_columns if drop_columns is not None else [])
 
         # read a sample of all required files. If any required file is missing exit
         # but we need only one file from the max quant results
@@ -69,13 +96,13 @@ def __init__(self, start_dir: str,
             self.new_proteins_txt_columns = self.rename_df_columns(self.new_proteins_txt_columns)
 
         # get columns that should be dropped
-        if isinstance(to_drop, str):
-            to_drop = [to_drop]
+        if isinstance(self.to_drop, str):
+            self.to_drop = [self.to_drop]
 
         # subset on all columns that start with intensity
         self.intensity_column_names = sorted([x.replace("Intensity ", "") for x in self.new_proteins_txt_columns
                                               if x.startswith('Intensity ')], key=len, reverse=True)
-        self.intensity_column_names = [x for x in self.intensity_column_names if x not in to_drop]
+        self.intensity_column_names = [x for x in self.intensity_column_names if x not in self.to_drop]
         if not self.reader_config.get("all_replicates", False):
             self.reader_config["all_replicates"] = self.intensity_column_names
         # check the naming convention
@@ -149,184 +176,140 @@ def guess_analysis_design(self, all_reps):
         raise NotImplementedError("This is not implemented at the moment. Please stick to the naming convention")
         # TODO update the attempted matching mechanism
 
-
-    def preprocess_contaminants(self):
+    def helper_preprocess_proteinGroups(self, select_contaminants: bool = False):
         file_dir = os.path.join(self.data_dir, MQReader.proteins_txt)
-        df_protein_groups = pd.read_csv(file_dir, sep="\t")
-        df_protein_groups.columns = self.rename_df_columns(df_protein_groups.columns)
-
-
-        contaminants = (df_protein_groups[["Only identified by site", "Reverse", "Potential contaminant"]] == "+"
-                            ).sum(axis=1) != 0
-        self.logger.debug("Removing %s rows from %s because they are not marked as contaminant",
-                          (~contaminants).sum(), MQReader.proteins_txt)
-        df_protein_groups  = df_protein_groups[contaminants]
+        df = pd.read_csv(file_dir, sep="\t")
+        df.columns = self.rename_df_columns(df.columns)
+        contaminant_cols = ["Only identified by site", "Reverse", "Potential contaminant"]
+        if select_contaminants:
+            cont = (df.loc[:, contaminant_cols] == "+").sum(axis=1) != 0
+            self.logger.debug("Removing %s rows from %s because they are not marked as contaminant",
+                              (~cont).sum(), MQReader.proteins_txt)
+            df = df.loc[cont, :]
+        else:
+            not_cont = (df.loc[:, contaminant_cols] == "+").sum(axis=1) == 0
+            self.logger.debug("Removing %s rows from %s because they are marked as contaminant",
+                              (~not_cont).sum(), MQReader.proteins_txt)
+            df = df.loc[not_cont, :]
 
-        if any(df_protein_groups["Fasta headers"].isna()):
+        if any(df["Fasta headers"].isna()):
             self.logger.warning("Missing fasta headers using default columns for information")
-            gene_name = df_protein_groups["Gene names"]
+            gene_name = df.loc[:, "Gene names"]
             sep_ind = gene_name.str.contains(";").fillna(False)
             if sep_ind.sum() > 0:
                 gene_name[sep_ind] = gene_name[sep_ind].str.split(";", expand=True)[0]
             concat_df = pd.DataFrame({
-                "protein id": df_protein_groups["Protein names"],
+                "protein id": df["Protein names"],
                 "Gene name": gene_name.str.upper(),
                 "Protein name": ["Missing"] * gene_name.shape[0],
             })
         else:
             # split the fasta headers
-            colon_start = df_protein_groups["Fasta headers"].str.startswith(";")
-            df_protein_groups.loc[colon_start, "Fasta headers"] = df_protein_groups.loc[
-                colon_start, "Fasta headers"].str.lstrip(";")
+            colon_start = df.loc[:, "Fasta headers"].str.startswith(";")
+            df.loc[colon_start, "Fasta headers"] = df.loc[colon_start, "Fasta headers"].str.lstrip(";")
             # first split all fasta headers that contain multiple entries
-            sep_ind = df_protein_groups["Fasta headers"].str.contains(";").fillna(False)
+            sep_ind = df.loc[:, "Fasta headers"].str.contains(";").fillna(False)
             # replace all fasta headers with multiple entries with only the first one
-            df_protein_groups.loc[sep_ind, "Fasta headers"] = \
-                df_protein_groups.loc[sep_ind, "Fasta headers"].str.split(";", expand=True)[0]
+            df.loc[sep_ind, "Fasta headers"] = df.loc[sep_ind, "Fasta headers"].str.split(";", expand=True)[0]
             # split the fasta headers with the pipe symbol
-            fasta_col = df_protein_groups["Fasta headers"].str.split("|", n=2).apply(pd.Series)
+            fasta_col = df.loc[:, "Fasta headers"].str.split("|", n=2).apply(pd.Series)
             fasta_col.columns = ["trash", "protein id", "description"]
             # extract the gene name from the description eg: "GN=abcd"
-            gene_names_fasta = fasta_col["description"].str.extract(r"(GN=(.*?)(\s|$))")[1]
+            gene_names_fasta = fasta_col.loc[:, "description"].str.extract(r"(GN=(.*?)(\s|$))")[1]
             # added upper() function to avoid that non-human gene names are not recognized
             concat_df = pd.DataFrame({
-                "protein id": fasta_col["protein id"],
+                "protein id": fasta_col.loc[:, "protein id"],
                 "Gene name": gene_names_fasta.str.upper(),
-                "Protein name": fasta_col["description"].str.split("_", expand=True)[0]
+                "Protein name": fasta_col.loc[:, "description"].str.split("_", expand=True)[0]
             })
         # concat all important columns with the original dataframe
-        df_protein_groups = pd.concat([df_protein_groups, concat_df], axis=1)
-        self.logger.debug("Shape of df_contaminants befor masking %s ", df_protein_groups.shape)
+        df = pd.concat([df, concat_df], axis=1)
+        self.logger.debug("Shape of df_contaminants before masking %s ", df.shape)
         # remove all rows where the column used for indexing is missing
-        mask = ~pd.isna(df_protein_groups[self.index_col])
+        mask = ~pd.isna(df[self.index_col])
 
-        df_protein_groups = df_protein_groups.loc[mask]
+        df = df.loc[mask]
 
-        self.logger.debug("Shape of df_contaminants after masking %s ", df_protein_groups.shape)
+        self.logger.debug("Shape of df_contaminants after masking %s ", df.shape)
         if ~mask.sum() > 0:
             self.logger.warning("Removing %s rows because the index col information from: %s is missing",
                                 ~mask.sum(), self.index_col)
-        #set index
+        # set index
         self.logger.info("Setting index of %s to %s", MQReader.proteins_txt, self.index_col)
-        df_protein_groups = df_protein_groups.set_index(df_protein_groups[self.index_col], drop=False)
+        df = df.set_index(df[self.index_col], drop=False)
         # convert all non numeric intensities
-        for col in [col for col in df_protein_groups.columns if "Intensity " in col or "LFQ " in col or "iBAQ " in col]:
-            if not is_numeric_dtype(df_protein_groups[col]):
-                df_protein_groups[col] = df_protein_groups[col].apply(lambda x: x.replace(",", ".")).fillna(0)
-                df_protein_groups[col] = df_protein_groups[col].astype("int64")
+        for col in [col for col in df.columns if "Intensity " in col or "LFQ " in col or "iBAQ " in col]:
+            if not is_numeric_dtype(df[col]):
+                df[col] = df[col].apply(lambda x: x.replace(",", ".")).fillna(0)
+                df[col] = df[col].astype("int64")
         # handle all rows with duplicated index column
-        duplicates = df_protein_groups.duplicated(subset=self.index_col, keep=False)
+        duplicates = df.duplicated(subset=self.index_col, keep=False)
         if any(duplicates):
             self.logger.warning("Found duplicates in %s column. Duplicate names: %s",
-                                self.index_col, ", ".join(df_protein_groups[duplicates].loc[:, self.index_col]))
+                                self.index_col, ", ".join(df[duplicates].loc[:, self.index_col]))
             if self.duplicate_handling == "drop":
                 self.logger.warning("Dropping all %s duplicates.", duplicates.sum())
-                df_protein_groups = df_protein_groups.drop_duplicates(subset=self.index_col, keep=False)
+                df = df.drop_duplicates(subset=self.index_col, keep=False)
             elif self.duplicate_handling == "sum":
                 def group_sum(x):
                     x.iloc[0].loc[x.select_dtypes("number").columns] = x.sum(axis=0, numeric_only=True)
                     return x.iloc[0]
 
-                new_index = df_protein_groups.index.drop_duplicates(keep=False)
-                duplicate_index = df_protein_groups.index.difference(new_index)
-                df_dup = df_protein_groups.loc[duplicate_index, :]
+                new_index = df.index.drop_duplicates(keep=False)
+                duplicate_index = df.index.difference(new_index)
+                df_dup = df.loc[duplicate_index, :]
                 self.logger.warning("Merging %s rows into %s by summing numerical columns. "
                                     "Some information might be incorrect", df_dup.shape[0], duplicate_index.shape[0])
                 df_dup = df_dup.groupby(df_dup.index).apply(group_sum)
-                df_protein_groups = pd.concat([df_protein_groups.loc[new_index, :], df_dup], axis=0)
-        self.logger.debug("%s shape after preprocessing: %s", MQReader.proteins_txt, df_protein_groups.shape)
+                df = pd.concat([df.loc[new_index, :], df_dup], axis=0)
+        self.logger.debug("%s shape after preprocessing: %s", MQReader.proteins_txt, df.shape)
 
-        return df_protein_groups
+        return df
 
+    def preprocess_contaminants(self):
+        """
+        | Preprocess the *proteinGroups.txt* file to internal format and return DataFrame with all those proteins marked
+          as contaminant.
+        | Contaminants are defined as those proteins *"Only identified by site"*, marked as *"Reverse"* or as
+          *"Potential contaminant"* in the *proteinGroups.txt* file.
+
+        Returns
+        -------
+        DataFrame
+            DataFrame containing preprocessed data of contaminants from *proteinGroups.txt* file
+        """
+        return self.helper_preprocess_proteinGroups(select_contaminants=True)
 
     def preprocess_proteinGroups(self):
-        file_dir = os.path.join(self.data_dir, MQReader.proteins_txt)
-        df_protein_groups = pd.read_csv(file_dir, sep="\t")
-        df_protein_groups.columns = self.rename_df_columns(df_protein_groups.columns)
-        not_contaminants = (df_protein_groups[
-                                ["Only identified by site", "Reverse", "Potential contaminant"]] == "+"
-                            ).sum(axis=1) == 0
-        self.logger.debug("Removing %s rows from %s because they are marked as contaminant",
-                          (~not_contaminants).sum(), MQReader.proteins_txt)
-        df_protein_groups = df_protein_groups[not_contaminants]
-        if any(df_protein_groups["Fasta headers"].isna()):
-            self.logger.warning("Missing fasta headers using default columns for information")
-            gene_name = df_protein_groups["Gene names"]
-            sep_ind = gene_name.str.contains(";").fillna(False)
-            if sep_ind.sum() > 0:
-                gene_name[sep_ind] = gene_name[sep_ind].str.split(";", expand=True)[0]
-            concat_df = pd.DataFrame({
-                "protein id": df_protein_groups["Protein names"],
-                "Gene name": gene_name.str.upper(),
-                "Protein name": ["Missing"] * gene_name.shape[0],
-            })
-        else:
-            # split the fasta headers
-            colon_start = df_protein_groups["Fasta headers"].str.startswith(";")
-            df_protein_groups.loc[colon_start, "Fasta headers"] = df_protein_groups.loc[
-                colon_start, "Fasta headers"].str.lstrip(";")
-            # first split all fasta headers that contain multiple entries
-            sep_ind = df_protein_groups["Fasta headers"].str.contains(";").fillna(False)
-            # replace all fasta headers with multiple entries with only the first one
-            df_protein_groups.loc[sep_ind, "Fasta headers"] = \
-                df_protein_groups.loc[sep_ind, "Fasta headers"].str.split(";", expand=True)[0]
-            # split the fasta headers with the pipe symbol
-            fasta_col = df_protein_groups["Fasta headers"].str.split("|", n=2).apply(pd.Series)
-            fasta_col.columns = ["trash", "protein id", "description"]
-            # extract the gene name from the description eg: "GN=abcd"
-            gene_names_fasta = fasta_col["description"].str.extract(r"(GN=(.*?)(\s|$))")[1]
-            # added upper() function to avoid that non-human gene names are not recognized
-            concat_df = pd.DataFrame({
-                "protein id": fasta_col["protein id"],
-                "Gene name": gene_names_fasta.str.upper(),
-                "Protein name": fasta_col["description"].str.split("_", expand=True)[0]
-            })
-        # concat all important columns with the original dataframe
-        df_protein_groups = pd.concat([df_protein_groups, concat_df], axis=1)
-        # remove all rows where the column used for indexing is missing
-        mask = ~pd.isna(df_protein_groups[self.index_col])
-        df_protein_groups = df_protein_groups.loc[mask]
-        if ~mask.sum() > 0:
-            self.logger.warning("Removing %s rows because the index col information from: %s is missing",
-                                ~mask.sum(), self.index_col)
-        # set index
-        self.logger.info("Setting index of %s to %s", MQReader.proteins_txt, self.index_col)
-        df_protein_groups = df_protein_groups.set_index(df_protein_groups[self.index_col], drop=False)
-        # convert all non numeric intensities
-        for col in [col for col in df_protein_groups.columns if "Intensity " in col or "LFQ " in col or "iBAQ " in col]:
-            if not is_numeric_dtype(df_protein_groups[col]):
-                df_protein_groups[col] = df_protein_groups[col].apply(lambda x: x.replace(",", ".")).fillna(0)
-                df_protein_groups[col] = df_protein_groups[col].astype("int64")
-        # handle all rows with duplicated index column
-        duplicates = df_protein_groups.duplicated(subset=self.index_col, keep=False)
-        if any(duplicates):
-            self.logger.warning("Found duplicates in %s column. Duplicate names: %s",
-                                self.index_col, ", ".join(df_protein_groups[duplicates].loc[:, self.index_col]))
-            if self.duplicate_handling == "drop":
-                self.logger.warning("Dropping all %s duplicates.", duplicates.sum())
-                df_protein_groups = df_protein_groups.drop_duplicates(subset=self.index_col, keep=False)
-            elif self.duplicate_handling == "sum":
-                def group_sum(x):
-                    x.iloc[0].loc[x.select_dtypes("number").columns] = x.sum(axis=0, numeric_only=True)
-                    return x.iloc[0]
-
-                new_index = df_protein_groups.index.drop_duplicates(keep=False)
-                duplicate_index = df_protein_groups.index.difference(new_index)
-                df_dup = df_protein_groups.loc[duplicate_index, :]
-                self.logger.warning("Merging %s rows into %s by summing numerical columns. "
-                                    "Some information might be incorrect", df_dup.shape[0], duplicate_index.shape[0])
-                df_dup = df_dup.groupby(df_dup.index).apply(group_sum)
-                df_protein_groups = pd.concat([df_protein_groups.loc[new_index, :], df_dup], axis=0)
-        self.logger.debug("%s shape after preprocessing: %s", MQReader.proteins_txt, df_protein_groups.shape)
-        return df_protein_groups
+        """
+        | Preprocess the *proteinGroups.txt* file to internal format and return DataFrame with all those proteins not
+          marked as contaminant.
+        | Contaminants are defined as those proteins *"Only identified by site"*, marked as *"Reverse"* or as
+          *"Potential contaminant"* in the *proteinGroups.txt* file.
+
+        Returns
+        -------
+        DataFrame
+            DataFrame containing preprocessed data from *proteinGroups.txt* file
+        """
+        return self.helper_preprocess_proteinGroups()
 
     def preprocess_peptides(self):
+        """
+        | Preprocess the *peptides.txt* file to internal format and return DataFrame with all those peptides not
+          marked as contaminant.
+        | Contaminants are defined as those peptides marked as *"Reverse"* or as *"Potential contaminant"* in the
+          *peptides.txt* file.
+
+        Returns
+        -------
+        DataFrame
+            DataFrame containing preprocessed data from *peptides.txt* file
+        """
         file_dir = os.path.join(self.data_dir, MQReader.peptides_txt)
         df_peptides = pd.read_csv(file_dir, sep="\t")
         df_peptides.columns = self.rename_df_columns(df_peptides.columns)
-        not_contaminants = (df_peptides[
-                                ["Reverse", "Potential contaminant"]] == "+"
-                            ).sum(axis=1) == 0
+        not_contaminants = (df_peptides[["Reverse", "Potential contaminant"]] == "+").sum(axis=1) == 0
         df_peptides = df_peptides[not_contaminants]
         self.logger.debug("Removing %s rows from %s because they are marked as contaminant",
                           (~not_contaminants).sum(), MQReader.peptides_txt)
@@ -334,6 +317,14 @@ def preprocess_peptides(self):
         return df_peptides
 
     def preprocess_summary(self):
+        """
+        | Preprocess the *summary.txt* file to internal format and return DataFrame.
+
+        Returns
+        -------
+        DataFrame
+            DataFrame containing preprocessed data from *summary.txt* file
+        """
         file_dir = os.path.join(self.data_dir, MQReader.summary_txt)
         df_summary = pd.read_csv(file_dir, sep="\t", encoding="unicode-escape")
         df_summary.columns = self.rename_df_columns(df_summary.columns)
@@ -342,11 +333,30 @@ def preprocess_summary(self):
         return df_summary
 
     def preprocess_parameters(self):
+        """
+        | Preprocess the *parameters.txt* file to internal format and return DataFrame.
+
+        Returns
+        -------
+        DataFrame
+            DataFrame containing preprocessed data from *parameters.txt* file
+        """
         file_dir = os.path.join(self.data_dir, MQReader.parameters_txt)
         df_parameters = pd.read_csv(file_dir, sep="\t", index_col=[0], squeeze=True)
         return df_parameters
 
     def preprocess_evidence(self):
+        """
+        | Preprocess the *evidence.txt* file to internal format and return DataFrame with all those peptides not
+          marked as contaminant.
+        | Contaminants are defined as those peptides marked as *"Reverse"* or as *"Potential contaminant"* in the
+          *evidence.txt* file.
+
+        Returns
+        -------
+        DataFrame
+            DataFrame containing preprocessed data from *evidence.txt* file
+        """
         file_dir = os.path.join(self.data_dir, MQReader.evidence_txt)
         df_evidence = pd.read_csv(file_dir, sep="\t")
         not_contaminants = (df_evidence[["Reverse", "Potential contaminant"]] == "+").sum(axis=1) == 0
@@ -356,12 +366,30 @@ def preprocess_evidence(self):
         return df_evidence
 
     def preprocess_msScans(self):
+        """
+        | Preprocess the *msScans.txt* file to internal format and return DataFrame.
+        | Only columns *"Raw file", "Total ion current"* and *"Retention time"* are read in.
+
+        Returns
+        -------
+        DataFrame
+            DataFrame containing preprocessed data from *msScans.txt* file
+        """
         file_dir = os.path.join(self.data_dir, MQReader.ms_scans_txt)
         df_msscans = pd.read_csv(file_dir, sep="\t", index_col=[0],
                                  usecols=["Raw file", "Total ion current", "Retention time"])
         return df_msscans
 
     def preprocess_msmsScans(self):
+        """
+        | Preprocess the *msmsScans.txt* file to internal format and return DataFrame.
+        | Only columns *"Raw file", "Total ion current"* and *"Retention time"* are read in.
+
+        Returns
+        -------
+        DataFrame
+            DataFrame containing preprocessed data from *msmsScans.txt* file
+        """
         file_dir = os.path.join(self.data_dir, MQReader.msms_scans_txt)
         df_msmsscans = pd.read_csv(file_dir, sep="\t", index_col=[0],
                                    usecols=["Raw file", "Total ion current", "Retention time"])
diff --git a/mspypeline/helpers/Utils.py b/mspypeline/helpers/Utils.py
index 087c6e7..82a98bb 100644
--- a/mspypeline/helpers/Utils.py
+++ b/mspypeline/helpers/Utils.py
@@ -1,4 +1,4 @@
-from typing import Optional, Dict, Tuple, Iterator, Union, Iterable, Sized
+from typing import Optional, Dict, Tuple, Iterator, Union, Iterable, Sized, Callable
 import pandas as pd
 from collections import defaultdict as ddict
 from itertools import combinations
@@ -43,7 +43,7 @@ def get_analysis_design(names: Iterable[str]) -> dict:
     return default_to_regular(analysis_design)
 
 
-def plot_annotate_line(ax, row1, row2, x, data,  fs: int = None, maxasterix: int = 5):
+def plot_annotate_line(ax, row1, row2, x, data,  fs: int = None, maxasterix: int = 3):
     """
     adjusted function
     from: https://stackoverflow.com/questions/11517986/indicating-the-statistically-significant-difference-in-bar-graph
@@ -128,7 +128,27 @@ def get_number_of_non_na_values(x: int, offset: int = 0) -> int:
     return max(int(np.round(percentage * x)) - offset, 3 - offset)
 
 
-def get_intersection_and_unique(v1: pd.DataFrame, v2: pd.DataFrame, na_function=get_number_of_non_na_values):
+def get_intersection_and_unique(v1: pd.DataFrame, v2: pd.DataFrame, na_function: Callable = get_number_of_non_na_values):
+    """
+    Given two dataframes with identical index, determines which rows (proteins) are present in both dataframes, or
+    unique to either dataframe. The number of missing values are counted row-wise and all rows above a threshold are
+    marked as positive. The threshold is determined by the na_function, which determines the allowed number of missing
+    values based on the number of columns. Then all rows which are positive in both dataframes are marked as
+    intersection. Rows that are positive in one dataframe but are missing completely in the other are marked as unique.
+    Parameters
+    ----------
+    v1
+        first dataframe
+    v2
+        second dataframe
+    na_function
+        function which takes and returns an int
+
+    Returns
+    -------
+    Three masks: The intersection, unique in v1 and unique in v2
+
+    """
     # get number of allowed non na values for both dataframes
     non_na_group_1 = na_function(v1.shape[1])
     non_na_group_2 = na_function(v2.shape[1])
@@ -160,7 +180,7 @@ def dict_depth(d: dict) -> int:
     return level
 
 
-def get_legend_elements(labels: list, color_map: Optional[dict] = None):
+def get_legend_elements(labels: list, color_map: Optional[dict] = None, marker_size:Optional[int] = None):
     """
         Returns custom legend elements based on a list of labels and an optional color map.
         These elements can be passed to a legend via the 'handles' parameter
@@ -175,8 +195,10 @@ def get_legend_elements(labels: list, color_map: Optional[dict] = None):
     """
     if color_map is None:
         color_map = {name: f"C{i}" for i, name in enumerate(labels)}
+    if marker_size is None:
+        marker_size=10
     legend_elements = [Line2D([0], [0], marker='o', color='w', label=name.replace("_", " "),
-                              markerfacecolor=color_map.get(name, "blue"), markersize=10)
+                              markerfacecolor=color_map.get(name, "blue"), markersize=marker_size)
                        for name in labels]
     return legend_elements
 
@@ -203,14 +225,15 @@ def get_plot_name_suffix(df_to_use: Optional[str] = None, level: Optional[int] =
 
 
 class DataDict(dict):
+    """
+    Overwrites the standard dictionary to provide an additional DataSource.
+    When a missing key is looked up the DataSource is searched for a method named:
+    e.g. looking up key=parameters, looking for method named "preprocess_parameters",
+    which is expected to return data, which will then be stored under the key.
+    This allows data from disk to be loaded on demand instead of loading all possible data at the beginning.
+    """
     def __init__(self, data_source, *args, **kwargs):
         """
-        Overwrites the standard dictionary to provide an additional DataSource.
-        When a missing key is looked up the DataSource is searched for a method named:
-        e.g. looking up key=parameters, looking for method named "preprocess_parameters",
-        which is expected to return data, which will then be stored under the key.
-        This allows data from disk to be loaded on demand instead of loading all possible data at the beginning.
-
         Parameters
         ----------
         data_source
diff --git a/mspypeline/modules/DataStructure.py b/mspypeline/modules/DataStructure.py
index 92d2f99..2b219cf 100644
--- a/mspypeline/modules/DataStructure.py
+++ b/mspypeline/modules/DataStructure.py
@@ -176,7 +176,9 @@ def groupby(
 
 
 class DataTree:
-    """Summary line
+    """
+    Data Structure in which the experiment is stored. Each leaf node is a
+    :class:`~mspypeline.DataNode`
 
     Attributes
     ----------
diff --git a/mspypeline/modules/Normalization.py b/mspypeline/modules/Normalization.py
index 1049576..bda358f 100644
--- a/mspypeline/modules/Normalization.py
+++ b/mspypeline/modules/Normalization.py
@@ -133,14 +133,15 @@ def determine_rank_invariance(df: pd.DataFrame, nri_threshold: float = 0.5) -> T
 
 
 class BaseNormalizer(ABC):
+    """
+    Abstract base class for Normalizers. Derived normalizers should implement the :meth:`fit` and :meth:`transform`.
+    """
     def __init__(self, input_scale: str = "log2",
                  output_scale: str = "normal",
                  col_name_prefix: Optional[str] = None,
                  loglevel: int = logging.DEBUG,
                  **kwargs):
         """
-        Abstract base class for Normalizers. Derived normalizers should implement the :meth:`fit` and :meth:`transform`.
-
         Parameters
         ----------
         input_scale
@@ -225,15 +226,16 @@ def fit_transform(self, data: pd.DataFrame):
 
 
 class MedianNormalizer(BaseNormalizer):
+    """
+    Median normalizer, which calculates a factor for each column (sample) by taking the column wise median.
+    Then from each column wise median the mean of all medians is subtracted.
+    """
     def __init__(self, input_scale: str = "log2",
                  output_scale: str = "normal",
                  col_name_prefix: Optional[str] = None,
                  loglevel: int = logging.DEBUG,
                  **kwargs):
         """
-        Median normalizer, which calculates a factor for each column (sample) by taking the column wise median.
-        Then from each column wise median the mean of all medians is subtracted.
-
         Parameters
         ----------
         input_scale
@@ -271,6 +273,10 @@ def transform(self, data: pd.DataFrame):
 
 
 class QuantileNormalizer(BaseNormalizer):
+    """
+    Quantile Normalizer as described on wikipedia
+    https://en.wikipedia.org/wiki/Quantile_normalization
+    """
     def __init__(self, missing_value_handler: Optional[Callable] = interpolate_data,
                  input_scale: str = "log2",
                  output_scale: str = "normal",
@@ -278,9 +284,6 @@ def __init__(self, missing_value_handler: Optional[Callable] = interpolate_data,
                  loglevel: int = logging.DEBUG,
                  **kwargs):
         """
-        Quantile Normalizer as described on wikipedia
-        https://en.wikipedia.org/wiki/Quantile_normalization
-
         Parameters
         ----------
         missing_value_handler
@@ -334,6 +337,12 @@ def transform(self, data: pd.DataFrame):
 
 
 class TailRobustNormalizer(BaseNormalizer):
+    """
+    An abstracted implementation of the Tail Robust Quantile Normalization as described here:
+    https://www.biorxiv.org/content/10.1101/2020.04.17.046227v1.full . Caclulates an offset factor by taking the
+    column wise mean. Then before a normalization is applied the offset factor is subtracted from each column.
+    Then the normalizer is applied and lastly the offset factor is added again.
+    """
     def __init__(self, normalizer: Type[BaseNormalizer] = QuantileNormalizer,
                  missing_value_handler: Optional[Callable] = interpolate_data,
                  input_scale: str = "log2",
@@ -342,11 +351,6 @@ def __init__(self, normalizer: Type[BaseNormalizer] = QuantileNormalizer,
                  loglevel: int = logging.DEBUG,
                  **kwargs):
         """
-        An abstracted implementation of the Tail Robust Quantile Normalization as described here:
-        https://www.biorxiv.org/content/10.1101/2020.04.17.046227v1.full . Caclulates an offset factor by taking the
-        column wise mean. Then before a normalization is applied the offset factor is subtracted from each column.
-        Then the normalizer is applied and lastly the offset factor is added again.
-
         Parameters
         ----------
         normalizer
diff --git a/mspypeline/plotting_backend/matplotlib_plots.py b/mspypeline/plotting_backend/matplotlib_plots.py
index 4f892f1..52cedde 100644
--- a/mspypeline/plotting_backend/matplotlib_plots.py
+++ b/mspypeline/plotting_backend/matplotlib_plots.py
@@ -1,4 +1,5 @@
 import os
+from copy import copy
 from itertools import combinations
 from typing import Tuple, Optional, Union, Callable, Dict, Iterable
 import pandas as pd
@@ -8,6 +9,7 @@
 import matplotlib.colors as colors
 import matplotlib.cm as cm
 import matplotlib.lines as mlines
+from matplotlib import rcParams
 from matplotlib.backends.backend_pdf import PdfPages
 from matplotlib.collections import LineCollection
 from adjustText import adjust_text
@@ -21,9 +23,11 @@
 import warnings
 
 from mspypeline.helpers import get_number_rows_cols_for_fig, plot_annotate_line, get_legend_elements, \
-    get_plot_name_suffix, get_intersection_and_unique, venn_names, format_docstrings
+    get_plot_name_suffix, venn_names, format_docstrings
 
 FIG_FORMAT = ".pdf"
+rcParams["pdf.fonttype"] = 42
+rcParams["ps.fonttype"] = 42
 
 
 def linear(x, m, b):
@@ -201,6 +205,8 @@ def wrapper_save_venn(*args, **kwargs):
                                       f"({len(named_sets)}")
                         continue
                     save_path, txt_name = get_path_and_name_from_kwargs(file_name, **kwargs)
+                    if save_path is None:
+                        continue
                     os.makedirs(save_path, exist_ok=True)
                     for intersected, unioned, result in venn_names(named_sets):
                         # create name based on the intersections and unions that were done
@@ -217,10 +223,11 @@ def wrapper_save_venn(*args, **kwargs):
 
 
 class QuantileNormalize(colors.Normalize):
+    """
+    Can be used to color the values of a dataset according to the quantiles.
+    """
     def __init__(self, quantiles: pd.Series):
         """
-        Can be used to color the values of a dataset according to the quantiles.
-
         Parameters
         ----------
         quantiles
@@ -261,10 +268,11 @@ def split_plot(n_rows, n_cols, figsize=(7, 7), plot_name="", data=None, plot_fn=
 @save_csvs({"unique_g1": "csv_significant/volcano_plot_data_{g1}_vs_{g2}_unique_{g1}",
             "unique_g2": "csv_significant/volcano_plot_data_{g1}_vs_{g2}_unique_{g2}"})
 def save_volcano_results(
-        volcano_data: pd.DataFrame, interesting_proteins, unique_g1: pd.Series = None, unique_g2: pd.Series = None, g1: str = "group1",
-        g2: str = "group2", adj_pval: bool = False, intensity_label: str = "Intensity",
-        show_suptitle: bool = True, pval_threshold: float = 0.05, fchange_threshold: float = 2,
-        scatter_size: float = 10, n_labelled_proteins: int = 10, **kwargs
+        volcano_data: pd.DataFrame, interesting_proteins, unique_g1: pd.Series = None,
+        unique_g2: pd.Series = None, g1: str = "group1", g2: str = "group2", adj_pval: bool = False,
+        intensity_label: str = "Intensity", show_suptitle: bool = True, pval_threshold: float = 0.05,
+        fchange_threshold: float = 2, scatter_size: float = 20, n_labelled_proteins: int = 10, close_plots: str = "all",
+        **kwargs
 ) -> Tuple[plt.Figure, Tuple[plt.Axes, plt.Axes, plt.Axes]]:
     """
     Saves multiple csv files and images containing the information of the volcano plot
@@ -274,33 +282,38 @@ def save_volcano_results(
     volcano_data
         DataFrame containing data for the volcano plot with columns logFC and column specified under col. The index
         should be protein names or gene names
+    interesting_proteins
+        mapping of pathways that shoul be annotated in the volcano plot
     unique_g1
         Series containing intensities of proteins or genes unique to group one
     unique_g2
         Series containing intensities of proteins or genes unique to group two
     g1
-        Name of group one
+        name of first sample that should be analysed (downregulated)
     g2
-        Name of group two
+        name of second sample that should be analysed (upregulated)
     adj_pval
-        Should adjusted or unadjusted p values be used
+        should adjusted p values be used
     intensity_label
-        From which intensities were the fold changes calculated
+        from which intensities were the fold changes calculated
     show_suptitle
-        Should the figure title be shown
+        should the figure title be shown
     pval_threshold
-        Maximum p value to be considered significant
+        maximum p value to be considered significant
     fchange_threshold
-        Minimum fold change threshold (before log2 transformation) to be labelled significant
+        minimum fold change threshold (before log2 transformation) to be labelled significant
     scatter_size
         size of the points in the scatter plots
     n_labelled_proteins
-        number of points that will be marked in th plot
+        number of points that will be annotated in th plot
+    close_plots
+        which plots should be closed when creating the plot, if None no plots will be closed
     kwargs
         {kwargs}
 
     """
-    plt.close("all")
+    if close_plots is not None:
+        plt.close(close_plots)
 
     col_mapping = {"adjpval": "adjusted p value", "pval": "unadjusted p value"}
     if adj_pval:
@@ -309,10 +322,12 @@ def save_volcano_results(
         col = "pval"
 
     # given pathway mapping(s)/proteins of interest create a list later used to be annotated in the volcano plot
+    pathway_label = ""
     POI_vals = []
     if interesting_proteins.values():
         all_pathway_proteins = set.union(*(set(x) for x in interesting_proteins.values()))
         POI_vals = volcano_data[volcano_data.index.isin(list(all_pathway_proteins))]
+        pathway_label = "_".join(interesting_proteins.keys())
 
     def get_volcano_significances(fchange, pval, pval_threshold, fchange_threshold):
         if pval > pval_threshold or abs(fchange) < np.log2(fchange_threshold):
@@ -324,7 +339,6 @@ def get_volcano_significances(fchange, pval, pval_threshold, fchange_threshold):
         else:
             raise ValueError(f"heisenbug: fold change: {fchange}, p value: {pval}")
 
-
     g1_name = g1.replace("_", " ")
     g2_name = g2.replace("_", " ")
 
@@ -333,15 +347,17 @@ def get_volcano_significances(fchange, pval, pval_threshold, fchange_threshold):
                                   for log_fold_change, p_val in zip(volcano_data["logFC"], volcano_data[col])]
 
     # save the volcano data csv in full and only the significant part
-    save_path, csv_name = get_path_and_name_from_kwargs("csv_full/volcano_plot_data_{g1}_vs_{g2}_full_{p}",
-                                                        g1=g1, g2=g2, p=col_mapping[col].replace(' ', '_'), **kwargs)
+    save_path, csv_name = get_path_and_name_from_kwargs(
+        "csv_full/volcano_plot_data_{g1}_vs_{g2}_full_{p}_{pathway_label}", g1=g1, g2=g2,
+        p=col_mapping[col].replace(' ', '_'), pathway_label=pathway_label, **kwargs)
     save_csv_fn(save_path, csv_name, volcano_data)
-    save_path, csv_name = get_path_and_name_from_kwargs("csv_significant/volcano_plot_data_{g1}_vs_{g2}_significant_{p}",
-                                                        g1=g1, g2=g2, p=col_mapping[col].replace(' ', '_'), **kwargs)
+    save_path, csv_name = get_path_and_name_from_kwargs(
+        "csv_significant/volcano_plot_data_{g1}_vs_{g2}_significant_{p}_{pathway_label}", g1=g1, g2=g2,
+        p=col_mapping[col].replace(' ', '_'), pathway_label=pathway_label, **kwargs)
     save_csv_fn(save_path, csv_name, volcano_data[volcano_data[col] < 0.05])
 
-    significance_to_color = {"ns": "gray", "up": "red", "down": "blue"}
-    significance_to_label = {"ns": "non-significant", "up": f"higher in  {g2_name}", "down": f"higher in  {g1_name}"}
+    significance_to_color = {"down": "blue", "ns": "gray", "up": "red"}
+    significance_to_label = {"down": f"higher in  {g1_name}", "ns": "non-significant", "up": f"higher in  {g2_name}"}
 
     # plot
     fig = plt.figure(figsize=(7, 7))
@@ -364,8 +380,9 @@ def get_volcano_significances(fchange, pval, pval_threshold, fchange_threshold):
     # non sign gray, left side significant blue, right side red
     for regulation in significance_to_color:
         mask = [x == regulation for x in volcano_data["regulation"]]
-        ax.scatter(volcano_data["logFC"][mask], -np.log10(volcano_data[col])[mask], s=scatter_size,
-                   color=significance_to_color[regulation], label=f"{sum(mask)} {significance_to_label[regulation]}")
+        ax.scatter(volcano_data["logFC"][mask], -np.log10(volcano_data[col])[mask], s=scatter_size, edgecolors="none",
+                   color=significance_to_color[regulation], alpha=0.6,
+                   label=f"{sum(mask)} {significance_to_label[regulation]}")
     # get axis bounds for vertical and horizontal lines
     ymin, ymax = ax.get_ybound()
     xmin, xmax = ax.get_xbound()
@@ -387,10 +404,10 @@ def get_volcano_significances(fchange, pval, pval_threshold, fchange_threshold):
         ax.axvline(-np.log2(fchange_threshold), **axline_kwargs, ymin=y_percentage, ymax=1)
         ax.axvline(np.log2(fchange_threshold), **axline_kwargs, ymin=y_percentage, ymax=1)
     # plot unique values with mean intensity at over maximum
-    ax_unique_down.scatter([0] * len(unique_g1), unique_g1, s=scatter_size, color="dodgerblue",
-                           label=f"{len(unique_g1)} unique in  {g1_name}")
-    ax_unique_up.scatter([0] * len(unique_g2), unique_g2, s=scatter_size, color="coral",
-                         label=f"{len(unique_g2)} unique in  {g2_name}")
+    ax_unique_down.scatter([0] * len(unique_g1), unique_g1, s=scatter_size, color="dodgerblue", edgecolors="none",
+                           alpha=0.6, label=f"{len(unique_g1)} unique in  {g1_name}")
+    ax_unique_up.scatter([0] * len(unique_g2), unique_g2, s=scatter_size, color="coral", edgecolors="none",
+                         alpha=0.6, label=f"{len(unique_g2)} unique in  {g2_name}")
     # adjust bounds for unique axis
     ymin_down, ymax_down = ax_unique_down.get_ybound()
     ymin_up, ymax_up = ax_unique_up.get_ybound()
@@ -399,7 +416,7 @@ def get_volcano_significances(fchange, pval, pval_threshold, fchange_threshold):
 
     # figure stuff
     if show_suptitle:
-        fig.suptitle(f"{g1} vs {g2}")
+        fig.suptitle(f"{g1_name} vs {g2_name}")
     ax.set_xlabel(f"{intensity_label} Fold Change")
     ax.set_ylabel(r"-$Log_{10}$" + f" {col_mapping[col]}")
     ax_unique_down.set_ylabel(intensity_label)
@@ -408,8 +425,9 @@ def get_volcano_significances(fchange, pval, pval_threshold, fchange_threshold):
     fig.tight_layout(rect=[0, 0.03, 1, 0.95])
 
     # save intermediate results
-    path, plot_name = get_path_and_name_from_kwargs(name="plots/volcano_{g1}_{g2}_no_annotation_{p}", g1=g1, g2=g2,
-                                                         p=col_mapping[col].replace(' ', '_'), **kwargs)
+    path, plot_name = get_path_and_name_from_kwargs(name="plots/volcano_{g1}_{g2}_no_annotation_{p}_{pathway_label}",
+                                                    g1=g1, g2=g2, p=col_mapping[col].replace(' ', '_'),
+                                                    pathway_label=pathway_label, **kwargs)
     save_plot_func(fig, path, plot_name, save_volcano_results, **kwargs)
 
     # add text labels to the most significantly regulated genes
@@ -435,8 +453,9 @@ def get_volcano_significances(fchange, pval, pval_threshold, fchange_threshold):
     adjust_text(texts, arrowprops=dict(width=0.15, headwidth=0, color='gray', alpha=0.6), ax=ax)
 
     # save the final result
-    path, plot_name = get_path_and_name_from_kwargs(name="plots/volcano_{g1}_{g2}_annotation_{p}", g1=g1, g2=g2,
-                                                         p=col_mapping[col].replace(' ', '_'), **kwargs)
+    path, plot_name = get_path_and_name_from_kwargs(name="plots/volcano_{g1}_{g2}_annotation_{p}_{pathway_label}",
+                                                    g1=g1, g2=g2, p=col_mapping[col].replace(' ', '_'),
+                                                    pathway_label=pathway_label, **kwargs)
     save_plot_func(fig, path, plot_name, save_volcano_results, **kwargs)
     # TODO scatter plot of significant genes
     return fig, (ax, ax_unique_down, ax_unique_up)
@@ -446,7 +465,8 @@ def get_volcano_significances(fchange, pval, pval_threshold, fchange_threshold):
 @format_docstrings(kwargs=_get_path_and_name_kwargs_doc)
 def save_pca_results(
         pca_data: pd.DataFrame, pca_fit: PCA = None, normalize: bool = True, intensity_label: str = "Intensity",
-        color_map: Optional[dict] = None, show_suptitle: bool = True, **kwargs
+        color_map: Optional[dict] = None, show_suptitle: bool = True, marker_size: int = 150,
+        legend_marker_size: int = 12, close_plots: str = "all", **kwargs
 ) -> Tuple[plt.Figure, plt.Axes]:
     """
     Saves image containing the pca results with prefix: {{name}}
@@ -458,18 +478,25 @@ def save_pca_results(
     pca_fit
         PCA object that was fitted to normalized input data
     normalize
-        Boolean whether the transformed data should be normalized with the singular values before plotting
+        should the transformed data be normalized with the singular values before plotting
     intensity_label
         figure title
     color_map
         mapping from column name to color if custom colors are wanted
     show_suptitle:
-        Should the figure title be shown
+        should the figure title be shown
+    marker_size
+        size of the points in the scatter plots
+    legend_marker_size
+        size of the legend marker
+    close_plots
+        which plots should be closed when creating the plot, if None no plots will be closed
     kwargs
         {kwargs}
 
     """
-    plt.close("all")
+    if close_plots is not None:
+        plt.close(close_plots)
     n_components = pca_data.shape[0]
     singular_values = np.ones(n_components)
     base_color_map = {value: f"C{i}" for i, value in enumerate(pca_data.columns.get_level_values(0).unique())}
@@ -492,11 +519,11 @@ def save_pca_results(
         ax.scatter(
             pca_data.loc["PC_1"] / singular_values[0],
             pca_data.loc["PC_2"] / singular_values[1],
-            s = 100,
+            s=marker_size, edgecolors="none",
             c=[base_color_map.get(name, "blue") for name in pca_data.columns.get_level_values(0)])
-        ax.set_xlabel("PC 1 - {0}".format(pca_var[0]), fontsize = 22)
-        ax.set_ylabel("PC 2 - {0}".format(pca_var[1]), fontsize = 22)
-        ax.tick_params(axis = "both", labelsize = 18)
+        ax.set_xlabel("PC 1 - {0}".format(pca_var[0]), fontsize=22, labelpad=20)
+        ax.set_ylabel("PC 2 - {0}".format(pca_var[1]), fontsize=22, labelpad=20)
+        ax.tick_params(axis="both", labelsize=18)
     else:
         fig, axarr = plt.subplots(n_components, n_components, figsize=(14, 14))
         for row in range(n_components):
@@ -508,17 +535,18 @@ def save_pca_results(
                     ax.scatter(
                         pca_data.loc[f"PC_{row_pc}"] / singular_values[row],
                         pca_data.loc[f"PC_{col_pc}"] / singular_values[col],
-                        s = 100,
+                        s=marker_size, edgecolors=None,
                         c=[base_color_map.get(name, "blue") for name in pca_data.columns.get_level_values(0)])
-                    ax.set_xlabel(f"PC {row_pc} - {0}".format(pca_var[0]), fontsize = 22)
-                    ax.set_ylabel(f"PC {col_pc} - {0}".format(pca_var[1]), fontsize = 22)
-                    ax.tick_params(axis = "both", labelsize = 18)
+                    ax.set_xlabel(f"PC {row_pc} - {pca_var[0]}", fontsize=22, labelpad=20)
+                    ax.set_ylabel(f"PC {col_pc} - {pca_var[1]}", fontsize=22, labelpad=20)
+                    ax.tick_params(axis="both", labelsize=18)
 
     if show_suptitle:
         fig.suptitle(intensity_label, fontsize=30)
-    legend_elements = get_legend_elements(labels=pca_data.columns.get_level_values(0).unique(), color_map=base_color_map)
-    fig.legend(handles=legend_elements, bbox_to_anchor=(1.02, 0.5), loc="center left", frameon=False, fontsize = 20)
-    fig.tight_layout(rect=[0, 0.03, 1, 0.95])
+    legend_elements = get_legend_elements(labels=pca_data.columns.get_level_values(0).unique(),
+                                          color_map=base_color_map, marker_size=legend_marker_size)
+    fig.legend(handles=legend_elements, bbox_to_anchor=(1.02, 0.5), loc="center left", frameon=False, fontsize=20)
+    fig.tight_layout(rect=[0.03, 0.03, 1, 0.95])
     return fig, axarr
 
 
@@ -527,8 +555,8 @@ def save_pca_results(
             "significances": "csv_pval/{pathway}_pvalues"})
 def save_pathway_analysis_results(
         protein_intensities: pd.DataFrame, significances: pd.DataFrame = None, pathway: str = "",
-        show_suptitle: bool = False, threshold: float = 0.05, intensity_label: str = "Intensity",
-        color_map: Optional[dict] = None, **kwargs
+        show_suptitle: bool = True, threshold: float = 0.05, intensity_label: str = "Intensity",
+        color_map: Optional[dict] = None, close_plots: str = "all", **kwargs
 ) -> Tuple[plt.Figure, plt.Axes]:
     """
     Saves plots into the pathway_analysis dir.
@@ -542,13 +570,15 @@ def save_pathway_analysis_results(
     pathway
         name of the pathway
     show_suptitle
-        should the pathway name be shown as overall title
+        should the pathway name be shown as figure title
     threshold
         maximum p value indicating significance
     intensity_label
         from which intensity was the data. will be shown on x axis
     color_map
         a mapping from the column names to a color
+    close_plots
+        which plots should be closed when creating the plot, if None no plots will be closed
     kwargs
         {kwargs}
 
@@ -556,17 +586,22 @@ def save_pathway_analysis_results(
     -------
 
     """
-    plt.close("all")
+    if close_plots is not None:
+        plt.close(close_plots)
     level_keys = list(protein_intensities.columns.get_level_values(0).unique())
     n_rows, n_cols = get_number_rows_cols_for_fig(protein_intensities.index)
-    fig, axarr = plt.subplots(n_rows, n_cols, figsize=(n_cols * 5, int(n_rows * len(level_keys) / 1.2)))
+    fig, axarr = plt.subplots(n_rows, n_cols, figsize=(n_cols * 5, int(n_rows * len(level_keys) / 1.1)))
+    for i in range(n_rows * n_cols - len(protein_intensities.index)):
+        axarr[n_rows - 1, n_cols - 1 - i].remove()
     result_color_map = {value: f"C{i}" for i, value in enumerate(level_keys)}
     result_color_map.update(color_map if color_map is not None else {})
     if show_suptitle:
-        fig.suptitle(pathway, size=28)
+        fig.suptitle(pathway.replace("_", " "), size=26)
     for protein, (pos, ax) in zip(protein_intensities.index, np.ndenumerate(axarr)):
-        ax.scatter(protein_intensities.loc[protein], [level_keys.index(c) for c in protein_intensities.columns.get_level_values(0)],
-                   c=[result_color_map[c] for c in protein_intensities.columns.get_level_values(0)])
+        ax.scatter(protein_intensities.loc[protein],
+                   [level_keys.index(c) for c in protein_intensities.columns.get_level_values(0)],
+                   c=[result_color_map[c] for c in protein_intensities.columns.get_level_values(0)], edgecolors="none",
+                   alpha=0.7)
         ax.set_title(protein)
         ax.set_ylim((-1, len(level_keys)))
         ax.set_yticks([i for i in range(len(level_keys))])
@@ -574,7 +609,6 @@ def save_pathway_analysis_results(
         if len(level_keys_labels) == 0:
             level_keys_labels = level_keys
         ax.set_yticklabels(level_keys_labels)
-        ax.set_yticklabels(level_keys)
         ax.set_xlabel(intensity_label)
     fig.tight_layout(rect=[0, 0.03, 1, 0.95])
 
@@ -590,7 +624,7 @@ def save_pathway_analysis_results(
             ax.set_xlim(right=xmax * (1 + to_annotate.shape[0] * 0.015))
             for i, (index, pval) in enumerate(to_annotate.items()):
                 plot_annotate_line(ax, level_keys.index(index[0]), level_keys.index(index[1]),
-                                   xmax * (1 + i * 0.015) - 0.005, pval, maxasterix = 3)
+                                   xmax * (1 + i * 0.015) - 0.005, pval, maxasterix=3)
 
         fig.tight_layout(rect=[0, 0.03, 1, 0.95])
 
@@ -603,7 +637,7 @@ def save_pathway_analysis_results(
 @format_docstrings(kwargs=_get_path_and_name_kwargs_doc)
 def save_boxplot_results(
         protein_intensities: pd.DataFrame, intensity_label: str = "Intensity",
-        plot: Optional[Tuple[plt.Figure, plt.Axes]] = None, vertical: bool = False, **kwargs
+        plot: Optional[Tuple[plt.Figure, plt.Axes]] = None, vertical: bool = False, close_plots: str = "all", **kwargs
 ) -> Tuple[plt.Figure, plt.Axes]:
     """
     Boxplot of intensities. Saves the plot with prefix: {{name}}
@@ -617,15 +651,18 @@ def save_boxplot_results(
     plot
         figure to put plot
     vertical
-        Should a vertical boxplot be created
+        should a vertical boxplot be created
+    close_plots
+        which plots should be closed when creating the plot, if None no plots will be closed
     kwargs
         {kwargs}
 
     """
     # TODO give colors to the different groups
     if plot is None:
-        plt.close("all")
-        fig, ax = plt.subplots(figsize=(14, 1 + len(protein_intensities.columns) // 3))
+        if close_plots is not None:
+            plt.close(close_plots)
+        fig, ax = plt.subplots(figsize=(14, 1 + len(protein_intensities.columns) // 2))
     else:
         fig, ax = plot
     # indicate overall median with a line
@@ -640,11 +677,13 @@ def save_boxplot_results(
         protein_intensities.loc[~pd.isna(protein_intensities.loc[:, c]), c].tolist()
         for c in protein_intensities.columns
     ]
-    ax.boxplot(data, vert=vertical, labels=protein_intensities.columns)
+    labels = [label.replace("_", " ") for label in protein_intensities.columns]
+    ax.boxplot(data, vert=vertical, labels=labels)
     if vertical:
-        ax.set_ylabel(intensity_label)
+        ax.set_ylabel(intensity_label, fontsize=15)
     else:
-        ax.set_xlabel(intensity_label)
+        ax.set_xlabel(intensity_label, fontsize=15)
+    ax.tick_params(labelsize=15)
     fig.tight_layout(rect=[0, 0.03, 1, 0.95])
     return fig, ax
 
@@ -653,7 +692,7 @@ def save_boxplot_results(
 @format_docstrings(kwargs=_get_path_and_name_kwargs_doc)
 def save_relative_std_results(
         intensities: pd.DataFrame, experiment_name: str, intensity_label: str = "Intensity",
-        show_suptitle: bool = True, bins=(10, 20, 30), cmap: dict = None, **kwargs
+        show_suptitle: bool = True, bins=(10, 20, 30), cmap: dict = None, close_plots: str = "all", **kwargs
 ) -> Tuple[plt.Figure, plt.Axes]:
     """
     Relative standard deviations of passed intensities with color marking based on the specified bins and color map.
@@ -668,18 +707,21 @@ def save_relative_std_results(
     intensity_label
         name of the intensities for the x label
     show_suptitle
-        should figure suptitle be shown
+        should the figure title be shown
     bins
         in which bins should the standard deviations be categorized
     cmap
         mapping for the digitized labels to a color
+    close_plots
+        which plots should be closed when creating the plot, if None no plots will be closed
     kwargs
         {kwargs}
 
     """
     # TODO add percentage to absolute numbers
     # TODO see if code could be optimized
-    plt.close("all")
+    if close_plots is not None:
+        plt.close(close_plots)
 
     bins = np.array(bins)
 
@@ -698,8 +740,8 @@ def save_relative_std_results(
     color_counts = {color: (plot_colors == color).sum() for color in plot_colors.unique()}
 
     fig, ax = plt.subplots(1, 1, figsize=(6, 4))
-    ax.scatter(intensities.mean(axis=1), relative_std_percent, c=plot_colors, marker="o", s=(2 * 72. / fig.dpi) ** 2,
-               alpha=0.8)
+    ax.scatter(intensities.mean(axis=1), relative_std_percent, c=plot_colors, marker="o", s=(4 * 72. / fig.dpi) ** 2,
+               alpha=0.7, edgecolors="none")
 
     experiment_name = experiment_name.replace("_", "  ")
     if show_suptitle:
@@ -722,7 +764,8 @@ def save_relative_std_results(
 @save_plot("detected_counts")
 @format_docstrings(kwargs=_get_path_and_name_kwargs_doc)
 def save_detection_counts_results(
-        counts: pd.DataFrame, intensity_label: str = "Intensity", show_suptitle: bool = True, **kwargs
+        counts: pd.DataFrame, intensity_label: str = "Intensity", show_suptitle: bool = True, close_plots: str = "all",
+        **kwargs
 ) -> Tuple[plt.Figure, plt.Axes]:
     """
     Saves the plot with prefix: {{name}}
@@ -735,44 +778,49 @@ def save_detection_counts_results(
         label of the dataframe
     show_suptitle
         should the figure title be shown
+    close_plots
+        which plots should be closed when creating the plot, if None no plots will be closed
     kwargs
         {kwargs}
 
     """
-    plt.close("all")
+    if close_plots is not None:
+        plt.close(close_plots)
 
     n_rows_experiment, n_cols_experiment = get_number_rows_cols_for_fig(counts.columns)
     fig, axarr = plt.subplots(n_rows_experiment, n_cols_experiment, squeeze=True,
                               figsize=(5 * n_cols_experiment, 3 * n_rows_experiment))
+    for i in range(n_rows_experiment * n_cols_experiment - len(counts.columns)):
+        axarr[n_rows_experiment - 1, n_cols_experiment - 1 - i].remove()
+
     if show_suptitle:
         fig.suptitle(f"Detection counts from {intensity_label}")
 
     global_max = counts.max().max()
-
-
     for (pos, ax), col in zip(np.ndenumerate(axarr), counts.columns):
         col_data = counts.loc[:, col]
         col_data = col_data[~pd.isna(col_data)]
-        col_name  = col.replace("_", " ")
+        col_name = col.replace("_", " ")
 
         ax.set_title(f"{col_name} \n total detected: {int(col_data.sum())}")
         ax.barh(col_data.index, col_data, color="skyblue")
 
-        if len(col_data) in range(1,9):
+        if len(col_data) in range(1, 9):
             fsize = 11
-        elif len(col_data) in range(9,13):
+        elif len(col_data) in range(9, 13):
             fsize = 7
         else:
             fsize = 5
 
         for y, value in zip(col_data.index, col_data):
             ax.text(col_data.max() / 2, y, value,
-                    verticalalignment='center', horizontalalignment='center', fontsize = fsize)
+                    verticalalignment='center', horizontalalignment='center', fontsize=fsize)
 
         ax.set_yticks(col_data.index)
         ax.set_yticklabels([f"detected in {i} replicates" for i in col_data.index], fontsize=fsize)
         ax.set_xlim(0, global_max + global_max*0.05)
-        ax.set_xlabel("Counts")
+        ax.set_xlabel("Counts", fontsize=fsize)
+        ax.tick_params(axis="both", labelsize=fsize)
 
     fig.tight_layout(rect=[0, 0.03, 1, 0.95])
     return fig, axarr
@@ -783,7 +831,7 @@ def save_detection_counts_results(
 def save_kde_results(
         intensities: pd.DataFrame, quantile_range: Optional[np.array] = None, n_points: int = 1000,
         cmap: Union[str, colors.Colormap] = "viridis", plot: Optional[Tuple[plt.Figure, plt.Axes]] = None,
-        intensity_label: str = "Intensity", **kwargs
+        intensity_label: str = "Intensity", close_plots: str = "all", **kwargs
 ) -> Tuple[plt.Figure, plt.Axes]:
     """
     saves the plot with prefix: {{name}}
@@ -802,6 +850,8 @@ def save_kde_results(
         figure to put plot
     intensity_label
         label to be put on x axis
+    close_plots
+        which plots should be closed when creating the plot, if None no plots will be closed
     kwargs
         {kwargs}
 
@@ -812,7 +862,8 @@ def save_kde_results(
     if plot is not None:
         fig, ax = plot
     else:
-        plt.close("all")
+        if close_plots is not None:
+            plt.close(close_plots)
         fig, ax = plt.subplots(1, 1)
 
     if quantile_range is None:
@@ -839,8 +890,9 @@ def save_kde_results(
         lc.set_linewidth(1)
         line = ax.add_collection(lc)
 
-    ax.set_ylabel("Density")
-    ax.set_xlabel(intensity_label)
+    ax.set_ylabel("Density", fontsize=15)
+    ax.set_xlabel(intensity_label, fontsize=15)
+    ax.tick_params(axis="both", labelsize=15)
 
     ax.autoscale_view()
 
@@ -853,7 +905,7 @@ def save_kde_results(
 def save_n_proteins_vs_quantile_results(
         quantiles: pd.DataFrame, n_proteins: pd.Series, nstd: int = 1, cmap: Union[str, colors.Colormap] = "viridis",
         plot: Optional[Tuple[plt.Figure, plt.Axes]] = None, cbar_ax: Optional[plt.Axes] = None,
-        intensity_label: str = "Intensity", fill_between: bool = False, **kwargs
+        intensity_label: str = "Intensity", fill_between: bool = False, close_plots: str = "all", **kwargs
 ) -> Tuple[plt.Figure, Tuple[plt.Axes, plt.Axes]]:
     """
     saves plot with prefix: {{name}}
@@ -876,6 +928,8 @@ def save_n_proteins_vs_quantile_results(
         label to put on x label
     fill_between
         should the area around the line be filled
+    close_plots
+        which plots should be closed when creating the plot, if None no plots will be closed
     kwargs
         {kwargs}
 
@@ -886,15 +940,16 @@ def save_n_proteins_vs_quantile_results(
     if plot is not None:
         fig, ax = plot
     else:
-        plt.close("all")
+        if close_plots is not None:
+            plt.close(close_plots)
         fig, ax = plt.subplots(1, 1, figsize=(14, 7))
 
     if not isinstance(cmap, colors.Colormap):
-        cmap = cm.get_cmap(cmap)
+        cmap = copy(cm.get_cmap(cmap))
 
     m = n_proteins.sort_values()
     for quant in quantiles.index:
-        ax.scatter(quantiles.loc[quant, :], n_proteins, c=[cmap(quant)] * len(n_proteins), alpha=0.5)
+        ax.scatter(quantiles.loc[quant, :], n_proteins, c=[cmap(quant)] * len(n_proteins), alpha=0.5, edgecolors="none")
         popt, pcov = curve_fit(linear, n_proteins, quantiles.loc[quant, :])
         fit = linear(m, *popt)
 
@@ -911,10 +966,11 @@ def save_n_proteins_vs_quantile_results(
     if cbar_ax is None:
         cbar_ax = fig.add_axes([0.2, 0.00, 0.6, 0.02])  # [left, bottom, width, height]
     cb = ColorbarBase(cbar_ax, cmap=cmap, orientation="horizontal")
-    cb.set_label("quantile")
+    cb.set_label("Quantile", fontsize=15)
 
-    ax.set_ylabel("# detected proteins")
-    ax.set_xlabel(intensity_label)
+    ax.set_ylabel("# detected proteins", fontsize=15)
+    ax.set_xlabel(intensity_label, fontsize=15)
+    ax.tick_params(axis="both", labelsize=15)
 
     fig.tight_layout(rect=[0, 0.03, 1, 0.95])
     return fig, (ax, cbar_ax)
@@ -924,7 +980,7 @@ def save_n_proteins_vs_quantile_results(
 @format_docstrings(kwargs=_get_path_and_name_kwargs_doc)
 def save_normalization_overview_results(
         quantiles, n_proteins, intensities, protein_intensities,
-        height: int = 15, intensity_label: str = "Intensity", **kwargs
+        height: int = 15, intensity_label: str = "Intensity", close_plots: str = "all", **kwargs
 ) -> Tuple[plt.Figure, Tuple[plt.Axes, plt.Axes, plt.Axes, plt.Axes]]:
     """
     saves plot with prefix: {{name}}
@@ -943,10 +999,14 @@ def save_normalization_overview_results(
         height of the figure
     intensity_label
         name of the experiment
+    close_plots
+        which plots should be closed when creating the plot, if None no plots will be closed
     kwargs
         {kwargs}
 
     """
+    if close_plots is not None:
+        plt.close(close_plots)
     fig = plt.figure(figsize=(18, 18), constrained_layout=True)
     gs = fig.add_gridspec(height, 2)
     ax_density = fig.add_subplot(gs[0:height // 2, 0])
@@ -954,17 +1014,19 @@ def save_normalization_overview_results(
     ax_colorbar = fig.add_subplot(gs[height - 1, 0])
     ax_boxplot = fig.add_subplot(gs[0:height, 1])
 
-    fig.suptitle(f"Normalization overview for {intensity_label}", size=28)
+    fig.suptitle(f"{intensity_label} overview", size=28)
     # order the boxplot data after the number of identified peptides
     boxplot_data = protein_intensities.loc[:, n_proteins.sort_values(ascending=False).index[::-1]]
 
     plot_kwargs = dict(intensity_label=intensity_label)
     plot_kwargs.update(**kwargs)
     plot_kwargs["save_path"] = None
+    plot_kwargs["close_plots"] = None
     with warnings.catch_warnings():
-        warnings.simplefilter("ignore", UserWarning)  # ignore warning for mixing constrained layout with thight_layout
+        warnings.simplefilter("ignore", UserWarning)  # ignore warning for mixing constrained layout with tight_layout
         save_kde_results(intensities=intensities,  plot=(fig, ax_density), **plot_kwargs)
-        save_n_proteins_vs_quantile_results(quantiles=quantiles, n_proteins=n_proteins, plot=(fig, ax_nprot), cbar_ax=ax_colorbar, **plot_kwargs)
+        save_n_proteins_vs_quantile_results(quantiles=quantiles, n_proteins=n_proteins, plot=(fig, ax_nprot),
+                                            cbar_ax=ax_colorbar, **plot_kwargs)
         save_boxplot_results(boxplot_data, plot=(fig, ax_boxplot), vertical=False, **plot_kwargs)
     ax_density.set_xlim(ax_nprot.get_xlim())
 
@@ -975,17 +1037,18 @@ def save_normalization_overview_results(
 @save_plot("intensities_heatmap")
 @format_docstrings(kwargs=_get_path_and_name_kwargs_doc)
 def save_intensities_heatmap_result(
-        intensities: pd.DataFrame, cmap: Union[str, colors.Colormap] = "autumn_r", cmap_bad: str ="dimgray",
+        intensities: pd.DataFrame, cmap: Union[str, colors.Colormap] = "autumn_r", cmap_bad: str = "dimgray",
         cax: plt.Axes = None, plot: Optional[Tuple[plt.Figure, plt.Axes]] = None, vmax: Optional[float] = None,
         vmin: Optional[float] = None,
-        intensity_label: str = "Intensity", show_suptitle: bool = True, **kwargs
+        intensity_label: str = "Intensity", show_suptitle: bool = True, close_plots: str = "all", **kwargs
 ) -> Tuple[plt.Figure, Tuple[plt.Axes, plt.Axes]]:
     """
     saves plot with prefix: {{name}}
-    
+
     Parameters
     ----------
     intensities
+        DataFrame containing protein intensities of samples
     cmap
         color map to use for heatmap coloring
     cmap_bad
@@ -1002,36 +1065,43 @@ def save_intensities_heatmap_result(
         name of the experiment
     show_suptitle
         should figure title be shown
+    close_plots
+        which plots should be closed when creating the plot, if None no plots will be closed
     kwargs
         {kwargs}
-
     """
     if plot is not None:
         fig, ax = plot
     else:
-        plt.close("all")
-        fig, ax = plt.subplots(figsize=(14, 16))  # TODO scale with intensities.shape
+        if close_plots is not None:
+            plt.close(close_plots)
+        if len(intensities.columns)*0.5 < 4:
+            height = 4
+        else:
+            height = len(intensities.columns)*0.5
+        fig, ax = plt.subplots(figsize=(17, height))
 
     if not isinstance(cmap, colors.Colormap):
-        cmap = cm.get_cmap(cmap)
+        cmap = copy(cm.get_cmap(cmap))
     if cmap_bad is not None:
         cmap.set_bad(color='dimgray')
 
-    im = ax.imshow(intensities.values.T, aspect="auto", cmap=cmap, vmin=vmin, vmax=vmax)
+    im = ax.imshow(intensities.values.T, aspect="auto", cmap=cmap, vmin=vmin, vmax=vmax, interpolation="none")
     if cax is None:
         cbar = ax.figure.colorbar(im, ax=ax)
     else:
         cbar = ax.figure.colorbar(im, cax=cax)
 
     if show_suptitle:
-        fig.suptitle(f"Present or absent in {intensity_label}")
-    ax.set_xlabel("Proteins")
+        fig.suptitle(f"Proteins detected or missing in {intensity_label}", fontsize=16)
+    ax.set_xlabel("Total proteins detected", fontsize=12)
 
     y_lim = ax.get_ylim()
     ax.set_yticks(np.linspace(0, len(intensities.columns) - 1, len(intensities.columns)))
     labels = [sample.replace("_", " ") for sample in intensities.columns.values]
-    ax.set_yticklabels(labels= labels)
+    ax.set_yticklabels(labels=labels)
     ax.set_ylim(*y_lim)
+    ax.tick_params(axis="both", labelsize=10)
 
     fig.tight_layout(rect=[0, 0.03, 1, 0.95])
     return fig, (ax, cbar.ax)
@@ -1040,7 +1110,8 @@ def save_intensities_heatmap_result(
 @save_plot("detection_per_replicate")
 @format_docstrings(kwargs=_get_path_and_name_kwargs_doc)
 def save_detected_proteins_per_replicate_results(
-        all_heights: Dict[str, pd.Series], intensity_label: str = "Intensity", show_suptitle: bool = True, **kwargs
+        all_heights: Dict[str, pd.Series], intensity_label: str = "Intensity", show_suptitle: bool = True,
+        close_plots: str = "all", **kwargs
 ):
     """
     saves plot with prefix: {{name}}
@@ -1052,16 +1123,22 @@ def save_detected_proteins_per_replicate_results(
     intensity_label
         name of the experiment
     show_suptitle
-        should a figure title be shown
+        should the figure title be shown
+    close_plots
+        which plots should be closed when creating the plot, if None no plots will be closed
     kwargs
         {kwargs}
 
     """
-    plt.close("all")
+    if close_plots is not None:
+        plt.close(close_plots)
     # determine number of rows and columns in the plot based on the number of experiments
     n_rows_experiment, n_cols_experiment = get_number_rows_cols_for_fig(all_heights.keys())
     fig, axarr = plt.subplots(n_rows_experiment, n_cols_experiment,
                               figsize=(5 * n_cols_experiment, 3 * n_rows_experiment))
+    for i in range(n_rows_experiment * n_cols_experiment - len(all_heights.keys())):
+        axarr[n_rows_experiment - 1, n_cols_experiment - 1 - i].remove()
+
     if show_suptitle:
         fig.suptitle(f"Number of detected proteins from {intensity_label}")
 
@@ -1077,25 +1154,26 @@ def save_detected_proteins_per_replicate_results(
         y_pos = [x for x in range(len(experiment_heights))]
         ax.barh(y_pos, experiment_heights, color="skyblue")
 
-        if len(experiment_heights) in range(1,10):
+        if len(experiment_heights) in range(1, 10):
             fsize = 11
-        elif len(experiment_heights) in range(10,16):
+        elif len(experiment_heights) in range(10, 16):
             fsize = 7
         else:
             fsize = 5
 
         for y, value in zip(y_pos, experiment_heights):
             ax.text(experiment_heights[0] / 2, y, value,
-                    verticalalignment='center', horizontalalignment='center', fontsize = fsize)
+                    verticalalignment='center', horizontalalignment='center', fontsize=fsize)
         labels = experiment_heights.index.values
         labels = [label.replace((experiment + "_"), "").replace("_", " ") for label in labels]
 
         ax.set_title(experiment.replace("_", "  "))
         ax.axvline(mean_height, linestyle="--", color="black", alpha=0.6)
         ax.set_yticks([i for i in range(len(experiment_heights.index))])
-        ax.set_yticklabels(labels, fontsize = fsize)
+        ax.set_yticklabels(labels, fontsize=fsize)
         ax.set_xlim(0, global_max + global_max*0.02)
-        ax.set_xlabel("Counts")
+        ax.set_xlabel("Counts", fontsize=fsize)
+
     fig.tight_layout(rect=[0, 0.03, 1, 0.95])
     return fig, axarr
 
@@ -1104,8 +1182,9 @@ def save_detected_proteins_per_replicate_results(
 @format_docstrings(kwargs=_get_path_and_name_kwargs_doc)
 def save_intensity_histogram_results(
         hist_data: pd.DataFrame, intensity_label: str = "Intensity", show_suptitle: bool = False,
-        compare_to_remaining: bool = False, n_bins: int = 25, histtype="bar", color=None,
-        plot: Optional[Tuple[plt.Figure, plt.Axes]] = None, **kwargs
+        compare_to_remaining: bool = False, legend: bool = True, n_bins: int = 25, show_mean: bool = True,
+        histtype="bar", color=None, plot: Optional[Tuple[plt.Figure, plt.Axes]] = None, close_plots: str = "all",
+        **kwargs
 ):
     """
     saves plot with prefix: {{name}}
@@ -1117,9 +1196,13 @@ def save_intensity_histogram_results(
     intensity_label
         name of experiment
     show_suptitle
-        should a figure title be shown
+        should the figure title be shown
     compare_to_remaining
         should the sample be compared to the overall samples
+    legend
+        should the legend of the sample names be shown
+    show_mean
+        should the mean intensity be shown
     n_bins
         how many bins should the histograms have
     histtype
@@ -1128,6 +1211,8 @@ def save_intensity_histogram_results(
         passed to hist
     plot
         figure to put plot
+    close_plots
+        which plots should be closed when creating the plot, if None no plots will be closed
     kwargs
         {kwargs}
 
@@ -1135,30 +1220,44 @@ def save_intensity_histogram_results(
     if plot is not None:
         fig, axarr = plot
     else:
-        plt.close("all")
+        if close_plots is not None:
+            plt.close(close_plots)
         n_rows, n_cols = get_number_rows_cols_for_fig(hist_data.columns.get_level_values(0).unique())
         fig, axarr = plt.subplots(n_rows, n_cols, figsize=(5 * n_cols, 5 * n_rows))
+        for i in range(n_rows * n_cols - len(hist_data.columns.get_level_values(0).unique())):
+            axarr[n_rows - 1, n_cols - 1 - i].remove()
 
     if show_suptitle:
         fig.suptitle(f"{intensity_label} histograms")
 
+    counts = []
+    for col in hist_data.columns:
+        col_count = pd.cut(hist_data[col], bins=int(np.ceil(n_bins*0.9))).value_counts()
+        counts.append(max(col_count))
+
     for col, (pos, ax) in zip(hist_data.columns.get_level_values(0).unique(), np.ndenumerate(axarr)):
         intensities = hist_data[col]
         try:
             labels = intensities.columns
         except AttributeError:
             labels = col
+        labels = [label.replace("_", " ") for label in labels]
 
         if "Log_2" in intensity_label:
             bins = np.linspace(np.nanmin(intensities.values), np.nanmax(intensities.values), n_bins)
         else:
-            bins = np.logspace(np.log2(np.nanmin(intensities.values)), np.log2(np.nanmax(intensities.values)), n_bins, base=2)
+            bins = np.logspace(np.log2(np.nanmin(intensities.values)), np.log2(np.nanmax(intensities.values)), n_bins,
+                               base=2)
 
         col_name = col.replace("_", "  ")
-        labels = [label.replace("_", " ") for label in labels]
-
         ax.set_title(col_name)
-        ax.hist(intensities, bins=bins, histtype=histtype, label=labels, color=color)
+
+        if not legend:
+            ax.hist(intensities, bins=bins, histtype=histtype, color=color)
+        elif legend and len(labels)<2:
+            ax.hist(intensities, bins=bins, histtype=histtype, color=color)
+        else:
+            ax.hist(intensities, bins=bins, histtype=histtype, color=color, label=labels)
 
         if compare_to_remaining:
             remaining = hist_data.drop(col, axis=1)
@@ -1169,6 +1268,18 @@ def save_intensity_histogram_results(
             ax.set_xscale("log", base=2)
         ax.set_xlabel(intensity_label)
         ax.set_ylabel("Counts")
+        ax.set_xlim(hist_data.min().min(), hist_data.max().max())
+        if histtype == ["bar"]:
+            ax.set_ylim(0, max(counts))
+
+        if show_mean:
+            means = []
+            for col in intensities.columns:
+                means.append(float(intensities[col].mean()))
+            mean = float(sum(means)) / float(len(means))
+            ax.axvline(mean, linestyle="--", color="black", alpha=0.6, linewidth=2.5,
+                       label='mean: {:5.2f}'.format(mean))
+        ax.legend(handlelength=1, handletextpad=0.8, loc='upper right', bbox_to_anchor=(0.98, 0.98), frameon=False)
 
     fig.tight_layout(rect=[0, 0.03, 1, 0.95])
     return fig, axarr
@@ -1177,7 +1288,8 @@ def save_intensity_histogram_results(
 @save_plot("scatter_{full_name}")
 @format_docstrings(kwargs=_get_path_and_name_kwargs_doc)
 def save_scatter_replicates_results(
-        scatter_data: pd.DataFrame, intensity_label: str = "Intensity", show_suptitle: bool = False, **kwargs
+        scatter_data: pd.DataFrame, intensity_label: str = "Intensity", show_suptitle: bool = True,
+        close_plots: str = "all", **kwargs
 ) -> Tuple[plt.Figure, plt.Axes]:
     """
     saves plot with prefix: {{name}}
@@ -1189,16 +1301,18 @@ def save_scatter_replicates_results(
     intensity_label
         name of the experiment
     show_suptitle
-        should a figure title be shown
+        should the figure title be shown
+    close_plots
+        which plots should be closed when creating the plot, if None no plots will be closed
     kwargs
         {kwargs}
 
     """
-    plt.close("all")
+    if close_plots is not None:
+        plt.close(close_plots)
     fig, ax = plt.subplots(1, 1, figsize=(6, 6))
 
-    if show_suptitle:
-        fig.suptitle()
+    min_counts = scatter_data.min().min()
 
     for rep1, rep2 in combinations(scatter_data.columns, 2):
         x1 = scatter_data.loc[:, rep1]
@@ -1208,14 +1322,16 @@ def save_scatter_replicates_results(
         exp = r"$r^{2}$"
         rep1 = rep1.replace("_", "  ")
         rep2 = rep2.replace("_", "  ")
-        ax.scatter(x1.fillna(x2.min() * 0.95)[plot_mask], x2.fillna(x2.min() * 0.95)[plot_mask],
-                       label=f"{rep1}  vs  {rep2},  "
-                        fr"{exp}: {stats.pearsonr(x1[corr_mask], x2[corr_mask])[0] ** 2:.4f}",
-                        alpha=0.5, marker=".")
-        ax.set_xlabel(intensity_label)
-        ax.set_ylabel(intensity_label)
-
-    fig.legend(frameon=False,  bbox_to_anchor=(1.02, 0.5), loc="center left")
+        ax.scatter(x1.fillna(min_counts)[plot_mask], x2.fillna(min_counts)[plot_mask],
+                   label=f"{rep1}  vs  {rep2},  "
+                         fr"{exp}: {stats.pearsonr(x1[corr_mask], x2[corr_mask])[0] ** 2:.4f}",
+                   alpha=0.5, s=40,  marker=".", edgecolors="none")
+        ax.set_xlabel(f"{intensity_label} of x1")
+        ax.set_ylabel(f"{intensity_label} of x2")
+        if show_suptitle:
+            ax.set_title(f"Scatter comparison of replicates using {intensity_label}")
+
+    fig.legend(frameon=False, bbox_to_anchor=(1.02, 0.5), loc="center left", title=r"$\bf{Sample\ x1\ vs\ Sample\ x2}$")
     if "Log_2" not in intensity_label:
         ax.set_xscale("log")
         ax.set_yscale("log")
@@ -1228,7 +1344,7 @@ def save_scatter_replicates_results(
 @format_docstrings(kwargs=_get_path_and_name_kwargs_doc)
 def save_rank_results(
         rank_data: pd.Series, interesting_proteins, intensity_label: str = "Intensity", full_name="Experiment",
-        show_suptitle: bool = False, **kwargs
+        close_plots: str = "all", **kwargs
 ) -> Tuple[plt.Figure, plt.Axes]:
     """
     saves plot with prefix: {{name}}
@@ -1242,13 +1358,15 @@ def save_rank_results(
     intensity_label
         name of the experiment
     full_name
-    show_suptitle
-        should figure title be shown
+        name of the sample/group plotted
+    close_plots
+        which plots should be closed when creating the plot, if None no plots will be closed
     kwargs
         {kwargs}
 
     """
-    plt.close("all")
+    if close_plots is not None:
+        plt.close(close_plots)
     if interesting_proteins.values():
         all_pathway_proteins = set.union(*(set(x) for x in interesting_proteins.values()))
     else:
@@ -1268,8 +1386,8 @@ def save_rank_results(
     x = [dic[protein][0] for protein in non_pathway_proteins]  # rank
     y = [dic[protein][1] for protein in non_pathway_proteins]  # intensity
 
-    fig, ax = plt.subplots(1, 1, figsize=(6, 4))
-    ax.scatter(x, y, c="darkgray", s=12, alpha=0.3, marker=".", label="no pathway")
+    fig, ax = plt.subplots(1, 1, figsize=(8, 6))
+    ax.scatter(x, y, c="darkgray", s=30, alpha=0.2, marker=".", label="no pathway", edgecolors="none")
 
     # plot all proteins of a specific pathway
     legend_text = []
@@ -1279,7 +1397,8 @@ def save_rank_results(
         if proteins:
             x = [dic[protein][0] for protein in proteins]  # the rank of each protein
             y = [dic[protein][1] for protein in proteins]  # the intensity of each protein
-            ax.scatter(x, y, c=f"C{i}", s=80, alpha=0.8, marker=".", label=pathway.replace("_", " "))
+            ax.scatter(x, y, c=f"C{i}", s=120, alpha=0.7, marker=".", edgecolors="none",
+                       label=pathway.replace("_", " "))
 
             median_pathway_rank = int(np.median(x))
             median_intensity = rank_data.iloc[median_pathway_rank]
@@ -1290,28 +1409,26 @@ def save_rank_results(
             # plot the median rank and intensity at that rank
             ax.axvline(median_pathway_rank, ymax=ym, linestyle="--", color=f"C{i}", alpha=0.6)
             ax.axhline(median_intensity, xmax=xm, linestyle="--", color=f"C{i}", alpha=0.6)
-            text = f"{pathway} : median rank: {median_pathway_rank / len(rank_data) * 100 :.1f}% "
+            pathway_label = pathway.replace("_", " ")
+            text = f"{pathway_label} : median rank: {median_pathway_rank / len(rank_data.dropna()) * 100 :.1f}% "
             legend_text.append(text)
             handle = mlines.Line2D([], [], color=f"C{i}", marker='.', markersize=10, label=text, linewidth=0)
             handles.append(handle)
-            # ax.text(xmin * 0.9, median_intensity * 0.9, text, verticalalignment="top", horizontalalignment="left")
-            # f"median rank: {median_pathway_rank} ({median_pathway_rank / len(rank_data) * 100 :.1f}%) "
-            # f"with intensity: {median_intensity:.2E}",  # TODO case for log and non log
-
 
-    legend_text.append("no pathway assigned")
-    handle = mlines.Line2D([], [], color="lightgray", marker='.', markersize=10, label=text, linewidth=0)
+    median_int_total = rank_data.dropna().median()
+    legend_text.append(f"Median intensity: {median_int_total :.1f} {intensity_label}")
+    handle = mlines.Line2D([], [], color="lightgray", marker='.', markersize=10, label=legend_text[-1], linewidth=0)
     handles.append(handle)
 
     exp_name = full_name.replace("_", " ")
     if "Log_2" not in intensity_label:
         ax.set_yscale("log")
-    ax.set_xlabel("Protein rank", size=10)
+    ax.set_xlabel("Protein rank", size=10, labelpad=10)
     # ax.set_ylabel(f"{exp_name} mean Log_2 intensity")
-    ax.set_ylabel(intensity_label, size=10)
-    ax.set_title(f"{exp_name} mean", weight="bold", size="14")
+    ax.set_ylabel(intensity_label, size=10, labelpad=10)
+    ax.set_title(f"{exp_name} mean", weight="bold", size="14", pad=10)
     # legend_text = [pathway for pathway in interesting_proteins.keys()]
-    fig.legend(labels=legend_text, handles=handles, bbox_to_anchor=(1.02, 0.5), loc="center left")
+    fig.legend(labels=legend_text, handles=handles, bbox_to_anchor=(1.02, 0.5), loc="center left", frameon=False)
     fig.tight_layout(rect=[0, 0.03, 1, 0.95])
     return fig, ax
 
@@ -1321,8 +1438,8 @@ def save_rank_results(
 def save_experiment_comparison_results(
         protein_intensities_sample1: pd.Series, protein_intensities_sample2: pd.Series,
         exclusive_sample1: pd.Series, exclusive_sample2: pd.Series, sample1: str, sample2: str,
-        intensity_label: str = "Intensity", show_suptitle: bool = False,
-        plot: Optional[Tuple[plt.Figure, plt.Axes]] = None,  **kwargs
+        intensity_label: str = "Intensity", show_suptitle: bool = True,
+        plot: Optional[Tuple[plt.Figure, plt.Axes]] = None, close_plots: str = "all", **kwargs
 ) -> Tuple[plt.Figure, plt.Axes]:
     """
     saves plot with prefix: {{name}}
@@ -1344,9 +1461,11 @@ def save_experiment_comparison_results(
     intensity_label
         name of experiment
     show_suptitle
-        should figure title be shown
+        should the figure title be shown
     plot
         figure to put plot
+    close_plots
+        which plots should be closed when creating the plot, if None no plots will be closed
     kwargs
         {kwargs}
 
@@ -1361,27 +1480,30 @@ def save_experiment_comparison_results(
     if plot is not None:
         fig, ax = plot
     else:
-        plt.close("all")
+        if close_plots is not None:
+            plt.close(close_plots)
         fig, ax = plt.subplots(1, 1, figsize=(6, 6))
 
     exp = r"$r^{2}$"
     sample1 = sample1.replace("_", " ")
     sample2 = sample2.replace("_", " ")
 
-    ax.scatter(protein_intensities_sample1, protein_intensities_sample2, s=8, alpha=0.6, marker=".",
+    ax.scatter(protein_intensities_sample1, protein_intensities_sample2, s=40, alpha=0.7, marker=".", edgecolors="none",
                label=f"{sample1}  vs  {sample2}, {exp}: {r[0] ** 2:.4f}")
     ax.scatter(exclusive_sample1, [np.min(protein_intensities_sample2) * 0.95] * exclusive_sample1.shape[0],
-               s=8, alpha=0.6, marker=".", label=f"exclusive for  {sample1}")
+               s=40, alpha=0.7, marker=".", edgecolors="none", label=f"unique for  {sample1}")
     ax.scatter([np.min(protein_intensities_sample1) * 0.95] * exclusive_sample2.shape[0], exclusive_sample2,
-               s=8, alpha=0.6, marker=".", label=f"exclusive for  {sample2}")
+               s=40, alpha=0.7, marker=".", edgecolors="none", label=f"unique for  {sample2}")
 
-    ax.set_xlabel(sample1, weight = "bold", labelpad= 10)
-    ax.set_ylabel(sample2, weight = "bold", labelpad = 10)
+    ax.set_xlabel(f"{intensity_label} of {sample1}", labelpad=10)
+    ax.set_ylabel(f"{intensity_label} of {sample2}", labelpad=10)
     fig.legend(frameon=False, bbox_to_anchor=(1.02, 0.5), loc="center left")
 
     if "Log_2" not in intensity_label:
         ax.set_xscale("log")
         ax.set_yscale("log")
+    if show_suptitle:
+        ax.set_title(f"Scatter comparison of groups using {intensity_label}")
 
     xmin, xmax = ax.get_xbound()
     ymin, ymax = ax.get_ybound()
@@ -1395,8 +1517,9 @@ def save_experiment_comparison_results(
 @save_plot("go_analysis")
 @format_docstrings(kwargs=_get_path_and_name_kwargs_doc)
 def save_go_analysis_results(
-        heights: Dict[str, list], test_results: Dict[str, list], go_analysis_gene_names: list,
-        intensity_label="Intensity", **kwargs
+        heights: Dict[str, list], test_results: Dict[str, list], go_length: Dict[str, list],
+        go_analysis_gene_names: list, show_suptitle: bool = True, intensity_label="Intensity", close_plots: str = "all",
+        **kwargs
 ) -> Tuple[plt.Figure, plt.Axes]:
     """
     saves plot with prefix: {{name}}
@@ -1407,33 +1530,39 @@ def save_go_analysis_results(
         mapping from samples to bar height
     test_results
         mapping from samples to p value
+    go_length
+        mapping of name to number of proteins of go terms
     go_analysis_gene_names
         names of the go term lists
+    show_suptitle
+        should the figure title be shown
     intensity_label
         name of the experiment
+    close_plots
+        which plots should be closed when creating the plot, if None no plots will be closed
     kwargs
         {kwargs}
 
     """
+    if close_plots is not None:
+        plt.close(close_plots)
 
-    plt.close("all")
-
-    go_analysis_gene_names = [go_term.replace("_", " ") for go_term in go_analysis_gene_names]
+    go_analysis_gene_names = [go_term.replace("_", " \n").replace(" + ", " \n") for go_term in go_analysis_gene_names]
 
     heights_df = pd.DataFrame(data=heights, index=go_analysis_gene_names)
     test_results_df = pd.DataFrame(data=test_results, index=go_analysis_gene_names)
     # save go analysis data
-    save_path, csv_name = get_path_and_name_from_kwargs(name = "tables/go_analysis_data", **kwargs)
+    save_path, csv_name = get_path_and_name_from_kwargs(name="tables/go_analysis_data", **kwargs)
     save_csv_fn(save_path, csv_name, heights_df)
     save_path, csv_name = get_path_and_name_from_kwargs(name="tables/go_analysis_pvals", **kwargs)
     save_csv_fn(save_path, csv_name, test_results_df)
-    #add extra col "background" to data frame - easier data handeling later
-    test_results_df.insert(0, "background", [1] * len(go_analysis_gene_names), True)
+    # add extra col "Total" to data frame - easier data handeling later
+    test_results_df.insert(0, "Total", [1] * len(go_analysis_gene_names), True)
 
     barwidth = 1 / (len(heights_df.columns) + 1)
     max_prot_count = heights_df.max().max()
     tick_y_pos = set()
-    fig, ax = plt.subplots(1, 1, figsize=(6, int(len(heights_df.columns) * len(go_analysis_gene_names)/1.5)))
+    fig, ax = plt.subplots(1, 1, figsize=(10, int(len(heights_df.columns) * len(go_analysis_gene_names)/1.5)))
     #for every sample plot a single bar per go term selected in one subplot
     for i, sample in enumerate(heights_df.columns):
         width = 1 / (len(heights_df.columns) + 1) * i
@@ -1446,14 +1575,20 @@ def save_go_analysis_results(
                 continue
             text = f"{pval:.4f}" if pval > 0.0005 else "< 0.0005"
             ax.annotate(f" p: {text}", xy=(x, y))
+
+    for i, total_count in enumerate(heights_df["Total"]):
+        ax.annotate(f"{total_count} / {go_length[i]}", xy=(total_count, list(tick_y_pos)[i]))
     #annotate each set of bars for a go term with the corresponding go term label = second layer of y axis labeling
     for i, go in enumerate(go_analysis_gene_names):
         text = go.split(".txt")[0].replace("_", " ")
-        ax.annotate(text, xy=(-max_prot_count*0.4, i + 0.5-(1/(2*(len(heights_df.columns)+1)))),
-                    rotation=90, verticalalignment="center", annotation_clip=False)
+        ax.annotate(text, xy=(-max_prot_count * 0.8, i + 0.5 - (1 / (2 * (len(heights_df.columns) + 1)))),
+                    verticalalignment="center", annotation_clip=False)
 
+    if show_suptitle:
+        ax.set_title(f"GO based analysis from {intensity_label}", pad=10)
     ax.set_yticks(sorted(list(tick_y_pos)))
-    ax.set_yticklabels(list(heights_df.columns.values) * len(heights_df))
+    labels = [label.replace("_", " ") for label in heights_df.columns]
+    ax.set_yticklabels(labels * len(heights_df))
     ax.set_xlim(0, max_prot_count + max_prot_count * 0.2)
     ax.set_xlabel('Number of detected proteins from GO list')
     fig.tight_layout(rect=[0, 0.03, 1, 0.95])
@@ -1502,7 +1637,7 @@ def save_pathway_timecourse_results():
 @save_venn_to_txt({"named_sets": "txts/set_bar"})
 @format_docstrings(kwargs=_get_path_and_name_kwargs_doc)
 def save_bar_venn(
-        named_sets: Dict[str, set], ex: str, show_suptitle: bool = True, **kwargs
+        named_sets: Dict[str, set], ex: str, show_suptitle: bool = True, close_plots: str = "all", **kwargs
 ) -> Optional[Tuple[plt.Figure, Tuple[plt.Axes, plt.Axes]]]:
     """
     saves plot with prefix: {{name}}
@@ -1514,12 +1649,15 @@ def save_bar_venn(
     ex
         figure title
     show_suptitle
-        should figure title be shown
+        should the figure title be shown
+    close_plots
+        which plots should be closed when creating the plot, if None no plots will be closed
     kwargs
         {kwargs}
 
     """
-    plt.close("all")
+    if close_plots is not None:
+        plt.close(close_plots)
     if len(named_sets) > 6:
         warnings.warn(f"Skipping bar-venn for {ex} because it has more than 6 experiments")
         return
@@ -1568,7 +1706,7 @@ def save_bar_venn(
 @format_docstrings(kwargs=_get_path_and_name_kwargs_doc)
 def save_venn(
         named_sets: Dict[str, set], ex: str, show_suptitle: bool = True,
-        title_font_size=20, set_label_font_size=16, subset_label_font_size=14, **kwargs
+        title_font_size=20, set_label_font_size=16, subset_label_font_size=14, close_plots: str = "all", **kwargs
 ) -> Optional[Tuple[plt.Figure, plt.Axes]]:
     """
     Creates Venn Diagrams from passed data. saves plot with prefix: {{name}}
@@ -1576,21 +1714,25 @@ def save_venn(
     Parameters
     ----------
     named_sets
+        a mapping of samples to protein names
     ex
         title for the plot
     show_suptitle
-        should the title be shown
+        should the figure title be shown
     title_font_size
         font size of the title
     set_label_font_size
         font size of sets
     subset_label_font_size
         font size of subsets
+    close_plots
+        which plots should be closed when creating the plot, if None no plots will be closed
     kwargs
         {kwargs}
 
     """
-    plt.close("all")
+    if close_plots is not None:
+        plt.close(close_plots)
     fig, ax = plt.subplots(1, 1, figsize=(14, 7))
     if show_suptitle:
         plt.title(ex.replace("_", " "), fontsize=title_font_size, weight="bold")
diff --git a/mspypeline_public_dataset b/mspypeline_public_dataset
new file mode 160000
index 0000000..14cbaa5
--- /dev/null
+++ b/mspypeline_public_dataset
@@ -0,0 +1,1 @@
+Subproject commit 14cbaa5e76c3eadf6d6b7a990c36307badcd7abd
diff --git a/setup.py b/setup.py
index 36a32e9..5493bba 100644
--- a/setup.py
+++ b/setup.py
@@ -30,7 +30,6 @@
         "matplotlib-venn>=0.11.5",
         "adjusttext>=0.7.3",
         "scikit-learn>=0.22.1",
-        "plotly>=4.6.0",
     ],
     project_urls={
         "Documentation": "https://mspypeline.readthedocs.io/en/stable/",


Test patch:
diff --git a/test/conftest.py b/test/conftest.py
index de1870e..8c342ef 100644
--- a/test/conftest.py
+++ b/test/conftest.py
@@ -29,4 +29,4 @@ def pytest_collection_modifyitems(config, items):
     skip_release = pytest.mark.skip(reason="need --release option to run")
     for item in items:
         if "release" in item.keywords and not config.getoption("--runrelease"):
-            item.add_marker(skip_release)
\ No newline at end of file
+            item.add_marker(skip_release)
diff --git a/test/mock_data.py b/test/mock_data.py
index 0c9b987..82ed83c 100644
--- a/test/mock_data.py
+++ b/test/mock_data.py
@@ -14,7 +14,7 @@ class MockData:
 
     @staticmethod
     def create_mock_data(
-            test_cases = (0, 1, 10, 20, 50, 100, 250, 500),
+            test_cases = (0, 10, 20, 50, 100),
             number_of_non_pathway_genes = 1000,
             average = 28,
             gene_sigma = 2,
diff --git a/test/test_imports.py b/test/test_imports.py
index 9b579b0..c578ad7 100644
--- a/test/test_imports.py
+++ b/test/test_imports.py
@@ -39,13 +39,11 @@ def test_import():
     assert inspect.isfunction(get_analysis_design)
     assert inspect.isfunction(fill_dict)
     # test plotting backends
-    from mspypeline import matplotlib_plots, plotly_plots
+    from mspypeline import matplotlib_plots
     assert inspect.ismodule(matplotlib_plots)
-    assert inspect.ismodule(plotly_plots)
 
 
 def test_config_available():
     from mspypeline import path_package_config
     import os
     assert os.path.isdir(path_package_config)
-