From 01fc591bc20944e335abeee81c6d7dbcc5fb8688 Mon Sep 17 00:00:00 2001 From: ammarcsj <70114795+ammarcsj@users.noreply.github.com> Date: Mon, 25 May 2026 10:46:34 +0200 Subject: [PATCH] Restore notebook plotting functions removed by dead code cleanup --- alphaquant/plotting/multicond.py | 41 ++++++++++++++++++++++++++++++++ alphaquant/plotting/pairwise.py | 26 ++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/alphaquant/plotting/multicond.py b/alphaquant/plotting/multicond.py index e69de29b..8705c9f4 100644 --- a/alphaquant/plotting/multicond.py +++ b/alphaquant/plotting/multicond.py @@ -0,0 +1,41 @@ +import matplotlib.pyplot as plt +import pandas as pd +import numpy as np + + +def plot_proteoform_intensity_profiles(proteoform_df: pd.DataFrame): + """Creates a panel of proteoform intensity profiles for each protein in the dataframe. + + Args: + proteoform_df: proteoform dataframe loaded from the AlphaQuant output file `medianref_proteoforms.tsv` + + Returns: + fig, axes: matplotlib figure and axes objects + """ + fixed_columns = ['proteoform_id', 'peptides', 'number_of_peptides', 'protein', 'corr_to_ref', 'is_reference'] + conditions = proteoform_df.columns.difference(fixed_columns) + + grouped = proteoform_df.groupby('protein') + n_plots = len(grouped) + + n_cols = int(np.ceil(np.sqrt(n_plots))) + n_rows = int(np.ceil(n_plots / n_cols)) + + fig, axes = plt.subplots(n_rows, n_cols, figsize=(5 * n_cols, 4 * n_rows)) + axes = axes.flatten() + + for ax, (protein, sub_df) in zip(axes, grouped): + for idx, row in sub_df.iterrows(): + style = '-' if row['is_reference'] else '--' + ax.plot(conditions, row[conditions], style, label=row['proteoform_id']) + ax.set_title(f'{protein}') + ax.set_xlabel('Tissue') + ax.set_ylabel('Expression Level') + ax.legend(title='Proteoform ID') + + for i in range(n_plots, len(axes)): + axes[i].axis('off') + + fig.tight_layout() + plt.show() + return fig, axes diff --git a/alphaquant/plotting/pairwise.py b/alphaquant/plotting/pairwise.py index 4fc97817..c56fc66a 100644 --- a/alphaquant/plotting/pairwise.py +++ b/alphaquant/plotting/pairwise.py @@ -11,6 +11,32 @@ LOGGER = logging.getLogger(__name__) +def plot_normalization_overview(normed_df, samplemap_df): + normed_df, sample2cond = aq_diff_utils.prepare_loaded_tables(normed_df, samplemap_df) + sample2cond = dict(zip(samplemap_df["sample"], samplemap_df["condition"])) + conditions = list(set([sample2cond.get(x) for x in normed_df.columns])) + conditions = [x for x in conditions if x is not None] + df_c1 = normed_df[[x for x in normed_df.columns if sample2cond.get(x) == conditions[0]]] + df_c2 = normed_df[[x for x in normed_df.columns if sample2cond.get(x) == conditions[1]]] + + plot_betweencond_fcs(df_c1, df_c2, merge_samples=True) + plot_sample_vs_median_fcs(df_c1, df_c2) + + +def plot_sample_vs_median_fcs(df_c1_normed, df_c2_normed): + combined_median = pd.concat([df_c1_normed, df_c2_normed], axis=1).median(axis=1, skipna=True) + fig, axes = plt.subplots() + for df in [df_c1_normed, df_c2_normed]: + for col in df.columns: + diff_fcs = df[col].subtract(combined_median) + axes.axvline(0, color='red', linestyle="dashed") + cutoff = max(abs(np.nanquantile(diff_fcs, 0.025)), abs(np.nanquantile(diff_fcs, 0.975))) + axes.hist(diff_fcs, 80, density=True, histtype='step', range=(-cutoff, cutoff), label=col) + axes.set_xlabel("log2(fc)") + axes.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0.) + return fig, axes + + def plot_withincond_normalization(df_c1, df_c2): LOGGER.info("without missingvals (if applicable)") plot_betweencond_fcs(aqnorm.drop_nas_if_possible(df_c1), aqnorm.drop_nas_if_possible(df_c2), True)