import pandas as pd
import numpy as np
import statsmodels.api as sm
import statsmodels.formula.api as smf
import scipy.stats as stats
from statsmodels.stats.multitest import multipletests
import tqdm
import matplotlib.pyplot as plt
import seaborn as sns
from skimage import filters, morphology, measure, color
from skimage.measure import regionprops
from tifffile import imread, imsave
import glob
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from skimage import measure
from scipy.spatial.distance import pdist
import random
random.seed(42)
plt.rcParams['pdf.fonttype'] = 'truetype'
plt.rcParams['font.size'] = 20
plt.style.use('seaborn-v0_8-ticks')
color_palette = {'DMSO' : '#4d4d4d',
'ARYL_AG':'#F8766D', 'ARYL_INH':"#F8766D50",
'ANDR_AG':'#fccb17', 'ANDR_INH':'#C49A0050',
"ESTR_AG": '#53B400', "ESTR_INH": '#53B40050',
'GC_AG' : '#00C094', 'GC_INH' : '#00C09450',
'LX_AG' : '#00B6EB', 'LX_INH' : '#00B6EB50',
'RET_AG' : '#A58AFF', 'RET_INH' : '#A58AFF50',
'THYR_AG' : '#FB61D7', 'THYR_INH' : '#FB61D750'
}
import matplotlib.colors as mcolors
def hex_to_rgba(hex_color):
"""Convert hex color to RGBA. Supports 8-digit hex with alpha."""
hex_color = hex_color.lstrip('#')
if len(hex_color) == 6:
return mcolors.to_rgba('#' + hex_color)
elif len(hex_color) == 8:
rgb = hex_color[:6]
alpha = int(hex_color[6:], 16) / 255
return (*mcolors.to_rgb('#' + rgb), alpha)
else:
raise ValueError(f"Invalid hex color: #{hex_color}")
def hex_to_rgba_string(hex_color):
"""Convert hex color to rgba() string for Seaborn."""
hex_color = hex_color.lstrip('#')
if len(hex_color) == 6:
r, g, b = tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
return f'rgba({r}, {g}, {b}, 1.0)'
elif len(hex_color) == 8:
r, g, b = tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
a = int(hex_color[6:], 16) / 255
return f'rgba({r}, {g}, {b}, {a:.3f})'
else:
raise ValueError(f"Invalid hex color: #{hex_color}")
# Convert all to RGBA
color_palette_rgba = {k: hex_to_rgba(v) for k, v in color_palette.items()}
color_palette_rgba_str = {k: hex_to_rgba_string(v) for k, v in color_palette.items()}
color_palette_expanded = {'DMSO_CTL08A': '#cacaca',
'DMSO_CTL04E': '#4d4d4d',
'ARYL_AG_CTL08A': '#fdd6d3',
'ARYL_AG_CTL04E': '#F8766D',
'ARYL_INH_CTL08A': '#fdd6d3',
'ARYL_INH_CTL04E': '#F8766D50',
'ANDR_AG_CTL08A': '#feefb9',
'ANDR_AG_CTL04E': '#fccb17',
'ANDR_INH_CTL08A': '#ede1b250',
'ANDR_INH_CTL04E': '#C49A0050',
'ESTR_AG_CTL08A': '#cbe8b2',
'ESTR_AG_CTL04E': '#53B400',
'ESTR_INH_CTL08A': '#cbe8b250',
'ESTR_INH_CTL04E': '#53B40050',
'GC_AG_CTL08A': '#b2ecdf',
'GC_AG_CTL04E': '#00C094',
'GC_INH_CTL08A': '#b2ecdf50',
'GC_INH_CTL04E': '#00C09450',
'LX_AG_CTL08A': '#b2e9f9',
'LX_AG_CTL04E': '#00B6EB',
'LX_INH_CTL08A': '#b2e9f950',
'LX_INH_CTL04E': '#00B6EB50',
'RET_AG_CTL08A': '#e4dcff',
'RET_AG_CTL04E': '#A58AFF',
'RET_INH_CTL08A': '#e4dcff50',
'RET_INH_CTL04E': '#A58AFF50',
'THYR_AG_CTL08A': '#fed0f3',
'THYR_AG_CTL04E': '#FB61D7',
'THYR_INH_CTL08A': '#fed0f350',
'THYR_INH_CTL04E': '#FB61D750'}
line_palette = {
'CTL08A': "#99cfd670", # azzurro pastello
'CTL04E': "#f8c88a70", # arancio pastello
}
labels = list(color_palette.keys())
handles = [plt.Line2D([0], [0], color=color_palette[label], lw=8) for label in labels]
fig, ax = plt.subplots(figsize=(8, 2))
legend = ax.legend(
handles, labels, loc='center', ncol=int(np.ceil(len(labels)/2)), frameon=False,
bbox_to_anchor=(0.5, 0.5)
)
ax.axis('off')
plt.tight_layout()
plt.savefig('../../../../endpoints_figures/color_palette_legend.pdf', dpi=300, bbox_inches='tight')
/tmp/ipykernel_1121090/191618692.py:10: UserWarning: Tight layout not applied. The left and right margins cannot be made large enough to accommodate all axes decorations. plt.tight_layout()
blank_mix1 = glob.glob('/group/testa/Project/EndPoints/TPSSU/analysis/single_tif_scanregion/*0136*.tif')
blank_mix1 = [f.split('/')[-1].split('.')[0] for f in blank_mix1]
blank_mix2 = glob.glob('/group/testa/Project/EndPoints/TPSSU/analysis/single_tif_scanregion/*0145*.tif')
blank_mix2 = [f.split('/')[-1].split('.')[0] for f in blank_mix2]
check_qc_ch1 = pd.read_csv('../../preprocessing/tables/Treshold_QC_check - Channel1_no_dup.csv')
check_qc_ch2 = pd.read_csv('../../preprocessing/tables/Treshold_QC_check - Channel2_no_dup.csv')
check_qc_ch1['general QC (keep or not)'] = check_qc_ch1['general QC (keep or not)'].str.upper()
check_qc_ch1['general QC (keep or not)'] = check_qc_ch1['general QC (keep or not)'].replace({'BETTER NOT': 'LIMIT', 'MAYBE': 'LIMIT', 'YES?': 'LIMIT', 'SUS': 'LIMIT', 'NOT SURE': 'LIMIT', 'YES ': 'YES', 'YES - 2 CBO': 'YES'})
check_qc_ch1['general QC (keep or not)'].value_counts().index
Index(['YES', 'LIMIT', 'NO'], dtype='object', name='general QC (keep or not)')
check_qc_ch1['Reference Image Report'] = check_qc_ch1['Reference Image Report'].str.replace('.pdf', '')
check_qc_ch1['Reference Image Report'].value_counts()
Reference Image Report
20240424_manuel_lessi_0148_ScanRegion1_rep_1_channel_1 1
20240424_manuel_lessi_0145_ScanRegion2_rep_2_channel_1 1
20240424_manuel_lessi_0145_ScanRegion3_rep_0_channel_1 1
20240424_manuel_lessi_0145_ScanRegion3_rep_1_channel_1 1
20240424_manuel_lessi_0145_ScanRegion3_rep_2_channel_1 1
..
20240424_manuel_lessi_0136_ScanRegion2_rep_1_channel_1 1
20240424_manuel_lessi_0136_ScanRegion2_rep_2_channel_1 1
20240424_manuel_lessi_0136_ScanRegion3_rep_0_channel_1 1
20240424_manuel_lessi_0136_ScanRegion3_rep_1_channel_1 1
20240424_manuel_lessi_0136_ScanRegion3_rep_2_channel_1 1
Name: count, Length: 153, dtype: int64
check_qc_ch2['general QC (keep or not)'] = check_qc_ch2['general QC (keep or not)'].str.upper()
check_qc_ch2['general QC (keep or not)'] = check_qc_ch2['general QC (keep or not)'].replace({'NOT SURE': 'LIMIT', '?': 'LIMIT', 'YES ': 'YES'})
check_qc_ch2['general QC (keep or not)'].value_counts().index
Index(['YES', 'NO', 'LIMIT'], dtype='object', name='general QC (keep or not)')
check_qc_ch2['Reference Image Report'] = check_qc_ch2['Reference Image Report'].str.replace('.pdf', '')
check_qc_ch1['Reference Image Report'].value_counts()
Reference Image Report
20240424_manuel_lessi_0148_ScanRegion1_rep_1_channel_1 1
20240424_manuel_lessi_0145_ScanRegion2_rep_2_channel_1 1
20240424_manuel_lessi_0145_ScanRegion3_rep_0_channel_1 1
20240424_manuel_lessi_0145_ScanRegion3_rep_1_channel_1 1
20240424_manuel_lessi_0145_ScanRegion3_rep_2_channel_1 1
..
20240424_manuel_lessi_0136_ScanRegion2_rep_1_channel_1 1
20240424_manuel_lessi_0136_ScanRegion2_rep_2_channel_1 1
20240424_manuel_lessi_0136_ScanRegion3_rep_0_channel_1 1
20240424_manuel_lessi_0136_ScanRegion3_rep_1_channel_1 1
20240424_manuel_lessi_0136_ScanRegion3_rep_2_channel_1 1
Name: count, Length: 153, dtype: int64
check_qc_ch1['ImageName_ScanRegion_Rep'] = check_qc_ch1['Reference Image Report'].apply(lambda x: '_'.join(x.split('_')[:7]))
check_qc_ch2['ImageName_ScanRegion_Rep'] = check_qc_ch2['Reference Image Report'].apply(lambda x: '_'.join(x.split('_')[:7]))
to_keep_ch1 = check_qc_ch1[check_qc_ch1['general QC (keep or not)'].isin(['YES', 'LIMIT'])]
to_keep_ch2 = check_qc_ch2[check_qc_ch2['general QC (keep or not)'].isin(['YES', 'LIMIT'])]
len(set(to_keep_ch1['ImageName_ScanRegion_Rep']).intersection(set(to_keep_ch2['ImageName_ScanRegion_Rep'])))
100
len(check_qc_ch1['ImageName_ScanRegion_Rep'])
153
len(check_qc_ch2['ImageName_ScanRegion_Rep'])
275
good_tissue_to_keep_limit = list(set(check_qc_ch1[check_qc_ch1['general QC (keep or not)'].isin(['YES', 'LIMIT'])]['ImageName_ScanRegion_Rep']).union(set(check_qc_ch2[check_qc_ch2['general QC (keep or not)'].isin(['YES', 'LIMIT'])]['ImageName_ScanRegion_Rep'])))
len(good_tissue_to_keep_limit)
245
good_tissue_to_keep_yes = list(set(check_qc_ch1[check_qc_ch1['general QC (keep or not)'].isin(['YES'])]['ImageName_ScanRegion_Rep']).union(set(check_qc_ch2[check_qc_ch2['general QC (keep or not)'].isin(['YES'])]['ImageName_ScanRegion_Rep'])))
len(good_tissue_to_keep_yes)
211
sample_sheet = pd.read_csv('../../preprocessing/tables/ImageAnalysisSampleSheet.csv')
sample_sheet
| Path | Scan Area | Condition | Line | OPA | Paraffin Block ID | MIX | |
|---|---|---|---|---|---|---|---|
| 0 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion0 | ESTR_AG | CTL04E | 12 | 29 | 1 |
| 1 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion1 | ESTR_AG | CTL08A | 12 | 30 | 1 |
| 2 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion2 | ESTR_INH | CTL04E | 12 | 31 | 1 |
| 3 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion3 | ANDR_AG | CTL04E | 12 | 33 | 1 |
| 4 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion4 | ESTR_INH | CTL08A | 12 | 32 | 1 |
| 5 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion5 | ANDR_AG | CTL08A | 12 | 34 | 1 |
| 6 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion0 | ANDR_ANT | CTL04E | 13 | 35 | 1 |
| 7 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion1 | ARYL_INH | CTL08A | 13 | 40 | 1 |
| 8 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion2 | ARYL_INH | CTL04E | 13 | 39 | 1 |
| 9 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion3 | ARYL_AG | CTL08A | 13 | 38 | 1 |
| 10 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion4 | ANDR_ANT | CTL08A | 13 | 36 | 1 |
| 11 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion5 | ARYL_AG | CTL04E | 13 | 37 | 1 |
| 12 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion0 | LX_AG | CTL04E | 14 | 41 | 1 |
| 13 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion1 | GC_AG | CTL08A | 14 | 46 | 1 |
| 14 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion2 | LX_AG | CTL08A | 14 | 42 | 1 |
| 15 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion3 | LX_INH | CTL04E | 14 | 43 | 1 |
| 16 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion4 | LX_INH | CTL08A | 14 | 44 | 1 |
| 17 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion0 | GC_INH | CTL04E | 15 | 47 | 1 |
| 18 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion1 | THYR_INH | CTL04E | 15 | 51 | 1 |
| 19 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion2 | THYR_AG | CTL08A | 15 | 50 | 1 |
| 20 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion3 | GC_INH | CTL08A | 15 | 48 | 1 |
| 21 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion4 | THYR_AG | CTL04E | 15 | 49 | 1 |
| 22 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion5 | THYR_INH | CTL08A | 15 | 52 | 1 |
| 23 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion4 | DMSO | CTL04E | 16 | 57 | 1 |
| 24 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion5 | DMSO | CTL08A | 16 | 58 | 1 |
| 25 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion4 | RET_AG | CTL08A | 17 | 64 | 1 |
| 26 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion0 | RET_INH | CTL04E | 18 | 65 | 1 |
| 27 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion2 | RET_INH | CTL08A | 18 | 66 | 1 |
| 28 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion0 | ESTR_AG | CTL04E | 12 | 29 | 2 |
| 29 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion1 | ANDR_AG | CTL08A | 12 | 34 | 2 |
| 30 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion2 | ESTR_AG | CTL08A | 12 | 30 | 2 |
| 31 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion3 | ESTR_INH | CTL04E | 12 | 31 | 2 |
| 32 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion4 | ANDR_AG | CTL04E | 12 | 33 | 2 |
| 33 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion5 | ESTR_INH | CTL08A | 12 | 32 | 2 |
| 34 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion0 | ANDR_INH | CTL08A | 13 | 36 | 2 |
| 35 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion1 | ANDR_INH | CTL04E | 13 | 35 | 2 |
| 36 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion2 | ARYL_INH | CTL04E | 13 | 39 | 2 |
| 37 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion3 | ARYL_AG | CTL08A | 13 | 38 | 2 |
| 38 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion4 | ARYL_INH | CTL08A | 13 | 40 | 2 |
| 39 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion5 | ARYL_AG | CTL04E | 13 | 37 | 2 |
| 40 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion0 | LX_AG | CTL08A | 14 | 42 | 2 |
| 41 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion1 | LX_INH | CTL08A | 14 | 44 | 2 |
| 42 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion2 | LX_AG | CTL04E | 14 | 41 | 2 |
| 43 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion3 | LX_INH | CTL04E | 14 | 43 | 2 |
| 44 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion4 | GC_AG | CTL08A | 14 | 46 | 2 |
| 45 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion0 | GC_INH | CTL08A | 15 | 48 | 2 |
| 46 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion1 | GC_INH | CTL04E | 15 | 47 | 2 |
| 47 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion2 | THYR_INH | CTL04E | 15 | 51 | 2 |
| 48 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion3 | THYR_AG | CTL04E | 15 | 49 | 2 |
| 49 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion4 | THYR_INH | CTL08A | 15 | 52 | 2 |
| 50 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion5 | THYR_AG | CTL08A | 15 | 50 | 2 |
| 51 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion2 | DMSO | CTL08A | 16 | 58 | 2 |
| 52 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion3 | DMSO | CTL04E | 16 | 57 | 2 |
| 53 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion2 | RET_AG | CTL08A | 17 | 64 | 2 |
| 54 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion0 | RET_INH | CTL08A | 18 | 66 | 2 |
| 55 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion1 | RET_INH | CTL04E | 18 | 65 | 2 |
sample_sheet['ImageName'] = sample_sheet['Path'].apply(lambda x: x.split('\\')[-1].split('.')[0])
sample_sheet['ImageName_ScanRegion'] = sample_sheet['ImageName'] + '_' + sample_sheet['Scan Area']
sample_sheet['Condition_Line'] = sample_sheet['Condition'] + '_' + sample_sheet['Line ']
sample_sheet
| Path | Scan Area | Condition | Line | OPA | Paraffin Block ID | MIX | ImageName | ImageName_ScanRegion | Condition_Line | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion0 | ESTR_AG | CTL04E | 12 | 29 | 1 | 20240424_manuel_lessi_0128 | 20240424_manuel_lessi_0128_ScanRegion0 | ESTR_AG_CTL04E |
| 1 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion1 | ESTR_AG | CTL08A | 12 | 30 | 1 | 20240424_manuel_lessi_0128 | 20240424_manuel_lessi_0128_ScanRegion1 | ESTR_AG_CTL08A |
| 2 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion2 | ESTR_INH | CTL04E | 12 | 31 | 1 | 20240424_manuel_lessi_0128 | 20240424_manuel_lessi_0128_ScanRegion2 | ESTR_INH_CTL04E |
| 3 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion3 | ANDR_AG | CTL04E | 12 | 33 | 1 | 20240424_manuel_lessi_0128 | 20240424_manuel_lessi_0128_ScanRegion3 | ANDR_AG_CTL04E |
| 4 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion4 | ESTR_INH | CTL08A | 12 | 32 | 1 | 20240424_manuel_lessi_0128 | 20240424_manuel_lessi_0128_ScanRegion4 | ESTR_INH_CTL08A |
| 5 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion5 | ANDR_AG | CTL08A | 12 | 34 | 1 | 20240424_manuel_lessi_0128 | 20240424_manuel_lessi_0128_ScanRegion5 | ANDR_AG_CTL08A |
| 6 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion0 | ANDR_ANT | CTL04E | 13 | 35 | 1 | 20240424_manuel_lessi_0129 | 20240424_manuel_lessi_0129_ScanRegion0 | ANDR_ANT_CTL04E |
| 7 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion1 | ARYL_INH | CTL08A | 13 | 40 | 1 | 20240424_manuel_lessi_0129 | 20240424_manuel_lessi_0129_ScanRegion1 | ARYL_INH_CTL08A |
| 8 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion2 | ARYL_INH | CTL04E | 13 | 39 | 1 | 20240424_manuel_lessi_0129 | 20240424_manuel_lessi_0129_ScanRegion2 | ARYL_INH_CTL04E |
| 9 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion3 | ARYL_AG | CTL08A | 13 | 38 | 1 | 20240424_manuel_lessi_0129 | 20240424_manuel_lessi_0129_ScanRegion3 | ARYL_AG_CTL08A |
| 10 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion4 | ANDR_ANT | CTL08A | 13 | 36 | 1 | 20240424_manuel_lessi_0129 | 20240424_manuel_lessi_0129_ScanRegion4 | ANDR_ANT_CTL08A |
| 11 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion5 | ARYL_AG | CTL04E | 13 | 37 | 1 | 20240424_manuel_lessi_0129 | 20240424_manuel_lessi_0129_ScanRegion5 | ARYL_AG_CTL04E |
| 12 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion0 | LX_AG | CTL04E | 14 | 41 | 1 | 20240424_manuel_lessi_0130 | 20240424_manuel_lessi_0130_ScanRegion0 | LX_AG_CTL04E |
| 13 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion1 | GC_AG | CTL08A | 14 | 46 | 1 | 20240424_manuel_lessi_0130 | 20240424_manuel_lessi_0130_ScanRegion1 | GC_AG_CTL08A |
| 14 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion2 | LX_AG | CTL08A | 14 | 42 | 1 | 20240424_manuel_lessi_0130 | 20240424_manuel_lessi_0130_ScanRegion2 | LX_AG_CTL08A |
| 15 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion3 | LX_INH | CTL04E | 14 | 43 | 1 | 20240424_manuel_lessi_0130 | 20240424_manuel_lessi_0130_ScanRegion3 | LX_INH_CTL04E |
| 16 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion4 | LX_INH | CTL08A | 14 | 44 | 1 | 20240424_manuel_lessi_0130 | 20240424_manuel_lessi_0130_ScanRegion4 | LX_INH_CTL08A |
| 17 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion0 | GC_INH | CTL04E | 15 | 47 | 1 | 20240424_manuel_lessi_0131 | 20240424_manuel_lessi_0131_ScanRegion0 | GC_INH_CTL04E |
| 18 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion1 | THYR_INH | CTL04E | 15 | 51 | 1 | 20240424_manuel_lessi_0131 | 20240424_manuel_lessi_0131_ScanRegion1 | THYR_INH_CTL04E |
| 19 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion2 | THYR_AG | CTL08A | 15 | 50 | 1 | 20240424_manuel_lessi_0131 | 20240424_manuel_lessi_0131_ScanRegion2 | THYR_AG_CTL08A |
| 20 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion3 | GC_INH | CTL08A | 15 | 48 | 1 | 20240424_manuel_lessi_0131 | 20240424_manuel_lessi_0131_ScanRegion3 | GC_INH_CTL08A |
| 21 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion4 | THYR_AG | CTL04E | 15 | 49 | 1 | 20240424_manuel_lessi_0131 | 20240424_manuel_lessi_0131_ScanRegion4 | THYR_AG_CTL04E |
| 22 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion5 | THYR_INH | CTL08A | 15 | 52 | 1 | 20240424_manuel_lessi_0131 | 20240424_manuel_lessi_0131_ScanRegion5 | THYR_INH_CTL08A |
| 23 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion4 | DMSO | CTL04E | 16 | 57 | 1 | 20240424_manuel_lessi_0132 | 20240424_manuel_lessi_0132_ScanRegion4 | DMSO_CTL04E |
| 24 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion5 | DMSO | CTL08A | 16 | 58 | 1 | 20240424_manuel_lessi_0132 | 20240424_manuel_lessi_0132_ScanRegion5 | DMSO_CTL08A |
| 25 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion4 | RET_AG | CTL08A | 17 | 64 | 1 | 20240424_manuel_lessi_0133 | 20240424_manuel_lessi_0133_ScanRegion4 | RET_AG_CTL08A |
| 26 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion0 | RET_INH | CTL04E | 18 | 65 | 1 | 20240424_manuel_lessi_0134 | 20240424_manuel_lessi_0134_ScanRegion0 | RET_INH_CTL04E |
| 27 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion2 | RET_INH | CTL08A | 18 | 66 | 1 | 20240424_manuel_lessi_0134 | 20240424_manuel_lessi_0134_ScanRegion2 | RET_INH_CTL08A |
| 28 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion0 | ESTR_AG | CTL04E | 12 | 29 | 2 | 20240424_manuel_lessi_0137 | 20240424_manuel_lessi_0137_ScanRegion0 | ESTR_AG_CTL04E |
| 29 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion1 | ANDR_AG | CTL08A | 12 | 34 | 2 | 20240424_manuel_lessi_0137 | 20240424_manuel_lessi_0137_ScanRegion1 | ANDR_AG_CTL08A |
| 30 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion2 | ESTR_AG | CTL08A | 12 | 30 | 2 | 20240424_manuel_lessi_0137 | 20240424_manuel_lessi_0137_ScanRegion2 | ESTR_AG_CTL08A |
| 31 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion3 | ESTR_INH | CTL04E | 12 | 31 | 2 | 20240424_manuel_lessi_0137 | 20240424_manuel_lessi_0137_ScanRegion3 | ESTR_INH_CTL04E |
| 32 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion4 | ANDR_AG | CTL04E | 12 | 33 | 2 | 20240424_manuel_lessi_0137 | 20240424_manuel_lessi_0137_ScanRegion4 | ANDR_AG_CTL04E |
| 33 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion5 | ESTR_INH | CTL08A | 12 | 32 | 2 | 20240424_manuel_lessi_0137 | 20240424_manuel_lessi_0137_ScanRegion5 | ESTR_INH_CTL08A |
| 34 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion0 | ANDR_INH | CTL08A | 13 | 36 | 2 | 20240424_manuel_lessi_0138 | 20240424_manuel_lessi_0138_ScanRegion0 | ANDR_INH_CTL08A |
| 35 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion1 | ANDR_INH | CTL04E | 13 | 35 | 2 | 20240424_manuel_lessi_0138 | 20240424_manuel_lessi_0138_ScanRegion1 | ANDR_INH_CTL04E |
| 36 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion2 | ARYL_INH | CTL04E | 13 | 39 | 2 | 20240424_manuel_lessi_0138 | 20240424_manuel_lessi_0138_ScanRegion2 | ARYL_INH_CTL04E |
| 37 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion3 | ARYL_AG | CTL08A | 13 | 38 | 2 | 20240424_manuel_lessi_0138 | 20240424_manuel_lessi_0138_ScanRegion3 | ARYL_AG_CTL08A |
| 38 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion4 | ARYL_INH | CTL08A | 13 | 40 | 2 | 20240424_manuel_lessi_0138 | 20240424_manuel_lessi_0138_ScanRegion4 | ARYL_INH_CTL08A |
| 39 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion5 | ARYL_AG | CTL04E | 13 | 37 | 2 | 20240424_manuel_lessi_0138 | 20240424_manuel_lessi_0138_ScanRegion5 | ARYL_AG_CTL04E |
| 40 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion0 | LX_AG | CTL08A | 14 | 42 | 2 | 20240424_manuel_lessi_0139 | 20240424_manuel_lessi_0139_ScanRegion0 | LX_AG_CTL08A |
| 41 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion1 | LX_INH | CTL08A | 14 | 44 | 2 | 20240424_manuel_lessi_0139 | 20240424_manuel_lessi_0139_ScanRegion1 | LX_INH_CTL08A |
| 42 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion2 | LX_AG | CTL04E | 14 | 41 | 2 | 20240424_manuel_lessi_0139 | 20240424_manuel_lessi_0139_ScanRegion2 | LX_AG_CTL04E |
| 43 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion3 | LX_INH | CTL04E | 14 | 43 | 2 | 20240424_manuel_lessi_0139 | 20240424_manuel_lessi_0139_ScanRegion3 | LX_INH_CTL04E |
| 44 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion4 | GC_AG | CTL08A | 14 | 46 | 2 | 20240424_manuel_lessi_0139 | 20240424_manuel_lessi_0139_ScanRegion4 | GC_AG_CTL08A |
| 45 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion0 | GC_INH | CTL08A | 15 | 48 | 2 | 20240424_manuel_lessi_0140 | 20240424_manuel_lessi_0140_ScanRegion0 | GC_INH_CTL08A |
| 46 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion1 | GC_INH | CTL04E | 15 | 47 | 2 | 20240424_manuel_lessi_0140 | 20240424_manuel_lessi_0140_ScanRegion1 | GC_INH_CTL04E |
| 47 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion2 | THYR_INH | CTL04E | 15 | 51 | 2 | 20240424_manuel_lessi_0140 | 20240424_manuel_lessi_0140_ScanRegion2 | THYR_INH_CTL04E |
| 48 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion3 | THYR_AG | CTL04E | 15 | 49 | 2 | 20240424_manuel_lessi_0140 | 20240424_manuel_lessi_0140_ScanRegion3 | THYR_AG_CTL04E |
| 49 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion4 | THYR_INH | CTL08A | 15 | 52 | 2 | 20240424_manuel_lessi_0140 | 20240424_manuel_lessi_0140_ScanRegion4 | THYR_INH_CTL08A |
| 50 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion5 | THYR_AG | CTL08A | 15 | 50 | 2 | 20240424_manuel_lessi_0140 | 20240424_manuel_lessi_0140_ScanRegion5 | THYR_AG_CTL08A |
| 51 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion2 | DMSO | CTL08A | 16 | 58 | 2 | 20240424_manuel_lessi_0141 | 20240424_manuel_lessi_0141_ScanRegion2 | DMSO_CTL08A |
| 52 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion3 | DMSO | CTL04E | 16 | 57 | 2 | 20240424_manuel_lessi_0141 | 20240424_manuel_lessi_0141_ScanRegion3 | DMSO_CTL04E |
| 53 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion2 | RET_AG | CTL08A | 17 | 64 | 2 | 20240424_manuel_lessi_0142 | 20240424_manuel_lessi_0142_ScanRegion2 | RET_AG_CTL08A |
| 54 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion0 | RET_INH | CTL08A | 18 | 66 | 2 | 20240424_manuel_lessi_0143 | 20240424_manuel_lessi_0143_ScanRegion0 | RET_INH_CTL08A |
| 55 | T:\Project\EndPoints\TPSSU\Pictures\20240424_m... | ScanRegion1 | RET_INH | CTL04E | 18 | 65 | 2 | 20240424_manuel_lessi_0143 | 20240424_manuel_lessi_0143_ScanRegion1 | RET_INH_CTL04E |
sample_dict= {i:j for i, j in zip(sample_sheet['ImageName_ScanRegion'], sample_sheet['Condition_Line'])}
mix_1_names = sample_sheet[sample_sheet['MIX'] == 1]['ImageName'].tolist()
mix_2_names = sample_sheet[sample_sheet['MIX'] == 2]['ImageName'].tolist()
hormonal_conditions = ['ESTR_AG', 'ESTR_INH', 'ANDR_AG', 'ANDR_INH', 'ARYL_INH',
'ARYL_AG', 'LX_AG', 'GC_AG', 'LX_INH', 'GC_INH', 'THYR_INH',
'THYR_AG', 'DMSO', 'RET_AG',
'RET_INH']
hormonal_conditions.remove('DMSO')
hormonal_conditions.sort()
hormonal_conditions = ['DMSO'] + hormonal_conditions
measurements_files = glob.glob("/group/testa/Project/EndPoints/TPSSU/analysis/measurements/*.csv")
measurements_files_mix_1 = [f for f in measurements_files if any(name in f for name in mix_1_names)]
measurements_files_mix_2 = [f for f in measurements_files if any(name in f for name in mix_2_names)]
mask_file = pd.read_csv("/group/testa/Project/EndPoints/TPSSU/analysis/cyto_mask_measures.csv")
mask_file
| Unnamed: 0 | area | label | intensity_mean | intensity_min | intensity_max | |
|---|---|---|---|---|---|---|
| 0 | 20240424_manuel_lessi_0133_ScanRegion4_rep_0_c... | 2415914.0 | 1.0 | 8478.139486 | 5323.0 | 45060.0 |
| 1 | 20240424_manuel_lessi_0143_ScanRegion0_rep_1_c... | 10287703.0 | 1.0 | 9564.326972 | 6720.0 | 42038.0 |
| 2 | 20240424_manuel_lessi_0133_ScanRegion2_rep_1_c... | 3015477.0 | 1.0 | 11510.699631 | 5536.0 | 49132.0 |
| 3 | 20240424_manuel_lessi_0128_ScanRegion4_rep_1_c... | 6843311.0 | 1.0 | 6301.567833 | 4239.0 | 34600.0 |
| 4 | 20240424_manuel_lessi_0141_ScanRegion0_rep_2_c... | 23305924.0 | 1.0 | 5729.083352 | 3988.0 | 24114.0 |
| ... | ... | ... | ... | ... | ... | ... |
| 278 | 20240424_manuel_lessi_0145_ScanRegion2_rep_1_c... | 35809244.0 | 1.0 | 367.353397 | 340.0 | 2983.0 |
| 279 | 20240424_manuel_lessi_0134_ScanRegion6_rep_1_c... | NaN | NaN | NaN | NaN | NaN |
| 280 | 20240424_manuel_lessi_0144_ScanRegion2_rep_1_c... | 6015146.0 | 1.0 | 7573.352427 | 4627.0 | 44177.0 |
| 281 | 20240424_manuel_lessi_0129_ScanRegion5_rep_1_c... | 23404593.0 | 1.0 | 7714.037972 | 4597.0 | 65534.0 |
| 282 | 20240424_manuel_lessi_0145_ScanRegion0_rep_1_c... | 10141827.0 | 1.0 | 388.299189 | 360.0 | 10460.0 |
283 rows × 6 columns
mask_file['OriginalImageName'] = mask_file['Unnamed: 0'].apply(lambda x: '_'.join(x.split('_')[0:4]))
mask_file['ImageName_ScanRegion'] = mask_file['Unnamed: 0'].apply(lambda x: '_'.join(x.split('_')[0:5]))
mask_file['ImageName_ScanRegion_Rep'] = mask_file['Unnamed: 0'].apply(lambda x: '_'.join(x.split('_')[0:7]))
mask_file
| Unnamed: 0 | area | label | intensity_mean | intensity_min | intensity_max | OriginalImageName | ImageName_ScanRegion | ImageName_ScanRegion_Rep | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 20240424_manuel_lessi_0133_ScanRegion4_rep_0_c... | 2415914.0 | 1.0 | 8478.139486 | 5323.0 | 45060.0 | 20240424_manuel_lessi_0133 | 20240424_manuel_lessi_0133_ScanRegion4 | 20240424_manuel_lessi_0133_ScanRegion4_rep_0 |
| 1 | 20240424_manuel_lessi_0143_ScanRegion0_rep_1_c... | 10287703.0 | 1.0 | 9564.326972 | 6720.0 | 42038.0 | 20240424_manuel_lessi_0143 | 20240424_manuel_lessi_0143_ScanRegion0 | 20240424_manuel_lessi_0143_ScanRegion0_rep_1 |
| 2 | 20240424_manuel_lessi_0133_ScanRegion2_rep_1_c... | 3015477.0 | 1.0 | 11510.699631 | 5536.0 | 49132.0 | 20240424_manuel_lessi_0133 | 20240424_manuel_lessi_0133_ScanRegion2 | 20240424_manuel_lessi_0133_ScanRegion2_rep_1 |
| 3 | 20240424_manuel_lessi_0128_ScanRegion4_rep_1_c... | 6843311.0 | 1.0 | 6301.567833 | 4239.0 | 34600.0 | 20240424_manuel_lessi_0128 | 20240424_manuel_lessi_0128_ScanRegion4 | 20240424_manuel_lessi_0128_ScanRegion4_rep_1 |
| 4 | 20240424_manuel_lessi_0141_ScanRegion0_rep_2_c... | 23305924.0 | 1.0 | 5729.083352 | 3988.0 | 24114.0 | 20240424_manuel_lessi_0141 | 20240424_manuel_lessi_0141_ScanRegion0 | 20240424_manuel_lessi_0141_ScanRegion0_rep_2 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 278 | 20240424_manuel_lessi_0145_ScanRegion2_rep_1_c... | 35809244.0 | 1.0 | 367.353397 | 340.0 | 2983.0 | 20240424_manuel_lessi_0145 | 20240424_manuel_lessi_0145_ScanRegion2 | 20240424_manuel_lessi_0145_ScanRegion2_rep_1 |
| 279 | 20240424_manuel_lessi_0134_ScanRegion6_rep_1_c... | NaN | NaN | NaN | NaN | NaN | 20240424_manuel_lessi_0134 | 20240424_manuel_lessi_0134_ScanRegion6 | 20240424_manuel_lessi_0134_ScanRegion6_rep_1 |
| 280 | 20240424_manuel_lessi_0144_ScanRegion2_rep_1_c... | 6015146.0 | 1.0 | 7573.352427 | 4627.0 | 44177.0 | 20240424_manuel_lessi_0144 | 20240424_manuel_lessi_0144_ScanRegion2 | 20240424_manuel_lessi_0144_ScanRegion2_rep_1 |
| 281 | 20240424_manuel_lessi_0129_ScanRegion5_rep_1_c... | 23404593.0 | 1.0 | 7714.037972 | 4597.0 | 65534.0 | 20240424_manuel_lessi_0129 | 20240424_manuel_lessi_0129_ScanRegion5 | 20240424_manuel_lessi_0129_ScanRegion5_rep_1 |
| 282 | 20240424_manuel_lessi_0145_ScanRegion0_rep_1_c... | 10141827.0 | 1.0 | 388.299189 | 360.0 | 10460.0 | 20240424_manuel_lessi_0145 | 20240424_manuel_lessi_0145_ScanRegion0 | 20240424_manuel_lessi_0145_ScanRegion0_rep_1 |
283 rows × 9 columns
mask_file_df_mix_1 = mask_file[mask_file.OriginalImageName.isin(mix_1_names)]
mask_file_df_mix_1
| Unnamed: 0 | area | label | intensity_mean | intensity_min | intensity_max | OriginalImageName | ImageName_ScanRegion | ImageName_ScanRegion_Rep | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 20240424_manuel_lessi_0133_ScanRegion4_rep_0_c... | 2415914.0 | 1.0 | 8478.139486 | 5323.0 | 45060.0 | 20240424_manuel_lessi_0133 | 20240424_manuel_lessi_0133_ScanRegion4 | 20240424_manuel_lessi_0133_ScanRegion4_rep_0 |
| 2 | 20240424_manuel_lessi_0133_ScanRegion2_rep_1_c... | 3015477.0 | 1.0 | 11510.699631 | 5536.0 | 49132.0 | 20240424_manuel_lessi_0133 | 20240424_manuel_lessi_0133_ScanRegion2 | 20240424_manuel_lessi_0133_ScanRegion2_rep_1 |
| 3 | 20240424_manuel_lessi_0128_ScanRegion4_rep_1_c... | 6843311.0 | 1.0 | 6301.567833 | 4239.0 | 34600.0 | 20240424_manuel_lessi_0128 | 20240424_manuel_lessi_0128_ScanRegion4 | 20240424_manuel_lessi_0128_ScanRegion4_rep_1 |
| 9 | 20240424_manuel_lessi_0134_ScanRegion6_rep_0_c... | 7147296.0 | 1.0 | 5035.728892 | 2796.0 | 20250.0 | 20240424_manuel_lessi_0134 | 20240424_manuel_lessi_0134_ScanRegion6 | 20240424_manuel_lessi_0134_ScanRegion6_rep_0 |
| 12 | 20240424_manuel_lessi_0130_ScanRegion2_rep_1_c... | 5736151.0 | 1.0 | 3811.331029 | 2366.0 | 59754.0 | 20240424_manuel_lessi_0130 | 20240424_manuel_lessi_0130_ScanRegion2 | 20240424_manuel_lessi_0130_ScanRegion2_rep_1 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 272 | 20240424_manuel_lessi_0131_ScanRegion2_rep_1_c... | 619563.0 | 1.0 | 7816.673183 | 4931.0 | 56017.0 | 20240424_manuel_lessi_0131 | 20240424_manuel_lessi_0131_ScanRegion2 | 20240424_manuel_lessi_0131_ScanRegion2_rep_1 |
| 274 | 20240424_manuel_lessi_0129_ScanRegion5_rep_2_c... | 15482008.0 | 1.0 | 5670.165540 | 3481.0 | 56907.0 | 20240424_manuel_lessi_0129 | 20240424_manuel_lessi_0129_ScanRegion5 | 20240424_manuel_lessi_0129_ScanRegion5_rep_2 |
| 277 | 20240424_manuel_lessi_0133_ScanRegion0_rep_2_c... | 10075425.0 | 1.0 | 4029.633461 | 2629.0 | 41430.0 | 20240424_manuel_lessi_0133 | 20240424_manuel_lessi_0133_ScanRegion0 | 20240424_manuel_lessi_0133_ScanRegion0_rep_2 |
| 279 | 20240424_manuel_lessi_0134_ScanRegion6_rep_1_c... | NaN | NaN | NaN | NaN | NaN | 20240424_manuel_lessi_0134 | 20240424_manuel_lessi_0134_ScanRegion6 | 20240424_manuel_lessi_0134_ScanRegion6_rep_1 |
| 281 | 20240424_manuel_lessi_0129_ScanRegion5_rep_1_c... | 23404593.0 | 1.0 | 7714.037972 | 4597.0 | 65534.0 | 20240424_manuel_lessi_0129 | 20240424_manuel_lessi_0129_ScanRegion5 | 20240424_manuel_lessi_0129_ScanRegion5_rep_1 |
116 rows × 9 columns
mask_file_df_mix_2 = mask_file[mask_file.OriginalImageName.isin(mix_2_names)]
mask_file_df_mix_2
| Unnamed: 0 | area | label | intensity_mean | intensity_min | intensity_max | OriginalImageName | ImageName_ScanRegion | ImageName_ScanRegion_Rep | |
|---|---|---|---|---|---|---|---|---|---|
| 1 | 20240424_manuel_lessi_0143_ScanRegion0_rep_1_c... | 10287703.0 | 1.0 | 9564.326972 | 6720.0 | 42038.0 | 20240424_manuel_lessi_0143 | 20240424_manuel_lessi_0143_ScanRegion0 | 20240424_manuel_lessi_0143_ScanRegion0_rep_1 |
| 4 | 20240424_manuel_lessi_0141_ScanRegion0_rep_2_c... | 23305924.0 | 1.0 | 5729.083352 | 3988.0 | 24114.0 | 20240424_manuel_lessi_0141 | 20240424_manuel_lessi_0141_ScanRegion0 | 20240424_manuel_lessi_0141_ScanRegion0_rep_2 |
| 5 | 20240424_manuel_lessi_0138_ScanRegion3_rep_1_c... | 6139706.0 | 1.0 | 10728.699008 | 7679.0 | 47373.0 | 20240424_manuel_lessi_0138 | 20240424_manuel_lessi_0138_ScanRegion3 | 20240424_manuel_lessi_0138_ScanRegion3_rep_1 |
| 6 | 20240424_manuel_lessi_0140_ScanRegion2_rep_0_c... | 2887437.0 | 1.0 | 10582.573429 | 8073.0 | 32277.0 | 20240424_manuel_lessi_0140 | 20240424_manuel_lessi_0140_ScanRegion2 | 20240424_manuel_lessi_0140_ScanRegion2_rep_0 |
| 10 | 20240424_manuel_lessi_0142_ScanRegion3_rep_0_c... | 18501332.0 | 1.0 | 8751.319145 | 6006.0 | 40819.0 | 20240424_manuel_lessi_0142 | 20240424_manuel_lessi_0142_ScanRegion3 | 20240424_manuel_lessi_0142_ScanRegion3_rep_0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 266 | 20240424_manuel_lessi_0139_ScanRegion0_rep_2_c... | 16192847.0 | 1.0 | 12416.619954 | 8449.0 | 52637.0 | 20240424_manuel_lessi_0139 | 20240424_manuel_lessi_0139_ScanRegion0 | 20240424_manuel_lessi_0139_ScanRegion0_rep_2 |
| 268 | 20240424_manuel_lessi_0140_ScanRegion4_rep_1_c... | 10125138.0 | 1.0 | 6630.255008 | 3940.0 | 59013.0 | 20240424_manuel_lessi_0140 | 20240424_manuel_lessi_0140_ScanRegion4 | 20240424_manuel_lessi_0140_ScanRegion4_rep_1 |
| 271 | 20240424_manuel_lessi_0137_ScanRegion4_rep_1_c... | 10843902.0 | 1.0 | 6203.065238 | 4195.0 | 41839.0 | 20240424_manuel_lessi_0137 | 20240424_manuel_lessi_0137_ScanRegion4 | 20240424_manuel_lessi_0137_ScanRegion4_rep_1 |
| 273 | 20240424_manuel_lessi_0142_ScanRegion2_rep_1_c... | 2596930.0 | 1.0 | 4422.110883 | 3233.0 | 18355.0 | 20240424_manuel_lessi_0142 | 20240424_manuel_lessi_0142_ScanRegion2 | 20240424_manuel_lessi_0142_ScanRegion2_rep_1 |
| 276 | 20240424_manuel_lessi_0141_ScanRegion4_rep_1_c... | 26594153.0 | 1.0 | 6924.010593 | 4440.0 | 41733.0 | 20240424_manuel_lessi_0141 | 20240424_manuel_lessi_0141_ScanRegion4 | 20240424_manuel_lessi_0141_ScanRegion4_rep_1 |
109 rows × 9 columns
def filter_nuclei(df):
min_quantile = df['area'].quantile(0.01)
max_quantile = df['area'].quantile(0.99)
df = df[(df['area'] > min_quantile) & (df['area'] < max_quantile)]
return df
tot_df_mix1_ch1 = pd.read_csv("/group/testa/Project/EndPoints/TPSSU/analysis/measurements_mix_1_ch1_CTIP2.csv")
tot_df_mix2_ch1 = pd.read_csv("/group/testa/Project/EndPoints/TPSSU/analysis/measurements_mix_2_ch1_NeuN.csv")
morphological_features = ['area', 'eccentricity', 'equivalent_diameter', 'extent',
'major_axis_length', 'minor_axis_length', 'orientation', 'perimeter',
'solidity']
tot_df_mix1_ch1['ImageName_ScanRegion_Rep'] = tot_df_mix1_ch1['ImageName'].apply(lambda x: '_'.join(x.split('_')[0:7]))
print(tot_df_mix1_ch1.shape)
tot_df_mix1_ch1 = tot_df_mix1_ch1.groupby('ImageName_ScanRegion_Rep').apply(filter_nuclei).reset_index(drop=True)
print(tot_df_mix1_ch1.shape)
tot_df_mix1_ch1['label_image'] = tot_df_mix1_ch1['label'].astype('str') + '_' + tot_df_mix1_ch1['ImageName_ScanRegion_Rep'].astype('str')
tot_df_mix1_ch1.set_index('label_image', inplace = True)
(4591259, 21)
/tmp/ipykernel_1121090/3325876105.py:11: DeprecationWarning: DataFrameGroupBy.apply operated on the grouping columns. This behavior is deprecated, and in a future version of pandas the grouping columns will be excluded from the operation. Either pass `include_groups=False` to exclude the groupings or explicitly select the grouping columns after groupby to silence this warning.
tot_df_mix1_ch1 = tot_df_mix1_ch1.groupby('ImageName_ScanRegion_Rep').apply(filter_nuclei).reset_index(drop=True)
(4496846, 21)
tot_df_mix1_ch1 = tot_df_mix1_ch1[morphological_features]
tot_df_mix2_ch1['ImageName_ScanRegion_Rep'] = tot_df_mix2_ch1['ImageName'].apply(lambda x: '_'.join(x.split('_')[0:7]))
print(tot_df_mix2_ch1.shape)
tot_df_mix2_ch1 = tot_df_mix2_ch1.groupby('ImageName_ScanRegion_Rep').apply(filter_nuclei).reset_index(drop=True)
print(tot_df_mix2_ch1.shape)
tot_df_mix2_ch1['label_image'] = tot_df_mix2_ch1['label'].astype('str') + '_' + tot_df_mix2_ch1['ImageName_ScanRegion_Rep'].astype('str')
tot_df_mix2_ch1.set_index('label_image', inplace = True)
(4788573, 21)
/tmp/ipykernel_1121090/531573534.py:4: DeprecationWarning: DataFrameGroupBy.apply operated on the grouping columns. This behavior is deprecated, and in a future version of pandas the grouping columns will be excluded from the operation. Either pass `include_groups=False` to exclude the groupings or explicitly select the grouping columns after groupby to silence this warning.
tot_df_mix2_ch1 = tot_df_mix2_ch1.groupby('ImageName_ScanRegion_Rep').apply(filter_nuclei).reset_index(drop=True)
(4690248, 21)
tot_df_mix2_ch1 = tot_df_mix2_ch1[morphological_features]
tot_df_morphological = pd.concat([tot_df_mix1_ch1, tot_df_mix2_ch1], axis=0)
tot_df_morphological['ImageName_ScanRegion_Rep'] = tot_df_morphological.reset_index()['label_image'].apply(lambda x: '_'.join(x.split('_')[1:8])).values
tot_df_morphological['ImageName_ScanRegion'] = tot_df_morphological.reset_index()['label_image'].apply(lambda x: '_'.join(x.split('_')[1:6])).values
tot_df_morphological['Condition_Line'] = tot_df_morphological['ImageName_ScanRegion'].apply(lambda x: sample_dict.get(x, 'Unknown'))
tot_df_morphological['Condition'] = tot_df_morphological['Condition_Line'].apply(lambda x: x.replace('_CTL04E', '').replace('_CTL08A', ''))
tot_df_morphological['Line'] = tot_df_morphological['Condition_Line'].apply(lambda x: x.split('_')[-1])
tot_df_morphological = tot_df_morphological[tot_df_morphological['Condition'].isin(hormonal_conditions)]
tot_df_morphological = tot_df_morphological[tot_df_morphological['ImageName_ScanRegion_Rep'].isin(good_tissue_to_keep_limit)]
tot_df_morphological = tot_df_morphological[tot_df_morphological["ImageName_ScanRegion_Rep"] != "20240424_manuel_lessi_0134_ScanRegion7_rep_1"] # outlier
tot_df_morphological = tot_df_morphological[tot_df_morphological['Condition'] != 'Unknown'] # filter out unknown conditions
features = tot_df_morphological[morphological_features]
len(tot_df_morphological["ImageName_ScanRegion_Rep"].unique())
139
# Standardize the features
scaler = StandardScaler()
features_scaled = scaler.fit_transform(features)
# Perform PCA
pca = PCA()
principal_components = pca.fit_transform(features_scaled)
# Add the principal components to the dataframe
for i in range(principal_components.shape[1]):
tot_df_morphological[f'PC{i+1}'] = principal_components[:, i]
# Extract the most important features for PCA1 and PCA2
pca_components = pd.DataFrame(pca.components_, columns=features.columns, index=[f'PC{i+1}' for i in range(len(pca.components_))])
important_features_pca1 = pca_components.loc['PC1'].abs().sort_values(ascending=False).head(5)
important_features_pca2 = pca_components.loc['PC2'].abs().sort_values(ascending=False).head(5)
important_features_pca3 = pca_components.loc['PC3'].abs().sort_values(ascending=False).head(5)
print("Top 5 features contributing to PCA1:")
print(important_features_pca1)
print("\nTop 5 features contributing to PCA2:")
print(important_features_pca2)
print("\nTop 5 features contributing to PCA3:")
print(important_features_pca3)
Top 5 features contributing to PCA1: equivalent_diameter 0.451671 perimeter 0.446028 area 0.445225 major_axis_length 0.430577 minor_axis_length 0.424077 Name: PC1, dtype: float64 Top 5 features contributing to PCA2: extent 0.637839 solidity 0.531573 eccentricity 0.499679 major_axis_length 0.179739 minor_axis_length 0.132653 Name: PC2, dtype: float64 Top 5 features contributing to PCA3: orientation 0.999614 solidity 0.023722 eccentricity 0.010693 extent 0.009049 major_axis_length 0.002369 Name: PC3, dtype: float64
grouped_df = tot_df_morphological.groupby('ImageName_ScanRegion_Rep').mean(['PC1', 'PC2']).reset_index()
grouped_df['ImageName_ScanRegion'] = grouped_df['ImageName_ScanRegion_Rep'].apply(lambda x: '_'.join(x.split('_')[0:5])).values
grouped_df['Condition_Line'] = grouped_df['ImageName_ScanRegion'].apply(lambda x: sample_dict.get(x, 'Unknown'))
grouped_df['Condition'] = grouped_df['Condition_Line'].apply(lambda x: x.replace('_CTL04E', '').replace('_CTL08A', ''))
grouped_df['Line'] = grouped_df['Condition_Line'].apply(lambda x: x.split('_')[-1])
cmap_conditions = plt.matplotlib.colors.ListedColormap([color_palette[c] for c in grouped_df['Condition'].astype('category').cat.categories])
plt.scatter(
grouped_df['PC1'], grouped_df['PC2'],
#alpha=0.3,
c=grouped_df['Condition'].astype('category').cat.codes,
cmap=cmap_conditions
)
plt.savefig('../../../../endpoints_figures/endpoints_PCA.pdf', dpi = 300)
plt.scatter(
grouped_df['PC2'], grouped_df['PC3'],
#alpha=0.3,
c=grouped_df['Condition'].astype('category').cat.codes,
cmap=cmap_conditions,
)
plt.savefig('../../../../endpoints_figures/endpoints_PCA_PC2_PC3.pdf', dpi = 300)
fig, ax = plt.subplots(1, 2, figsize=(20, 5))
for i, cond in enumerate(hormonal_conditions):
data = tot_df_morphological[(tot_df_morphological['Line'] == 'CTL08A') &
(tot_df_morphological['Condition'] == cond)]['PC1']
box = ax[0].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = tot_df_morphological[(tot_df_morphological['Condition'] == 'DMSO') &
(tot_df_morphological['Line'] == 'CTL08A')]['PC1'].median()
ax[0].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
for i, cond in enumerate(hormonal_conditions):
data = tot_df_morphological[(tot_df_morphological['Line'] == 'CTL04E') &
(tot_df_morphological['Condition'] == cond)]['PC1']
box = ax[1].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = tot_df_morphological[(tot_df_morphological['Condition'] == 'DMSO') &
(tot_df_morphological['Line'] == 'CTL04E')]['PC1'].median()
ax[1].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
_ = ax[0].set_xticks(range(len(hormonal_conditions)))
_ = ax[0].set_xticklabels(hormonal_conditions, rotation=90)
_ = ax[1].set_xticks(range(len(hormonal_conditions)))
_ = ax[1].set_xticklabels(hormonal_conditions, rotation=90)
ax[0].set_title('CTL08A')
ax[1].set_title('CTL04E')
ax[0].set_ylabel('PC1')
ax[1].set_ylabel('PC1')
plt.savefig('../../../../endpoints_figures/endpoints_PC1_all_nuclei.pdf', dpi=300, bbox_inches='tight')
plt.savefig('../../../../endpoints_figures/endpoints_PC1_all_nuclei.png', dpi=300, bbox_inches='tight')
fig, ax = plt.subplots(1, 2, figsize=(20, 5))
for i, cond in enumerate(hormonal_conditions):
data = tot_df_morphological[(tot_df_morphological['Line'] == 'CTL08A') &
(tot_df_morphological['Condition'] == cond)]['PC2']
box = ax[0].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = tot_df_morphological[(tot_df_morphological['Condition'] == 'DMSO') &
(tot_df_morphological['Line'] == 'CTL08A')]['PC2'].median()
ax[0].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
for i, cond in enumerate(hormonal_conditions):
data = tot_df_morphological[(tot_df_morphological['Line'] == 'CTL04E') &
(tot_df_morphological['Condition'] == cond)]['PC2']
box = ax[1].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = tot_df_morphological[(tot_df_morphological['Condition'] == 'DMSO') &
(tot_df_morphological['Line'] == 'CTL04E')]['PC2'].median()
ax[1].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
_ = ax[0].set_xticks(range(len(hormonal_conditions)))
_ = ax[0].set_xticklabels(hormonal_conditions, rotation=90)
_ = ax[1].set_xticks(range(len(hormonal_conditions)))
_ = ax[1].set_xticklabels(hormonal_conditions, rotation=90)
ax[0].set_title('CTL08A')
ax[1].set_title('CTL04E')
ax[0].set_ylabel('PC2')
ax[1].set_ylabel('PC2')
plt.savefig('../../../../endpoints_figures/endpoints_PC2_all_nuclei.pdf', dpi=300, bbox_inches='tight')
plt.savefig('../../../../endpoints_figures/endpoints_PC2_all_nuclei.png', dpi=300, bbox_inches='tight')
fig, ax = plt.subplots(1, 2, figsize=(20, 5))
for i, cond in enumerate(hormonal_conditions):
data = tot_df_morphological[(tot_df_morphological['Line'] == 'CTL08A') &
(tot_df_morphological['Condition'] == cond)]['PC3']
box = ax[0].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = tot_df_morphological[(tot_df_morphological['Condition'] == 'DMSO') &
(tot_df_morphological['Line'] == 'CTL08A')]['PC3'].median()
ax[0].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
for i, cond in enumerate(hormonal_conditions):
data = tot_df_morphological[(tot_df_morphological['Line'] == 'CTL04E') &
(tot_df_morphological['Condition'] == cond)]['PC3']
box = ax[1].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = tot_df_morphological[(tot_df_morphological['Condition'] == 'DMSO') &
(tot_df_morphological['Line'] == 'CTL04E')]['PC3'].median()
ax[1].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
_ = ax[0].set_xticks(range(len(hormonal_conditions)))
_ = ax[0].set_xticklabels(hormonal_conditions, rotation=90)
_ = ax[1].set_xticks(range(len(hormonal_conditions)))
_ = ax[1].set_xticklabels(hormonal_conditions, rotation=90)
ax[0].set_title('CTL08A')
ax[1].set_title('CTL04E')
ax[0].set_ylabel('PC3')
ax[1].set_ylabel('PC3')
plt.savefig('../../../../endpoints_figures/endpoints_PC3_all_nuclei.pdf', dpi=300, bbox_inches='tight')
plt.savefig('../../../../endpoints_figures/endpoints_PC3_all_nuclei.png', dpi=300, bbox_inches='tight')
fig, ax = plt.subplots(1, 2, figsize=(20, 5))
for i, cond in enumerate(hormonal_conditions):
data = grouped_df[(grouped_df['Line'] == 'CTL08A') &
(grouped_df['Condition'] == cond)]['PC1']
box = ax[0].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
# Add stripplot for CTL08A (single points per box)
dmso_median = grouped_df[(grouped_df['Condition'] == 'DMSO') &
(grouped_df['Line'] == 'CTL08A')]['PC1'].median()
ax[0].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=grouped_df[(grouped_df['Line'] == 'CTL08A')],
y='PC1', x='Condition', order=hormonal_conditions, color='black', alpha=0.5, jitter=False, ax=ax[0], size=8
)
for i, cond in enumerate(hormonal_conditions):
data = grouped_df[(grouped_df['Line'] == 'CTL04E') &
(grouped_df['Condition'] == cond)]['PC1']
box = ax[1].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = grouped_df[(grouped_df['Condition'] == 'DMSO') &
(grouped_df['Line'] == 'CTL04E')]['PC1'].median()
ax[1].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=grouped_df[grouped_df['Line'] == 'CTL04E'],
y='PC1', x='Condition', order=hormonal_conditions, color='black', alpha=0.5, jitter=False, ax=ax[1], size=8
)
_ = ax[0].set_xticks(range(len(hormonal_conditions)))
_ = ax[0].set_xticklabels(hormonal_conditions, rotation=90)
_ = ax[1].set_xticks(range(len(hormonal_conditions)))
_ = ax[1].set_xticklabels(hormonal_conditions, rotation=90)
ax[0].set_title('CTL08A')
ax[1].set_title('CTL04E')
ax[0].set_ylabel('PC1')
ax[1].set_ylabel('PC1')
plt.savefig('../../../../endpoints_figures/endpoints_PC1_grouped.pdf', dpi=300, bbox_inches='tight')
plt.savefig('../../../../endpoints_figures/endpoints_PC1_grouped.png', dpi=300, bbox_inches='tight')
grouped_df_CTL08A = grouped_df[grouped_df['Line'] == 'CTL08A']
to_test = {}
for i in grouped_df_CTL08A.Condition.unique():
data = grouped_df_CTL08A[grouped_df_CTL08A['Condition'] == i]['PC1'].values
to_test[i] = data
results = stats.kruskal(*list(to_test.values()))
results
KruskalResult(statistic=51.17330953153743, pvalue=3.87841286463078e-06)
DMSO = grouped_df_CTL08A[grouped_df_CTL08A['Condition'] == 'DMSO']['PC1'].values
results_MW_CTL08A_p_values = {}
statistics_MW_CTL08A = {}
for cond in grouped_df_CTL08A.Condition.unique():
if cond != 'DMSO':
data = grouped_df_CTL08A[grouped_df_CTL08A['Condition'] == cond]['PC1'].values
results_MW_CTL08A_p_values[cond] = stats.mannwhitneyu(data, DMSO).pvalue
statistics_MW_CTL08A[cond] = stats.mannwhitneyu(data, DMSO).statistic
pvals_CTL08A = list(results_MW_CTL08A_p_values.values()) # exclude intercept
corrected_pvals_CTL08A = multipletests(pvals_CTL08A, method='fdr_bh')[1]
corrected_pvals_CTL08A = {i:j for i, j in zip(results_MW_CTL08A_p_values.keys(), corrected_pvals_CTL08A)}
results_p_val = pd.DataFrame({'CTL08A': corrected_pvals_CTL08A.values()}, index = corrected_pvals_CTL08A.keys())
results_stat = pd.DataFrame({'CTL08A': statistics_MW_CTL08A.values()}, index = statistics_MW_CTL08A.keys())
DMSO = grouped_df_CTL08A[grouped_df_CTL08A['Condition'] == 'DMSO']['PC1'].values
diff_with_DMSO = {}
for cond in grouped_df_CTL08A.Condition.unique():
if cond != 'DMSO':
data = grouped_df_CTL08A[grouped_df_CTL08A['Condition'] == cond]['PC1'].values
diff_with_DMSO[cond] = np.median(data) - np.median(DMSO)
results_diff = pd.DataFrame({'CTL08A': diff_with_DMSO.values()}, index = diff_with_DMSO.keys())
grouped_df_CTL04E = grouped_df[grouped_df['Line'] == 'CTL04E']
to_test = {}
for i in grouped_df_CTL04E.Condition.unique():
data = grouped_df_CTL04E[grouped_df_CTL04E['Condition'] == i]['PC1'].values
to_test[i] = data
results = stats.kruskal(*list(to_test.values()))
results
KruskalResult(statistic=42.534796404019005, pvalue=2.7062988752687628e-05)
DMSO = grouped_df_CTL04E[grouped_df_CTL04E['Condition'] == 'DMSO']['PC1'].values
results_MW_CTL04E_p_values = {}
statistics_MW_CTL04E = {}
for cond in grouped_df_CTL04E.Condition.unique():
if cond != 'DMSO':
data = grouped_df_CTL04E[grouped_df_CTL04E['Condition'] == cond]['PC1'].values
results_MW_CTL04E_p_values[cond] = stats.mannwhitneyu(data, DMSO).pvalue
statistics_MW_CTL04E[cond] = stats.mannwhitneyu(data, DMSO).statistic
pvals_CTL04E = list(results_MW_CTL04E_p_values.values()) # exclude intercept
corrected_pvals_CTL04E = multipletests(pvals_CTL04E, method='fdr_bh')[1]
corrected_pvals_CTL04E = {i:j for i, j in zip(results_MW_CTL04E_p_values.keys(), corrected_pvals_CTL04E)}
results_p_val['CTL04E'] = results_p_val.index.map(corrected_pvals_CTL04E)
results_stat['CTL04E'] = results_stat.index.map(statistics_MW_CTL04E)
DMSO = grouped_df_CTL04E[grouped_df_CTL04E['Condition'] == 'DMSO']['PC1'].values
diff_with_DMSO = {}
for cond in grouped_df_CTL04E.Condition.unique():
if cond != 'DMSO':
data = grouped_df_CTL04E[grouped_df_CTL04E['Condition'] == cond]['PC1'].values
diff_with_DMSO[cond] = np.median(data) - np.median(DMSO)
results_diff['CTL04E'] = pd.DataFrame({'CTL04E': diff_with_DMSO.values()}, index = diff_with_DMSO.keys())
results_diff = np.round(results_diff, 2)
fig, ax = plt.subplots(figsize = (4,7))
#results_stat = results_stat.applymap(lambda x: f"{x:+.1f}%" if pd.notnull(x) else "")
#results_diff = results_diff[results_p_val < 0.05].fillna('')
sns.heatmap(results_p_val, annot=results_diff[results_p_val < 0.05].fillna(''), cmap='Greens_r', cbar_kws={'label': 'p-value'}, vmin=0, vmax=0.05, ax=ax, fmt='')
plt.title('Condition vs DMSO\n')
Text(0.5, 1.0, 'Condition vs DMSO\n')
fig, ax = plt.subplots(1, 2, figsize=(20, 5))
for i, cond in enumerate(hormonal_conditions):
data = grouped_df[(grouped_df['Line'] == 'CTL08A') &
(grouped_df['Condition'] == cond)]['PC2']
box = ax[0].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
# Add stripplot for CTL08A (single points per box)
dmso_median = grouped_df[(grouped_df['Condition'] == 'DMSO') &
(grouped_df['Line'] == 'CTL08A')]['PC2'].median()
ax[0].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=grouped_df[(grouped_df['Line'] == 'CTL08A')],
y='PC2', x='Condition', order=hormonal_conditions, color='black', alpha=0.5, jitter=False, ax=ax[0], size=8
)
for i, cond in enumerate(hormonal_conditions):
data = grouped_df[(grouped_df['Line'] == 'CTL04E') &
(grouped_df['Condition'] == cond)]['PC2']
box = ax[1].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = grouped_df[(grouped_df['Condition'] == 'DMSO') &
(grouped_df['Line'] == 'CTL04E')]['PC2'].median()
ax[1].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=grouped_df[(grouped_df['Line'] == 'CTL04E')],
y='PC2', x='Condition', order=hormonal_conditions, color='black', alpha=0.5, jitter=False, ax=ax[1], size=8
)
_ = ax[0].set_xticks(range(len(hormonal_conditions)))
_ = ax[0].set_xticklabels(hormonal_conditions, rotation=90)
_ = ax[1].set_xticks(range(len(hormonal_conditions)))
_ = ax[1].set_xticklabels(hormonal_conditions, rotation=90)
ax[0].set_title('CTL08A')
ax[1].set_title('CTL04E')
ax[0].set_ylabel('PC2')
ax[1].set_ylabel('PC2')
plt.savefig('../../../../endpoints_figures/endpoints_PC2_grouped.pdf', dpi=300, bbox_inches='tight')
plt.savefig('../../../../endpoints_figures/endpoints_PC2_grouped.png', dpi=300, bbox_inches='tight')
grouped_df_CTL08A = grouped_df[grouped_df['Line'] == 'CTL08A']
to_test = {}
for i in grouped_df_CTL08A.Condition.unique():
data = grouped_df_CTL08A[grouped_df_CTL08A['Condition'] == i]['PC2'].values
to_test[i] = data
results = stats.kruskal(*list(to_test.values()))
results
KruskalResult(statistic=57.05543654657589, pvalue=3.826203225448208e-07)
DMSO = grouped_df_CTL08A[grouped_df_CTL08A['Condition'] == 'DMSO']['PC2'].values
results_MW_CTL08A_p_values = {}
statistics_MW_CTL08A = {}
for cond in grouped_df_CTL08A.Condition.unique():
if cond != 'DMSO':
data = grouped_df_CTL08A[grouped_df_CTL08A['Condition'] == cond]['PC2'].values
results_MW_CTL08A_p_values[cond] = stats.mannwhitneyu(data, DMSO).pvalue
statistics_MW_CTL08A[cond] = stats.mannwhitneyu(data, DMSO).statistic
pvals_CTL08A = list(results_MW_CTL08A_p_values.values()) # exclude intercept
corrected_pvals_CTL08A = multipletests(pvals_CTL08A, method='fdr_bh')[1]
corrected_pvals_CTL08A = {i:j for i, j in zip(results_MW_CTL08A_p_values.keys(), corrected_pvals_CTL08A)}
results_p_val = pd.DataFrame({'CTL08A': corrected_pvals_CTL08A.values()}, index = corrected_pvals_CTL08A.keys())
results_stat = pd.DataFrame({'CTL08A': statistics_MW_CTL08A.values()}, index = statistics_MW_CTL08A.keys())
DMSO = grouped_df_CTL08A[grouped_df_CTL08A['Condition'] == 'DMSO']['PC2'].values
diff_with_DMSO = {}
for cond in grouped_df_CTL08A.Condition.unique():
if cond != 'DMSO':
data = grouped_df_CTL08A[grouped_df_CTL08A['Condition'] == cond]['PC2'].values
diff_with_DMSO[cond] = np.median(data) - np.median(DMSO)
results_diff = pd.DataFrame({'CTL08A': diff_with_DMSO.values()}, index = diff_with_DMSO.keys())
grouped_df_CTL04E = grouped_df[grouped_df['Line'] == 'CTL04E']
to_test = {}
for i in grouped_df_CTL04E.Condition.unique():
data = grouped_df_CTL04E[grouped_df_CTL04E['Condition'] == i]['PC2'].values
to_test[i] = data
results = stats.kruskal(*list(to_test.values()))
results
KruskalResult(statistic=45.047435219460596, pvalue=1.0113944300737967e-05)
DMSO = grouped_df_CTL04E[grouped_df_CTL04E['Condition'] == 'DMSO']['PC2'].values
results_MW_CTL04E_p_values = {}
statistics_MW_CTL04E = {}
for cond in grouped_df_CTL04E.Condition.unique():
if cond != 'DMSO':
data = grouped_df_CTL04E[grouped_df_CTL04E['Condition'] == cond]['PC2'].values
results_MW_CTL04E_p_values[cond] = stats.mannwhitneyu(data, DMSO).pvalue
statistics_MW_CTL04E[cond] = stats.mannwhitneyu(data, DMSO).statistic
pvals_CTL04E = list(results_MW_CTL04E_p_values.values()) # exclude intercept
corrected_pvals_CTL04E = multipletests(pvals_CTL04E, method='fdr_bh')[1]
corrected_pvals_CTL04E = {i:j for i, j in zip(results_MW_CTL04E_p_values.keys(), corrected_pvals_CTL04E)}
results_p_val['CTL04E'] = results_p_val.index.map(corrected_pvals_CTL04E)
results_stat['CTL04E'] = results_stat.index.map(statistics_MW_CTL04E)
DMSO = grouped_df_CTL04E[grouped_df_CTL04E['Condition'] == 'DMSO']['PC2'].values
diff_with_DMSO = {}
for cond in grouped_df_CTL04E.Condition.unique():
if cond != 'DMSO':
data = grouped_df_CTL04E[grouped_df_CTL04E['Condition'] == cond]['PC2'].values
diff_with_DMSO[cond] = np.median(data) - np.median(DMSO)
results_diff['CTL04E'] = pd.DataFrame({'CTL04E': diff_with_DMSO.values()}, index = diff_with_DMSO.keys())
results_diff = np.round(results_diff, 2)
fig, ax = plt.subplots(figsize = (4,7))
#results_stat = results_stat.applymap(lambda x: f"{x:+.1f}%" if pd.notnull(x) else "")
#results_diff = results_diff[results_p_val < 0.05].fillna('')
sns.heatmap(results_p_val, annot=results_diff[results_p_val < 0.05].fillna(''), cmap='Greens_r', cbar_kws={'label': 'p-value'}, vmin=0, vmax=0.05, ax=ax, fmt='')
plt.title('Condition vs DMSO\n')
Text(0.5, 1.0, 'Condition vs DMSO\n')
fig, ax = plt.subplots(1, 2, figsize=(20, 5))
for i, cond in enumerate(hormonal_conditions):
data = grouped_df[(grouped_df['Line'] == 'CTL08A') &
(grouped_df['Condition'] == cond)]['PC3']
box = ax[0].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
# Add stripplot for CTL08A (single points per box)
dmso_median = grouped_df[(grouped_df['Condition'] == 'DMSO') &
(grouped_df['Line'] == 'CTL08A')]['PC3'].median()
ax[0].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=grouped_df[(grouped_df['Line'] == 'CTL08A')],
y='PC3', x='Condition', order=hormonal_conditions, color='black', alpha=0.5, jitter=False, ax=ax[0], size=8
)
for i, cond in enumerate(hormonal_conditions):
data = grouped_df[(grouped_df['Line'] == 'CTL04E') &
(grouped_df['Condition'] == cond)]['PC3']
box = ax[1].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = grouped_df[(grouped_df['Condition'] == 'DMSO') &
(grouped_df['Line'] == 'CTL04E')]['PC3'].median()
ax[1].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=grouped_df[(grouped_df['Line'] == 'CTL04E')],
y='PC3', x='Condition', order=hormonal_conditions, color='black', alpha=0.5, jitter=False, ax=ax[1], size=8
)
_ = ax[0].set_xticks(range(len(hormonal_conditions)))
_ = ax[0].set_xticklabels(hormonal_conditions, rotation=90)
_ = ax[1].set_xticks(range(len(hormonal_conditions)))
_ = ax[1].set_xticklabels(hormonal_conditions, rotation=90)
ax[0].set_title('CTL08A')
ax[1].set_title('CTL04E')
ax[0].set_ylabel('PC3')
ax[1].set_ylabel('PC3')
plt.savefig('../../../../endpoints_figures/endpoints_PC3_grouped.pdf', dpi=300, bbox_inches='tight')
plt.savefig('../../../../endpoints_figures/endpoints_PC3_grouped.png', dpi=300, bbox_inches='tight')
grouped_df_CTL08A = grouped_df[grouped_df['Line'] == 'CTL08A']
to_test = {}
for i in grouped_df_CTL08A.Condition.unique():
data = grouped_df_CTL08A[grouped_df_CTL08A['Condition'] == i]['PC3'].values
to_test[i] = data
results = stats.kruskal(*list(to_test.values()))
results
KruskalResult(statistic=29.874099318403125, pvalue=0.00794236681106045)
DMSO = grouped_df_CTL08A[grouped_df_CTL08A['Condition'] == 'DMSO']['PC3'].values
results_MW_CTL08A_p_values = {}
statistics_MW_CTL08A = {}
for cond in grouped_df_CTL08A.Condition.unique():
if cond != 'DMSO':
data = grouped_df_CTL08A[grouped_df_CTL08A['Condition'] == cond]['PC3'].values
results_MW_CTL08A_p_values[cond] = stats.mannwhitneyu(data, DMSO).pvalue
statistics_MW_CTL08A[cond] = stats.mannwhitneyu(data, DMSO).statistic
pvals_CTL08A = list(results_MW_CTL08A_p_values.values()) # exclude intercept
corrected_pvals_CTL08A = multipletests(pvals_CTL08A, method='fdr_bh')[1]
corrected_pvals_CTL08A = {i:j for i, j in zip(results_MW_CTL08A_p_values.keys(), corrected_pvals_CTL08A)}
results_p_val = pd.DataFrame({'CTL08A': corrected_pvals_CTL08A.values()}, index = corrected_pvals_CTL08A.keys())
results_stat = pd.DataFrame({'CTL08A': statistics_MW_CTL08A.values()}, index = statistics_MW_CTL08A.keys())
DMSO = grouped_df_CTL08A[grouped_df_CTL08A['Condition'] == 'DMSO']['PC3'].values
diff_with_DMSO = {}
for cond in grouped_df_CTL08A.Condition.unique():
if cond != 'DMSO':
data = grouped_df_CTL08A[grouped_df_CTL08A['Condition'] == cond]['PC3'].values
diff_with_DMSO[cond] = np.median(data) - np.median(DMSO)
results_diff = pd.DataFrame({'CTL08A': diff_with_DMSO.values()}, index = diff_with_DMSO.keys())
grouped_df_CTL04E = grouped_df[grouped_df['Line'] == 'CTL04E']
to_test = {}
for i in grouped_df_CTL04E.Condition.unique():
data = grouped_df_CTL04E[grouped_df_CTL04E['Condition'] == i]['PC3'].values
to_test[i] = data
results = stats.kruskal(*list(to_test.values()))
results
KruskalResult(statistic=27.127445795875133, pvalue=0.007407220324972986)
DMSO = grouped_df_CTL04E[grouped_df_CTL04E['Condition'] == 'DMSO']['PC3'].values
results_MW_CTL04E_p_values = {}
statistics_MW_CTL04E = {}
for cond in grouped_df_CTL04E.Condition.unique():
if cond != 'DMSO':
data = grouped_df_CTL04E[grouped_df_CTL04E['Condition'] == cond]['PC3'].values
results_MW_CTL04E_p_values[cond] = stats.mannwhitneyu(data, DMSO).pvalue
statistics_MW_CTL04E[cond] = stats.mannwhitneyu(data, DMSO).statistic
pvals_CTL04E = list(results_MW_CTL04E_p_values.values()) # exclude intercept
corrected_pvals_CTL04E = multipletests(pvals_CTL04E, method='fdr_bh')[1]
corrected_pvals_CTL04E = {i:j for i, j in zip(results_MW_CTL04E_p_values.keys(), corrected_pvals_CTL04E)}
results_p_val['CTL04E'] = results_p_val.index.map(corrected_pvals_CTL04E)
results_stat['CTL04E'] = results_stat.index.map(statistics_MW_CTL04E)
DMSO = grouped_df_CTL04E[grouped_df_CTL04E['Condition'] == 'DMSO']['PC3'].values
diff_with_DMSO = {}
for cond in grouped_df_CTL04E.Condition.unique():
if cond != 'DMSO':
data = grouped_df_CTL04E[grouped_df_CTL04E['Condition'] == cond]['PC3'].values
diff_with_DMSO[cond] = np.median(data) - np.median(DMSO)
results_diff['CTL04E'] = pd.DataFrame({'CTL04E': diff_with_DMSO.values()}, index = diff_with_DMSO.keys())
results_diff = np.round(results_diff, 2)
fig, ax = plt.subplots(figsize = (4,7))
#results_stat = results_stat.applymap(lambda x: f"{x:+.1f}%" if pd.notnull(x) else "")
#results_diff = results_diff[results_p_val < 0.05].fillna('')
sns.heatmap(results_p_val, annot=results_diff[results_p_val < 0.05].fillna(''), cmap='Greens_r', cbar_kws={'label': 'p-value'}, vmin=0, vmax=0.05, ax=ax, fmt='')
plt.title('Condition vs DMSO\n')
Text(0.5, 1.0, 'Condition vs DMSO\n')
important_features_pca1 = pca_components.loc['PC1'].sort_values(ascending=False)
import matplotlib.pyplot as plt
# Lollipop plot for important_features_pca1
plt.figure(figsize=(5, 6))
x = important_features_pca1.index
y = important_features_pca1.values
plt.stem(x, y, basefmt=" ")
plt.xticks(rotation=90)
plt.ylabel('Contribution to PC1')
plt.tight_layout()
plt.savefig('../../../../endpoints_figures/important_features_pca1.pdf', dpi=300, bbox_inches='tight')
important_features_pca2 = pca_components.loc['PC2'].sort_values(ascending=False)
plt.figure(figsize=(5, 6))
x = important_features_pca2.index
y = important_features_pca2.values
plt.stem(x, y, basefmt=" ")
plt.xticks(rotation=90)
plt.ylabel('Contribution to PC2')
plt.tight_layout()
plt.savefig('../../../../endpoints_figures/important_features_pca2.pdf', dpi=300, bbox_inches='tight')
important_features_pca3 = pca_components.loc['PC3'].sort_values(ascending=False)
plt.figure(figsize=(5, 6))
x = important_features_pca3.index
y = important_features_pca3.values
plt.stem(x, y, basefmt=" ")
plt.xticks(rotation=90)
plt.ylabel('Contribution to PC3')
plt.tight_layout()
plt.savefig('../../../../endpoints_figures/important_features_pca3.pdf', dpi=300, bbox_inches='tight')
Main contributor of variance for PC1
fig, ax = plt.subplots(1, 2, figsize=(20, 5))
for i, cond in enumerate(hormonal_conditions):
data = tot_df_morphological[(tot_df_morphological['Line'] == 'CTL08A') &
(tot_df_morphological['Condition'] == cond)]['equivalent_diameter']
box = ax[0].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = tot_df_morphological[(tot_df_morphological['Condition'] == 'DMSO') &
(tot_df_morphological['Line'] == 'CTL08A')]['equivalent_diameter'].median()
ax[0].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
for i, cond in enumerate(hormonal_conditions):
data = tot_df_morphological[(tot_df_morphological['Line'] == 'CTL04E') &
(tot_df_morphological['Condition'] == cond)]['equivalent_diameter']
box = ax[1].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = tot_df_morphological[(tot_df_morphological['Condition'] == 'DMSO') &
(tot_df_morphological['Line'] == 'CTL04E')]['equivalent_diameter'].median()
ax[1].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
_ = ax[0].set_xticks(range(len(hormonal_conditions)))
_ = ax[0].set_xticklabels(hormonal_conditions, rotation=90)
_ = ax[1].set_xticks(range(len(hormonal_conditions)))
_ = ax[1].set_xticklabels(hormonal_conditions, rotation=90)
ax[0].set_title('CTL08A')
ax[1].set_title('CTL04E')
ax[0].set_ylabel('equivalent_diameter')
ax[1].set_ylabel('equivalent_diameter')
plt.savefig('../../../../endpoints_figures/endpoints_equivalent_diameter_all_nuclei.pdf', dpi=300, bbox_inches='tight')
plt.savefig('../../../../endpoints_figures/endpoints_equivalent_diameter_all_nuclei.png', dpi=300, bbox_inches='tight')
fig, ax = plt.subplots(1, 2, figsize=(20, 5))
for i, cond in enumerate(hormonal_conditions):
data = grouped_df[(grouped_df['Line'] == 'CTL08A') &
(grouped_df['Condition'] == cond)]['equivalent_diameter']
box = ax[0].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
# Add stripplot for CTL08A (single points per box)
dmso_median = grouped_df[(grouped_df['Condition'] == 'DMSO') &
(grouped_df['Line'] == 'CTL08A')]['equivalent_diameter'].median()
ax[0].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=grouped_df[(grouped_df['Line'] == 'CTL08A')],
y='equivalent_diameter', x='Condition', order=hormonal_conditions, color='black', alpha=0.5, jitter=False, ax=ax[0], size=8
)
for i, cond in enumerate(hormonal_conditions):
data = grouped_df[(grouped_df['Line'] == 'CTL04E') &
(grouped_df['Condition'] == cond)]['equivalent_diameter']
box = ax[1].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = grouped_df[(grouped_df['Condition'] == 'DMSO') &
(grouped_df['Line'] == 'CTL04E')]['equivalent_diameter'].median()
ax[1].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=grouped_df[(grouped_df['Line'] == 'CTL04E')],
y='equivalent_diameter', x='Condition', order=hormonal_conditions, color='black', alpha=0.5, jitter=False, ax=ax[1], size=8
)
_ = ax[0].set_xticks(range(len(hormonal_conditions)))
_ = ax[0].set_xticklabels(hormonal_conditions, rotation=90)
_ = ax[1].set_xticks(range(len(hormonal_conditions)))
_ = ax[1].set_xticklabels(hormonal_conditions, rotation=90)
ax[0].set_title('CTL08A')
ax[1].set_title('CTL04E')
ax[0].set_ylabel('equivalent_diameter')
ax[1].set_ylabel('equivalent_diameter')
plt.savefig('../../../../endpoints_figures/endpoints_equivalent_diameter_grouped.pdf', dpi=300, bbox_inches='tight')
plt.savefig('../../../../endpoints_figures/endpoints_equivalent_diameter_grouped.png', dpi=300, bbox_inches='tight')
grouped_df_CTL08A = grouped_df[grouped_df['Line'] == 'CTL08A']
grouped_df_CTL08A['Condition'] = grouped_df_CTL08A['Condition'].astype('category')
model_CTL08A = smf.ols("equivalent_diameter ~ C(Condition, Treatment(reference='DMSO'))",
data=grouped_df_CTL08A,
).fit()
print(model_CTL08A.summary())
OLS Regression Results
===============================================================================
Dep. Variable: equivalent_diameter R-squared: 0.541
Model: OLS Adj. R-squared: 0.439
Method: Least Squares F-statistic: 5.298
Date: Tue, 28 Apr 2026 Prob (F-statistic): 1.69e-06
Time: 15:53:39 Log-Likelihood: -193.55
No. Observations: 78 AIC: 417.1
Df Residuals: 63 BIC: 452.5
Df Model: 14
Covariance Type: nonrobust
=========================================================================================================================
coef std err t P>|t| [0.025 0.975]
-------------------------------------------------------------------------------------------------------------------------
Intercept 19.1982 1.314 14.605 0.000 16.571 21.825
C(Condition, Treatment(reference='DMSO'))[T.ANDR_AG] 1.3612 1.859 0.732 0.467 -2.354 5.076
C(Condition, Treatment(reference='DMSO'))[T.ANDR_INH] 4.2478 2.277 1.866 0.067 -0.302 8.797
C(Condition, Treatment(reference='DMSO'))[T.ARYL_AG] 2.4017 1.697 1.415 0.162 -0.989 5.793
C(Condition, Treatment(reference='DMSO'))[T.ARYL_INH] 2.8381 1.859 1.527 0.132 -0.877 6.553
C(Condition, Treatment(reference='DMSO'))[T.ESTR_AG] 2.8453 2.078 1.369 0.176 -1.308 6.999
C(Condition, Treatment(reference='DMSO'))[T.ESTR_INH] 2.0426 2.078 0.983 0.329 -2.111 6.196
C(Condition, Treatment(reference='DMSO'))[T.GC_AG] 1.4172 2.078 0.682 0.498 -2.736 5.570
C(Condition, Treatment(reference='DMSO'))[T.GC_INH] 2.6384 1.950 1.353 0.181 -1.258 6.535
C(Condition, Treatment(reference='DMSO'))[T.LX_AG] 2.2393 1.859 1.205 0.233 -1.476 5.954
C(Condition, Treatment(reference='DMSO'))[T.LX_INH] 0.8054 2.277 0.354 0.725 -3.744 5.355
C(Condition, Treatment(reference='DMSO'))[T.RET_AG] 12.6892 1.859 6.826 0.000 8.974 16.404
C(Condition, Treatment(reference='DMSO'))[T.RET_INH] 0.2288 1.859 0.123 0.902 -3.486 3.944
C(Condition, Treatment(reference='DMSO'))[T.THYR_AG] 0.3718 1.950 0.191 0.849 -3.524 4.268
C(Condition, Treatment(reference='DMSO'))[T.THYR_INH] 0.3973 1.950 0.204 0.839 -3.499 4.293
==============================================================================
Omnibus: 43.608 Durbin-Watson: 1.275
Prob(Omnibus): 0.000 Jarque-Bera (JB): 633.742
Skew: 1.052 Prob(JB): 2.42e-138
Kurtosis: 16.805 Cond. No. 15.0
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
/tmp/ipykernel_1121090/2352630096.py:2: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
grouped_df_CTL08A['Condition'] = grouped_df_CTL08A['Condition'].astype('category')
grouped_df_CTL04E = grouped_df[grouped_df['Line'] == 'CTL04E']
grouped_df_CTL04E['Condition'] = grouped_df_CTL04E['Condition'].astype('category')
model_CTL04E = smf.ols("equivalent_diameter ~ C(Condition, Treatment(reference='DMSO'))",
data=grouped_df_CTL04E,
).fit()
print(model_CTL04E.summary())
OLS Regression Results
===============================================================================
Dep. Variable: equivalent_diameter R-squared: 0.738
Model: OLS Adj. R-squared: 0.672
Method: Least Squares F-statistic: 11.25
Date: Tue, 28 Apr 2026 Prob (F-statistic): 3.14e-10
Time: 15:53:39 Log-Likelihood: -73.088
No. Observations: 61 AIC: 172.2
Df Residuals: 48 BIC: 199.6
Df Model: 12
Covariance Type: nonrobust
=========================================================================================================================
coef std err t P>|t| [0.025 0.975]
-------------------------------------------------------------------------------------------------------------------------
Intercept 20.3398 0.452 45.000 0.000 19.431 21.249
C(Condition, Treatment(reference='DMSO'))[T.ANDR_AG] 0.8830 0.639 1.381 0.174 -0.402 2.168
C(Condition, Treatment(reference='DMSO'))[T.ANDR_INH] 0.8536 0.690 1.236 0.222 -0.535 2.242
C(Condition, Treatment(reference='DMSO'))[T.ARYL_AG] -1.4807 0.584 -2.537 0.014 -2.654 -0.307
C(Condition, Treatment(reference='DMSO'))[T.ARYL_INH] 1.6345 0.584 2.801 0.007 0.461 2.808
C(Condition, Treatment(reference='DMSO'))[T.ESTR_AG] -0.0834 0.690 -0.121 0.904 -1.472 1.305
C(Condition, Treatment(reference='DMSO'))[T.ESTR_INH] -1.1550 0.584 -1.979 0.054 -2.328 0.018
C(Condition, Treatment(reference='DMSO'))[T.GC_INH] -1.9279 0.584 -3.304 0.002 -3.101 -0.755
C(Condition, Treatment(reference='DMSO'))[T.LX_AG] -2.4619 0.606 -4.060 0.000 -3.681 -1.243
C(Condition, Treatment(reference='DMSO'))[T.LX_INH] -1.8504 0.584 -3.171 0.003 -3.024 -0.677
C(Condition, Treatment(reference='DMSO'))[T.RET_INH] -1.3852 0.639 -2.167 0.035 -2.670 -0.100
C(Condition, Treatment(reference='DMSO'))[T.THYR_AG] -0.8752 0.584 -1.500 0.140 -2.048 0.298
C(Condition, Treatment(reference='DMSO'))[T.THYR_INH] 2.2845 0.783 2.918 0.005 0.710 3.859
==============================================================================
Omnibus: 4.570 Durbin-Watson: 2.574
Prob(Omnibus): 0.102 Jarque-Bera (JB): 2.841
Skew: -0.334 Prob(JB): 0.242
Kurtosis: 2.180 Cond. No. 15.1
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
/tmp/ipykernel_1121090/2302572593.py:2: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
grouped_df_CTL04E['Condition'] = grouped_df_CTL04E['Condition'].astype('category')
resid_CTL08A = model_CTL08A.resid
stats.probplot(resid_CTL08A, dist="norm", plot=plt)
plt.show()
resid_CTL04E = model_CTL04E.resid
stats.probplot(resid_CTL04E, dist="norm", plot=plt)
plt.show()
pvals_CTL08A = model_CTL08A.pvalues[1:] # exclude intercept
corrected_pvals_CTL08A = multipletests(pvals_CTL08A, method='fdr_bh')[1]
df_results_CTL08A = pd.concat([model_CTL08A.params, pd.Series(corrected_pvals_CTL08A, index=model_CTL08A.params.index[1:])], axis = 1).iloc[1:]
df_results_CTL08A.columns = ['intercept', 'pvalue']
pvals_CTL04E = model_CTL04E.pvalues[1:] # exclude intercept
corrected_pvals_CTL04E = multipletests(pvals_CTL04E, method='fdr_bh')[1]
df_results_CTL04E = pd.concat([model_CTL04E.params, pd.Series(corrected_pvals_CTL04E, index=model_CTL04E.params.index[1:])], axis = 1).iloc[1:]
df_results_CTL04E.columns = ['intercept', 'pvalue']
pvals = pd.concat([df_results_CTL08A['pvalue'], df_results_CTL04E['pvalue']], axis = 1)
pvals.columns = ['CTL08A', 'CTL04E']
pvals.index = [i.split('C(Condition, Treatment(reference=\'DMSO\'))[T.')[1].replace(']', '') for i in pvals.index]
pvals
| CTL08A | CTL04E | |
|---|---|---|
| ANDR_AG | 6.969339e-01 | 0.208263 |
| ANDR_INH | 4.218924e-01 | 0.242570 |
| ARYL_AG | 4.218924e-01 | 0.028941 |
| ARYL_INH | 4.218924e-01 | 0.017565 |
| ESTR_AG | 4.218924e-01 | 0.904346 |
| ESTR_INH | 5.765536e-01 | 0.080280 |
| GC_AG | 6.969339e-01 | NaN |
| GC_INH | 4.218924e-01 | 0.010585 |
| LX_AG | 4.657286e-01 | 0.002164 |
| LX_INH | 9.024162e-01 | 0.010585 |
| RET_AG | 5.618575e-08 | NaN |
| RET_INH | 9.024162e-01 | 0.060399 |
| THYR_AG | 9.024162e-01 | 0.186927 |
| THYR_INH | 9.024162e-01 | 0.016037 |
intercepts = pd.concat([df_results_CTL08A['intercept'], df_results_CTL04E['intercept']], axis = 1)
intercepts.columns = ['CTL08A', 'CTL04E']
intercepts.index = [i.split('C(Condition, Treatment(reference=\'DMSO\'))[T.')[1].replace(']', '') for i in intercepts.index]
params = model_CTL08A.params
mean_DMSO = params["Intercept"]
intercepts['CTL08A'] = intercepts['CTL08A']/ mean_DMSO * 100
params = model_CTL04E.params
mean_DMSO = params["Intercept"]
intercepts['CTL04E'] = intercepts['CTL04E']/ mean_DMSO * 100
intercepts
| CTL08A | CTL04E | |
|---|---|---|
| ANDR_AG | 7.090013 | 4.341349 |
| ANDR_INH | 22.125814 | 4.196708 |
| ARYL_AG | 12.510013 | -7.279584 |
| ARYL_INH | 14.783145 | 8.036174 |
| ESTR_AG | 14.820896 | -0.410092 |
| ESTR_INH | 10.639776 | -5.678729 |
| GC_AG | 7.382001 | NaN |
| GC_INH | 13.743015 | -9.478257 |
| LX_AG | 11.664044 | -12.103826 |
| LX_INH | 4.195281 | -9.097445 |
| RET_AG | 66.096060 | NaN |
| RET_INH | 1.192013 | -6.810068 |
| THYR_AG | 1.936849 | -4.302990 |
| THYR_INH | 2.069517 | 11.231696 |
fig, ax = plt.subplots(figsize = (4,7))
intercepts = intercepts.applymap(lambda x: f"{x:+.1f}%" if pd.notnull(x) else "")
intercepts = intercepts[pvals < 0.05].fillna('')
sns.heatmap(pvals, annot=intercepts, fmt='', cmap='Greens_r', cbar_kws={'label': 'p-value'}, vmin=0, vmax=0.05, ax = ax)
plt.title('Condition vs DMSO\n')
plt.savefig('../../../../endpoints_figures/endpoints_organoids_eq_diameter_OLS_test.png', dpi=300, bbox_inches='tight')
/tmp/ipykernel_1121090/3118655519.py:2: FutureWarning: DataFrame.applymap has been deprecated. Use DataFrame.map instead.
intercepts = intercepts.applymap(lambda x: f"{x:+.1f}%" if pd.notnull(x) else "")
Main contributor of variance for PC2
fig, ax = plt.subplots(1, 2, figsize=(20, 5))
for i, cond in enumerate(hormonal_conditions):
data = tot_df_morphological[(tot_df_morphological['Line'] == 'CTL08A') &
(tot_df_morphological['Condition'] == cond)]['extent']
box = ax[0].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = tot_df_morphological[(tot_df_morphological['Condition'] == 'DMSO') &
(tot_df_morphological['Line'] == 'CTL08A')]['extent'].median()
ax[0].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
for i, cond in enumerate(hormonal_conditions):
data = tot_df_morphological[(tot_df_morphological['Line'] == 'CTL04E') &
(tot_df_morphological['Condition'] == cond)]['extent']
box = ax[1].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = tot_df_morphological[(tot_df_morphological['Condition'] == 'DMSO') &
(tot_df_morphological['Line'] == 'CTL04E')]['extent'].median()
ax[1].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
_ = ax[0].set_xticks(range(len(hormonal_conditions)))
_ = ax[0].set_xticklabels(hormonal_conditions, rotation=90)
_ = ax[1].set_xticks(range(len(hormonal_conditions)))
_ = ax[1].set_xticklabels(hormonal_conditions, rotation=90)
ax[0].set_title('CTL08A')
ax[1].set_title('CTL04E')
ax[0].set_ylabel('extent')
ax[1].set_ylabel('extent')
plt.savefig('../../../../endpoints_figures/endpoints_extent_all_nuclei.pdf', dpi=300, bbox_inches='tight')
plt.savefig('../../../../endpoints_figures/endpoints_extent_all_nuclei.png', dpi=300, bbox_inches='tight')
fig, ax = plt.subplots(1, 2, figsize=(20, 5))
for i, cond in enumerate(hormonal_conditions):
data = grouped_df[(grouped_df['Line'] == 'CTL08A') &
(grouped_df['Condition'] == cond)]['extent']
box = ax[0].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
# Add stripplot for CTL08A (single points per box)
dmso_median = grouped_df[(grouped_df['Condition'] == 'DMSO') &
(grouped_df['Line'] == 'CTL08A')]['extent'].median()
ax[0].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=grouped_df[(grouped_df['Line'] == 'CTL08A') & (grouped_df['Condition'] == cond)],
y='extent', x='Condition', order=[cond], color='black', alpha=0.5, jitter=False, ax=ax[0], size=8
)
for i, cond in enumerate(hormonal_conditions):
data = grouped_df[(grouped_df['Line'] == 'CTL04E') &
(grouped_df['Condition'] == cond)]['extent']
box = ax[1].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = grouped_df[(grouped_df['Condition'] == 'DMSO') &
(grouped_df['Line'] == 'CTL04E')]['extent'].median()
ax[1].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=grouped_df[(grouped_df['Line'] == 'CTL04E') & (grouped_df['Condition'] == cond)],
y='extent', x='Condition', order=[cond], color='black', alpha=0.5, jitter=False, ax=ax[1], size=8
)
_ = ax[0].set_xticks(range(len(hormonal_conditions)))
_ = ax[0].set_xticklabels(hormonal_conditions, rotation=90)
_ = ax[1].set_xticks(range(len(hormonal_conditions)))
_ = ax[1].set_xticklabels(hormonal_conditions, rotation=90)
ax[0].set_title('CTL08A')
ax[1].set_title('CTL04E')
ax[0].set_ylabel('extent')
ax[1].set_ylabel('extent')
plt.savefig('../../../../endpoints_figures/endpoints_extent_grouped.pdf', dpi=300, bbox_inches='tight')
plt.savefig('../../../../endpoints_figures/endpoints_extent_grouped.png', dpi=300, bbox_inches='tight')
grouped_df_CTL08A = grouped_df[grouped_df['Line'] == 'CTL08A']
grouped_df_CTL08A['Condition'] = grouped_df_CTL08A['Condition'].astype('category')
model_CTL08A = smf.ols("extent ~ C(Condition, Treatment(reference='DMSO'))",
data=grouped_df_CTL08A,
).fit()
print(model_CTL08A.summary())
OLS Regression Results
==============================================================================
Dep. Variable: extent R-squared: 0.483
Model: OLS Adj. R-squared: 0.368
Method: Least Squares F-statistic: 4.206
Date: Tue, 28 Apr 2026 Prob (F-statistic): 3.73e-05
Time: 15:54:29 Log-Likelihood: 300.72
No. Observations: 78 AIC: -571.4
Df Residuals: 63 BIC: -536.1
Df Model: 14
Covariance Type: nonrobust
=========================================================================================================================
coef std err t P>|t| [0.025 0.975]
-------------------------------------------------------------------------------------------------------------------------
Intercept 0.7392 0.002 317.709 0.000 0.735 0.744
C(Condition, Treatment(reference='DMSO'))[T.ANDR_AG] -0.0058 0.003 -1.757 0.084 -0.012 0.001
C(Condition, Treatment(reference='DMSO'))[T.ANDR_INH] -0.0102 0.004 -2.528 0.014 -0.018 -0.002
C(Condition, Treatment(reference='DMSO'))[T.ARYL_AG] -0.0088 0.003 -2.938 0.005 -0.015 -0.003
C(Condition, Treatment(reference='DMSO'))[T.ARYL_INH] -0.0081 0.003 -2.464 0.016 -0.015 -0.002
C(Condition, Treatment(reference='DMSO'))[T.ESTR_AG] -0.0137 0.004 -3.719 0.000 -0.021 -0.006
C(Condition, Treatment(reference='DMSO'))[T.ESTR_INH] 0.0004 0.004 0.099 0.922 -0.007 0.008
C(Condition, Treatment(reference='DMSO'))[T.GC_AG] 0.0008 0.004 0.219 0.828 -0.007 0.008
C(Condition, Treatment(reference='DMSO'))[T.GC_INH] -0.0054 0.003 -1.577 0.120 -0.012 0.001
C(Condition, Treatment(reference='DMSO'))[T.LX_AG] -0.0040 0.003 -1.211 0.230 -0.011 0.003
C(Condition, Treatment(reference='DMSO'))[T.LX_INH] -0.0083 0.004 -2.051 0.044 -0.016 -0.000
C(Condition, Treatment(reference='DMSO'))[T.RET_AG] -0.0114 0.003 -3.479 0.001 -0.018 -0.005
C(Condition, Treatment(reference='DMSO'))[T.RET_INH] 0.0041 0.003 1.234 0.222 -0.003 0.011
C(Condition, Treatment(reference='DMSO'))[T.THYR_AG] -0.0069 0.003 -1.987 0.051 -0.014 3.79e-05
C(Condition, Treatment(reference='DMSO'))[T.THYR_INH] 0.0003 0.003 0.080 0.936 -0.007 0.007
==============================================================================
Omnibus: 20.325 Durbin-Watson: 2.053
Prob(Omnibus): 0.000 Jarque-Bera (JB): 146.730
Skew: -0.019 Prob(JB): 1.37e-32
Kurtosis: 9.719 Cond. No. 15.0
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
/tmp/ipykernel_1121090/3097047810.py:2: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
grouped_df_CTL08A['Condition'] = grouped_df_CTL08A['Condition'].astype('category')
grouped_df_CTL04E = grouped_df[grouped_df['Line'] == 'CTL04E']
grouped_df_CTL04E['Condition'] = grouped_df_CTL04E['Condition'].astype('category')
model_CTL04E = smf.ols("extent ~ C(Condition, Treatment(reference='DMSO'))",
data=grouped_df_CTL04E,
).fit()
print(model_CTL04E.summary())
OLS Regression Results
==============================================================================
Dep. Variable: extent R-squared: 0.696
Model: OLS Adj. R-squared: 0.620
Method: Least Squares F-statistic: 9.153
Date: Tue, 28 Apr 2026 Prob (F-statistic): 8.30e-09
Time: 15:54:29 Log-Likelihood: 265.75
No. Observations: 61 AIC: -505.5
Df Residuals: 48 BIC: -478.1
Df Model: 12
Covariance Type: nonrobust
=========================================================================================================================
coef std err t P>|t| [0.025 0.975]
-------------------------------------------------------------------------------------------------------------------------
Intercept 0.7404 0.002 423.362 0.000 0.737 0.744
C(Condition, Treatment(reference='DMSO'))[T.ANDR_AG] -0.0087 0.002 -3.509 0.001 -0.014 -0.004
C(Condition, Treatment(reference='DMSO'))[T.ANDR_INH] -0.0073 0.003 -2.728 0.009 -0.013 -0.002
C(Condition, Treatment(reference='DMSO'))[T.ARYL_AG] -0.0007 0.002 -0.289 0.774 -0.005 0.004
C(Condition, Treatment(reference='DMSO'))[T.ARYL_INH] -0.0039 0.002 -1.739 0.088 -0.008 0.001
C(Condition, Treatment(reference='DMSO'))[T.ESTR_AG] 0.0028 0.003 1.055 0.297 -0.003 0.008
C(Condition, Treatment(reference='DMSO'))[T.ESTR_INH] 0.0085 0.002 3.756 0.000 0.004 0.013
C(Condition, Treatment(reference='DMSO'))[T.GC_INH] 0.0031 0.002 1.366 0.178 -0.001 0.008
C(Condition, Treatment(reference='DMSO'))[T.LX_AG] 0.0039 0.002 1.683 0.099 -0.001 0.009
C(Condition, Treatment(reference='DMSO'))[T.LX_INH] 0.0020 0.002 0.893 0.376 -0.003 0.007
C(Condition, Treatment(reference='DMSO'))[T.RET_INH] 0.0063 0.002 2.536 0.015 0.001 0.011
C(Condition, Treatment(reference='DMSO'))[T.THYR_AG] -0.0025 0.002 -1.107 0.274 -0.007 0.002
C(Condition, Treatment(reference='DMSO'))[T.THYR_INH] 0.0006 0.003 0.197 0.844 -0.005 0.007
==============================================================================
Omnibus: 0.005 Durbin-Watson: 1.897
Prob(Omnibus): 0.997 Jarque-Bera (JB): 0.138
Skew: 0.010 Prob(JB): 0.933
Kurtosis: 2.768 Cond. No. 15.1
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
/tmp/ipykernel_1121090/270499386.py:2: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
grouped_df_CTL04E['Condition'] = grouped_df_CTL04E['Condition'].astype('category')
resid_CTL08A = model_CTL08A.resid
stats.probplot(resid_CTL08A, dist="norm", plot=plt)
plt.show()
resid_CTL04E = model_CTL04E.resid
stats.probplot(resid_CTL04E, dist="norm", plot=plt)
plt.show()
pvals_CTL08A = model_CTL08A.pvalues[1:] # exclude intercept
corrected_pvals_CTL08A = multipletests(pvals_CTL08A, method='fdr_bh')[1]
df_results_CTL08A = pd.concat([model_CTL08A.params, pd.Series(corrected_pvals_CTL08A, index=model_CTL08A.params.index[1:])], axis = 1).iloc[1:]
df_results_CTL08A.columns = ['intercept', 'pvalue']
pvals_CTL04E = model_CTL04E.pvalues[1:] # exclude intercept
corrected_pvals_CTL04E = multipletests(pvals_CTL04E, method='fdr_bh')[1]
df_results_CTL04E = pd.concat([model_CTL04E.params, pd.Series(corrected_pvals_CTL04E, index=model_CTL04E.params.index[1:])], axis = 1).iloc[1:]
df_results_CTL04E.columns = ['intercept', 'pvalue']
pvals = pd.concat([df_results_CTL08A['pvalue'], df_results_CTL04E['pvalue']], axis = 1)
pvals.columns = ['CTL08A', 'CTL04E']
pvals.index = [i.split('C(Condition, Treatment(reference=\'DMSO\'))[T.')[1].replace(']', '') for i in pvals.index]
pvals
| CTL08A | CTL04E | |
|---|---|---|
| ANDR_AG | 0.146588 | 0.005935 |
| ANDR_INH | 0.046107 | 0.035509 |
| ARYL_AG | 0.021496 | 0.844374 |
| ARYL_INH | 0.046107 | 0.197766 |
| ESTR_AG | 0.005981 | 0.395654 |
| ESTR_INH | 0.936429 | 0.005601 |
| GC_AG | 0.936429 | NaN |
| GC_INH | 0.186370 | 0.305775 |
| LX_AG | 0.293340 | 0.197766 |
| LX_INH | 0.102465 | 0.451261 |
| RET_AG | 0.006429 | NaN |
| RET_INH | 0.293340 | 0.043522 |
| THYR_AG | 0.102465 | 0.395654 |
| THYR_INH | 0.936429 | 0.844461 |
intercepts = pd.concat([df_results_CTL08A['intercept'], df_results_CTL04E['intercept']], axis = 1)
intercepts.columns = ['CTL08A', 'CTL04E']
intercepts.index = [i.split('C(Condition, Treatment(reference=\'DMSO\'))[T.')[1].replace(']', '') for i in intercepts.index]
params = model_CTL08A.params
mean_DMSO = params["Intercept"]
intercepts['CTL08A'] = intercepts['CTL08A']/ mean_DMSO * 100
params = model_CTL04E.params
mean_DMSO = params["Intercept"]
intercepts['CTL04E'] = intercepts['CTL04E']/ mean_DMSO * 100
intercepts
| CTL08A | CTL04E | |
|---|---|---|
| ANDR_AG | -0.782122 | -1.172067 |
| ANDR_INH | -1.378235 | -0.984255 |
| ARYL_AG | -1.193967 | -0.088054 |
| ARYL_INH | -1.096948 | -0.530394 |
| ESTR_AG | -1.851045 | 0.380626 |
| ESTR_INH | 0.049108 | 1.145418 |
| GC_AG | 0.108898 | NaN |
| GC_INH | -0.736219 | 0.416484 |
| LX_AG | -0.538977 | 0.533323 |
| LX_INH | -1.117992 | 0.272461 |
| RET_AG | -1.548628 | NaN |
| RET_INH | 0.549067 | 0.847269 |
| THYR_AG | -0.927813 | -0.337672 |
| THYR_INH | 0.037385 | 0.080701 |
fig, ax = plt.subplots(figsize = (4,7))
intercepts = intercepts.applymap(lambda x: f"{x:+.1f}%" if pd.notnull(x) else "")
intercepts = intercepts[pvals < 0.05].fillna('')
sns.heatmap(pvals, annot=intercepts, fmt='', cmap='Greens_r', cbar_kws={'label': 'p-value'}, vmin=0, vmax=0.05, ax = ax)
plt.title('Condition vs DMSO\n')
plt.savefig('../../../../endpoints_figures/endpoints_organoids_extent_OLS_test.png', dpi=300, bbox_inches='tight')
/tmp/ipykernel_1121090/1658638270.py:2: FutureWarning: DataFrame.applymap has been deprecated. Use DataFrame.map instead.
intercepts = intercepts.applymap(lambda x: f"{x:+.1f}%" if pd.notnull(x) else "")
Main contributor of variance for PC2
fig, ax = plt.subplots(1, 2, figsize=(20, 5))
for i, cond in enumerate(hormonal_conditions):
data = tot_df_morphological[(tot_df_morphological['Line'] == 'CTL08A') &
(tot_df_morphological['Condition'] == cond)]['eccentricity']
box = ax[0].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = tot_df_morphological[(tot_df_morphological['Condition'] == 'DMSO') &
(tot_df_morphological['Line'] == 'CTL08A')]['eccentricity'].median()
ax[0].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
for i, cond in enumerate(hormonal_conditions):
data = tot_df_morphological[(tot_df_morphological['Line'] == 'CTL04E') &
(tot_df_morphological['Condition'] == cond)]['eccentricity']
box = ax[1].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = tot_df_morphological[(tot_df_morphological['Condition'] == 'DMSO') &
(tot_df_morphological['Line'] == 'CTL04E')]['eccentricity'].median()
ax[1].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
_ = ax[0].set_xticks(range(len(hormonal_conditions)))
_ = ax[0].set_xticklabels(hormonal_conditions, rotation=90)
_ = ax[1].set_xticks(range(len(hormonal_conditions)))
_ = ax[1].set_xticklabels(hormonal_conditions, rotation=90)
ax[0].set_title('CTL08A')
ax[1].set_title('CTL04E')
ax[0].set_ylabel('eccentricity')
ax[1].set_ylabel('eccentricity')
plt.savefig('../../../../endpoints_figures/endpoints_eccentricity_all_nuclei.pdf', dpi=300, bbox_inches='tight')
plt.savefig('../../../../endpoints_figures/endpoints_eccentricity_all_nuclei.png', dpi=300, bbox_inches='tight')
fig, ax = plt.subplots(1, 2, figsize=(20, 5))
for i, cond in enumerate(hormonal_conditions):
data = grouped_df[(grouped_df['Line'] == 'CTL08A') &
(grouped_df['Condition'] == cond)]['eccentricity']
box = ax[0].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
# Add stripplot for CTL08A (single points per box)
dmso_median = grouped_df[(grouped_df['Condition'] == 'DMSO') &
(grouped_df['Line'] == 'CTL08A')]['eccentricity'].median()
ax[0].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=grouped_df[(grouped_df['Line'] == 'CTL08A') & (grouped_df['Condition'] == cond)],
y='eccentricity', x='Condition', order=[cond], color='black', alpha=0.5, jitter=False, ax=ax[0], size=8
)
for i, cond in enumerate(hormonal_conditions):
data = grouped_df[(grouped_df['Line'] == 'CTL04E') &
(grouped_df['Condition'] == cond)]['eccentricity']
box = ax[1].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = grouped_df[(grouped_df['Condition'] == 'DMSO') &
(grouped_df['Line'] == 'CTL04E')]['eccentricity'].median()
ax[1].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=grouped_df[(grouped_df['Line'] == 'CTL04E') & (grouped_df['Condition'] == cond)],
y='eccentricity', x='Condition', order=[cond], color='black', alpha=0.5, jitter=False, ax=ax[1], size=8
)
_ = ax[0].set_xticks(range(len(hormonal_conditions)))
_ = ax[0].set_xticklabels(hormonal_conditions, rotation=90)
_ = ax[1].set_xticks(range(len(hormonal_conditions)))
_ = ax[1].set_xticklabels(hormonal_conditions, rotation=90)
ax[0].set_title('CTL08A')
ax[1].set_title('CTL04E')
ax[0].set_ylabel('eccentricity')
ax[1].set_ylabel('eccentricity')
plt.savefig('../../../../endpoints_figures/endpoints_eccentricity_grouped.pdf', dpi=300, bbox_inches='tight')
plt.savefig('../../../../endpoints_figures/endpoints_eccentricity_grouped.png', dpi=300, bbox_inches='tight')
grouped_df_CTL08A = grouped_df[grouped_df['Line'] == 'CTL08A']
grouped_df_CTL08A['Condition'] = grouped_df_CTL08A['Condition'].astype('category')
model_CTL08A = smf.ols("eccentricity ~ C(Condition, Treatment(reference='DMSO'))",
data=grouped_df_CTL08A,
).fit()
print(model_CTL08A.summary())
OLS Regression Results
==============================================================================
Dep. Variable: eccentricity R-squared: 0.622
Model: OLS Adj. R-squared: 0.537
Method: Least Squares F-statistic: 7.391
Date: Tue, 28 Apr 2026 Prob (F-statistic): 8.35e-09
Time: 15:55:15 Log-Likelihood: 212.88
No. Observations: 78 AIC: -395.8
Df Residuals: 63 BIC: -360.4
Df Model: 14
Covariance Type: nonrobust
=========================================================================================================================
coef std err t P>|t| [0.025 0.975]
-------------------------------------------------------------------------------------------------------------------------
Intercept 0.6177 0.007 86.093 0.000 0.603 0.632
C(Condition, Treatment(reference='DMSO'))[T.ANDR_AG] 0.0265 0.010 2.613 0.011 0.006 0.047
C(Condition, Treatment(reference='DMSO'))[T.ANDR_INH] 0.0500 0.012 4.025 0.000 0.025 0.075
C(Condition, Treatment(reference='DMSO'))[T.ARYL_AG] 0.0298 0.009 3.219 0.002 0.011 0.048
C(Condition, Treatment(reference='DMSO'))[T.ARYL_INH] 0.0440 0.010 4.340 0.000 0.024 0.064
C(Condition, Treatment(reference='DMSO'))[T.ESTR_AG] 0.0534 0.011 4.707 0.000 0.031 0.076
C(Condition, Treatment(reference='DMSO'))[T.ESTR_INH] 0.0066 0.011 0.582 0.563 -0.016 0.029
C(Condition, Treatment(reference='DMSO'))[T.GC_AG] -0.0062 0.011 -0.550 0.584 -0.029 0.016
C(Condition, Treatment(reference='DMSO'))[T.GC_INH] 0.0116 0.011 1.086 0.281 -0.010 0.033
C(Condition, Treatment(reference='DMSO'))[T.LX_AG] 0.0247 0.010 2.438 0.018 0.004 0.045
C(Condition, Treatment(reference='DMSO'))[T.LX_INH] 0.0138 0.012 1.113 0.270 -0.011 0.039
C(Condition, Treatment(reference='DMSO'))[T.RET_AG] 0.0479 0.010 4.716 0.000 0.028 0.068
C(Condition, Treatment(reference='DMSO'))[T.RET_INH] -0.0066 0.010 -0.655 0.515 -0.027 0.014
C(Condition, Treatment(reference='DMSO'))[T.THYR_AG] 0.0148 0.011 1.394 0.168 -0.006 0.036
C(Condition, Treatment(reference='DMSO'))[T.THYR_INH] -0.0106 0.011 -0.998 0.322 -0.032 0.011
==============================================================================
Omnibus: 11.233 Durbin-Watson: 1.655
Prob(Omnibus): 0.004 Jarque-Bera (JB): 20.877
Skew: -0.449 Prob(JB): 2.93e-05
Kurtosis: 5.370 Cond. No. 15.0
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
/tmp/ipykernel_1121090/1012140979.py:2: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
grouped_df_CTL08A['Condition'] = grouped_df_CTL08A['Condition'].astype('category')
grouped_df_CTL04E = grouped_df[grouped_df['Line'] == 'CTL04E']
grouped_df_CTL04E['Condition'] = grouped_df_CTL04E['Condition'].astype('category')
model_CTL04E = smf.ols("eccentricity ~ C(Condition, Treatment(reference='DMSO'))",
data=grouped_df_CTL04E,
).fit()
print(model_CTL04E.summary())
OLS Regression Results
==============================================================================
Dep. Variable: eccentricity R-squared: 0.699
Model: OLS Adj. R-squared: 0.624
Method: Least Squares F-statistic: 9.303
Date: Tue, 28 Apr 2026 Prob (F-statistic): 6.47e-09
Time: 15:55:15 Log-Likelihood: 183.87
No. Observations: 61 AIC: -341.7
Df Residuals: 48 BIC: -314.3
Df Model: 12
Covariance Type: nonrobust
=========================================================================================================================
coef std err t P>|t| [0.025 0.975]
-------------------------------------------------------------------------------------------------------------------------
Intercept 0.6134 0.007 91.640 0.000 0.600 0.627
C(Condition, Treatment(reference='DMSO'))[T.ANDR_AG] 0.0365 0.009 3.855 0.000 0.017 0.056
C(Condition, Treatment(reference='DMSO'))[T.ANDR_INH] 0.0279 0.010 2.726 0.009 0.007 0.048
C(Condition, Treatment(reference='DMSO'))[T.ARYL_AG] 0.0062 0.009 0.722 0.474 -0.011 0.024
C(Condition, Treatment(reference='DMSO'))[T.ARYL_INH] 0.0093 0.009 1.072 0.289 -0.008 0.027
C(Condition, Treatment(reference='DMSO'))[T.ESTR_AG] -0.0094 0.010 -0.922 0.361 -0.030 0.011
C(Condition, Treatment(reference='DMSO'))[T.ESTR_INH] -0.0289 0.009 -3.346 0.002 -0.046 -0.012
C(Condition, Treatment(reference='DMSO'))[T.GC_INH] -0.0231 0.009 -2.668 0.010 -0.040 -0.006
C(Condition, Treatment(reference='DMSO'))[T.LX_AG] -0.0151 0.009 -1.678 0.100 -0.033 0.003
C(Condition, Treatment(reference='DMSO'))[T.LX_INH] -0.0109 0.009 -1.261 0.213 -0.028 0.006
C(Condition, Treatment(reference='DMSO'))[T.RET_INH] -0.0214 0.009 -2.266 0.028 -0.040 -0.002
C(Condition, Treatment(reference='DMSO'))[T.THYR_AG] 0.0056 0.009 0.652 0.517 -0.012 0.023
C(Condition, Treatment(reference='DMSO'))[T.THYR_INH] -0.0029 0.012 -0.251 0.803 -0.026 0.020
==============================================================================
Omnibus: 0.652 Durbin-Watson: 2.177
Prob(Omnibus): 0.722 Jarque-Bera (JB): 0.168
Skew: -0.022 Prob(JB): 0.920
Kurtosis: 3.253 Cond. No. 15.1
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
/tmp/ipykernel_1121090/2137971027.py:2: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
grouped_df_CTL04E['Condition'] = grouped_df_CTL04E['Condition'].astype('category')
resid_CTL08A = model_CTL08A.resid
stats.probplot(resid_CTL08A, dist="norm", plot=plt)
plt.show()
resid_CTL04E = model_CTL04E.resid
stats.probplot(resid_CTL04E, dist="norm", plot=plt)
plt.show()
pvals_CTL08A = model_CTL08A.pvalues[1:] # exclude intercept
corrected_pvals_CTL08A = multipletests(pvals_CTL08A, method='fdr_bh')[1]
df_results_CTL08A = pd.concat([model_CTL08A.params, pd.Series(corrected_pvals_CTL08A, index=model_CTL08A.params.index[1:])], axis = 1).iloc[1:]
df_results_CTL08A.columns = ['intercept', 'pvalue']
pvals_CTL04E = model_CTL04E.pvalues[1:] # exclude intercept
corrected_pvals_CTL04E = multipletests(pvals_CTL04E, method='fdr_bh')[1]
df_results_CTL04E = pd.concat([model_CTL04E.params, pd.Series(corrected_pvals_CTL04E, index=model_CTL04E.params.index[1:])], axis = 1).iloc[1:]
df_results_CTL04E.columns = ['intercept', 'pvalue']
pvals = pd.concat([df_results_CTL08A['pvalue'], df_results_CTL04E['pvalue']], axis = 1)
pvals.columns = ['CTL08A', 'CTL04E']
pvals.index = [i.split('C(Condition, Treatment(reference=\'DMSO\'))[T.')[1].replace(']', '') for i in pvals.index]
pvals
| CTL08A | CTL04E | |
|---|---|---|
| ANDR_AG | 0.026175 | 0.004128 |
| ANDR_INH | 0.000545 | 0.031130 |
| ARYL_AG | 0.005701 | 0.564293 |
| ARYL_INH | 0.000246 | 0.433723 |
| ESTR_AG | 0.000100 | 0.481559 |
| ESTR_INH | 0.584482 | 0.009591 |
| GC_AG | 0.584482 | NaN |
| GC_INH | 0.393980 | 0.031130 |
| LX_AG | 0.035222 | 0.199756 |
| LX_INH | 0.393980 | 0.365859 |
| RET_AG | 0.000100 | NaN |
| RET_INH | 0.584482 | 0.067244 |
| THYR_AG | 0.294518 | 0.564293 |
| THYR_INH | 0.409853 | 0.802613 |
intercepts = pd.concat([df_results_CTL08A['intercept'], df_results_CTL04E['intercept']], axis = 1)
intercepts.columns = ['CTL08A', 'CTL04E']
intercepts.index = [i.split('C(Condition, Treatment(reference=\'DMSO\'))[T.')[1].replace(']', '') for i in intercepts.index]
params = model_CTL08A.params
mean_DMSO = params["Intercept"]
intercepts['CTL08A'] = intercepts['CTL08A']/ mean_DMSO * 100
params = model_CTL04E.params
mean_DMSO = params["Intercept"]
intercepts['CTL04E'] = intercepts['CTL04E']/ mean_DMSO * 100
intercepts
| CTL08A | CTL04E | |
|---|---|---|
| ANDR_AG | 4.291810 | 5.948758 |
| ANDR_INH | 8.096875 | 4.543271 |
| ARYL_AG | 4.826548 | 1.016616 |
| ARYL_INH | 7.128947 | 1.509976 |
| ESTR_AG | 8.644100 | -1.536757 |
| ESTR_INH | 1.069257 | -4.713942 |
| GC_AG | -1.009511 | NaN |
| GC_INH | 1.871787 | -3.758465 |
| LX_AG | 4.004447 | -2.456410 |
| LX_INH | 2.238430 | -1.776391 |
| RET_AG | 7.746693 | NaN |
| RET_INH | -1.076113 | -3.496482 |
| THYR_AG | 2.401156 | 0.919046 |
| THYR_INH | -1.719633 | -0.475073 |
fig, ax = plt.subplots(figsize = (4,7))
intercepts = intercepts.applymap(lambda x: f"{x:+.1f}%" if pd.notnull(x) else "")
intercepts = intercepts[pvals < 0.05].fillna('')
sns.heatmap(pvals, annot=intercepts, fmt='', cmap='Greens_r', cbar_kws={'label': 'p-value'}, vmin=0, vmax=0.05, ax = ax)
plt.title('Condition vs DMSO\n')
plt.savefig('../../../../endpoints_figures/endpoints_organoids_eccentricity_OLS_test.png', dpi=300, bbox_inches='tight')
/tmp/ipykernel_1121090/3100479939.py:2: FutureWarning: DataFrame.applymap has been deprecated. Use DataFrame.map instead.
intercepts = intercepts.applymap(lambda x: f"{x:+.1f}%" if pd.notnull(x) else "")
Main contributor of variance for PC3
fig, ax = plt.subplots(1, 2, figsize=(20, 5))
for i, cond in enumerate(hormonal_conditions):
data = tot_df_morphological[(tot_df_morphological['Line'] == 'CTL08A') &
(tot_df_morphological['Condition'] == cond)]['orientation']
box = ax[0].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = tot_df_morphological[(tot_df_morphological['Condition'] == 'DMSO') &
(tot_df_morphological['Line'] == 'CTL08A')]['orientation'].median()
ax[0].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
for i, cond in enumerate(hormonal_conditions):
data = tot_df_morphological[(tot_df_morphological['Line'] == 'CTL04E') &
(tot_df_morphological['Condition'] == cond)]['orientation']
box = ax[1].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = tot_df_morphological[(tot_df_morphological['Condition'] == 'DMSO') &
(tot_df_morphological['Line'] == 'CTL04E')]['orientation'].median()
ax[1].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
_ = ax[0].set_xticks(range(len(hormonal_conditions)))
_ = ax[0].set_xticklabels(hormonal_conditions, rotation=90)
_ = ax[1].set_xticks(range(len(hormonal_conditions)))
_ = ax[1].set_xticklabels(hormonal_conditions, rotation=90)
ax[0].set_title('CTL08A')
ax[1].set_title('CTL04E')
ax[0].set_ylabel('orientation')
ax[1].set_ylabel('orientation')
plt.savefig('../../../../endpoints_figures/endpoints_orientation_all_nuclei.pdf', dpi=300, bbox_inches='tight')
plt.savefig('../../../../endpoints_figures/endpoints_orientation_all_nuclei.png', dpi=300, bbox_inches='tight')
fig, ax = plt.subplots(1, 2, figsize=(20, 5))
for i, cond in enumerate(hormonal_conditions):
data = grouped_df[(grouped_df['Line'] == 'CTL08A') &
(grouped_df['Condition'] == cond)]['orientation']
box = ax[0].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
# Add stripplot for CTL08A (single points per box)
dmso_median = grouped_df[(grouped_df['Condition'] == 'DMSO') &
(grouped_df['Line'] == 'CTL08A')]['orientation'].median()
ax[0].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=grouped_df[(grouped_df['Line'] == 'CTL08A') & (grouped_df['Condition'] == cond)],
y='orientation', x='Condition', order=[cond], color='black', alpha=0.5, jitter=False, ax=ax[0], size=8
)
for i, cond in enumerate(hormonal_conditions):
data = grouped_df[(grouped_df['Line'] == 'CTL04E') &
(grouped_df['Condition'] == cond)]['orientation']
box = ax[1].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = grouped_df[(grouped_df['Condition'] == 'DMSO') &
(grouped_df['Line'] == 'CTL04E')]['orientation'].median()
ax[1].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=grouped_df[(grouped_df['Line'] == 'CTL04E') & (grouped_df['Condition'] == cond)],
y='orientation', x='Condition', order=[cond], color='black', alpha=0.5, jitter=False, ax=ax[1], size=8
)
_ = ax[0].set_xticks(range(len(hormonal_conditions)))
_ = ax[0].set_xticklabels(hormonal_conditions, rotation=90)
_ = ax[1].set_xticks(range(len(hormonal_conditions)))
_ = ax[1].set_xticklabels(hormonal_conditions, rotation=90)
ax[0].set_title('CTL08A')
ax[1].set_title('CTL04E')
ax[0].set_ylabel('orientation')
ax[1].set_ylabel('orientation')
plt.savefig('../../../../endpoints_figures/endpoints_orientation_grouped.pdf', dpi=300, bbox_inches='tight')
plt.savefig('../../../../endpoints_figures/endpoints_orientation_grouped.png', dpi=300, bbox_inches='tight')
tot_df_morphological['area_um2'] = tot_df_morphological['area'] * (0.325 ** 2) # Convert area to um^2
fig, ax = plt.subplots(1, 2, figsize=(20, 5))
for i, cond in enumerate(hormonal_conditions):
data = tot_df_morphological[(tot_df_morphological['Line'] == 'CTL08A') &
(tot_df_morphological['Condition'] == cond)]['area_um2']
box = ax[0].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = tot_df_morphological[(tot_df_morphological['Condition'] == 'DMSO') &
(tot_df_morphological['Line'] == 'CTL08A')]['area_um2'].median()
ax[0].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
for i, cond in enumerate(hormonal_conditions):
data = tot_df_morphological[(tot_df_morphological['Line'] == 'CTL04E') &
(tot_df_morphological['Condition'] == cond)]['area_um2']
box = ax[1].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = tot_df_morphological[(tot_df_morphological['Condition'] == 'DMSO') &
(tot_df_morphological['Line'] == 'CTL04E')]['area_um2'].median()
ax[1].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
_ = ax[0].set_xticks(range(len(hormonal_conditions)))
_ = ax[0].set_xticklabels(hormonal_conditions, rotation=90)
_ = ax[1].set_xticks(range(len(hormonal_conditions)))
_ = ax[1].set_xticklabels(hormonal_conditions, rotation=90)
ax[0].set_title('CTL08A')
ax[1].set_title('CTL04E')
ax[0].set_ylabel('area_um2')
ax[1].set_ylabel('area_um2')
plt.savefig('../../../../endpoints_figures/endpoints_area_um2_all_nuclei.pdf', dpi=300, bbox_inches='tight')
plt.savefig('../../../../endpoints_figures/endpoints_area_um2_all_nuclei.png', dpi=300, bbox_inches='tight')
grouped_df['area_um2'] = grouped_df['area'] * (0.325 ** 2) # Convert area to um^2
fig, ax = plt.subplots(1, 2, figsize=(20, 5))
for i, cond in enumerate(hormonal_conditions):
data = grouped_df[(grouped_df['Line'] == 'CTL08A') &
(grouped_df['Condition'] == cond)]['area_um2']
box = ax[0].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
# Add stripplot for CTL08A (single points per box)
dmso_median = grouped_df[(grouped_df['Condition'] == 'DMSO') &
(grouped_df['Line'] == 'CTL08A')]['area_um2'].median()
ax[0].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=grouped_df[(grouped_df['Line'] == 'CTL08A')],
y='area_um2', x='Condition', order=hormonal_conditions, color='black', alpha=0.5, jitter=False, ax=ax[0], size=8
)
for i, cond in enumerate(hormonal_conditions):
data = grouped_df[(grouped_df['Line'] == 'CTL04E') &
(grouped_df['Condition'] == cond)]['area_um2']
box = ax[1].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = grouped_df[(grouped_df['Condition'] == 'DMSO') &
(grouped_df['Line'] == 'CTL04E')]['area_um2'].median()
ax[1].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=grouped_df[(grouped_df['Line'] == 'CTL04E')],
y='area_um2', x='Condition', order=hormonal_conditions, color='black', alpha=0.5, jitter=False, ax=ax[1], size=8
)
_ = ax[0].set_xticks(range(len(hormonal_conditions)))
_ = ax[0].set_xticklabels(hormonal_conditions, rotation=90)
_ = ax[1].set_xticks(range(len(hormonal_conditions)))
_ = ax[1].set_xticklabels(hormonal_conditions, rotation=90)
ax[0].set_title('CTL08A')
ax[1].set_title('CTL04E')
ax[0].set_ylabel('Nuclei area (um2)')
ax[1].set_ylabel('Nuclei area (um2)')
plt.savefig('../../../../endpoints_figures/endpoints_area_um2_grouped.pdf', dpi=300, bbox_inches='tight')
plt.savefig('../../../../endpoints_figures/endpoints_area_um2_grouped.png', dpi=300, bbox_inches='tight')
grouped_df_CTL08A = grouped_df[grouped_df['Line'] == 'CTL08A']
grouped_df_CTL08A['Condition'] = grouped_df_CTL08A['Condition'].astype('category')
grouped_df_CTL08A["log_area"] = np.log(grouped_df_CTL08A["area_um2"])
grouped_df_CTL08A['log_area'].hist(bins = 10)
model_CTL08A = smf.ols("log_area ~ C(Condition, Treatment(reference='DMSO'))",
data=grouped_df_CTL08A,
).fit()
print(model_CTL08A.summary())
OLS Regression Results
==============================================================================
Dep. Variable: log_area R-squared: 0.590
Model: OLS Adj. R-squared: 0.499
Method: Least Squares F-statistic: 6.484
Date: Tue, 28 Apr 2026 Prob (F-statistic): 7.59e-08
Time: 15:56:45 Log-Likelihood: 19.126
No. Observations: 78 AIC: -8.251
Df Residuals: 63 BIC: 27.10
Df Model: 14
Covariance Type: nonrobust
=========================================================================================================================
coef std err t P>|t| [0.025 0.975]
-------------------------------------------------------------------------------------------------------------------------
Intercept 3.4752 0.086 40.402 0.000 3.303 3.647
C(Condition, Treatment(reference='DMSO'))[T.ANDR_AG] 0.1418 0.122 1.165 0.248 -0.101 0.385
C(Condition, Treatment(reference='DMSO'))[T.ANDR_INH] 0.4025 0.149 2.701 0.009 0.105 0.700
C(Condition, Treatment(reference='DMSO'))[T.ARYL_AG] 0.2294 0.111 2.065 0.043 0.007 0.451
C(Condition, Treatment(reference='DMSO'))[T.ARYL_INH] 0.2732 0.122 2.246 0.028 0.030 0.516
C(Condition, Treatment(reference='DMSO'))[T.ESTR_AG] 0.2892 0.136 2.127 0.037 0.017 0.561
C(Condition, Treatment(reference='DMSO'))[T.ESTR_INH] 0.2084 0.136 1.532 0.130 -0.063 0.480
C(Condition, Treatment(reference='DMSO'))[T.GC_AG] 0.1330 0.136 0.978 0.332 -0.139 0.405
C(Condition, Treatment(reference='DMSO'))[T.GC_INH] 0.2446 0.128 1.917 0.060 -0.010 0.500
C(Condition, Treatment(reference='DMSO'))[T.LX_AG] 0.2182 0.122 1.794 0.078 -0.025 0.461
C(Condition, Treatment(reference='DMSO'))[T.LX_INH] 0.0831 0.149 0.558 0.579 -0.215 0.381
C(Condition, Treatment(reference='DMSO'))[T.RET_AG] 0.9205 0.122 7.567 0.000 0.677 1.164
C(Condition, Treatment(reference='DMSO'))[T.RET_INH] 0.0280 0.122 0.230 0.819 -0.215 0.271
C(Condition, Treatment(reference='DMSO'))[T.THYR_AG] 0.0510 0.128 0.400 0.690 -0.204 0.306
C(Condition, Treatment(reference='DMSO'))[T.THYR_INH] 0.0367 0.128 0.288 0.774 -0.218 0.292
==============================================================================
Omnibus: 29.224 Durbin-Watson: 1.338
Prob(Omnibus): 0.000 Jarque-Bera (JB): 292.528
Skew: 0.536 Prob(JB): 3.01e-64
Kurtosis: 12.427 Cond. No. 15.0
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
/tmp/ipykernel_1121090/2562141296.py:2: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
grouped_df_CTL08A['Condition'] = grouped_df_CTL08A['Condition'].astype('category')
/tmp/ipykernel_1121090/2562141296.py:3: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
grouped_df_CTL08A["log_area"] = np.log(grouped_df_CTL08A["area_um2"])
grouped_df_CTL04E = grouped_df[grouped_df['Line'] == 'CTL04E']
grouped_df_CTL04E['Condition'] = grouped_df_CTL04E['Condition'].astype('category')
grouped_df_CTL04E["log_area"] = np.log(grouped_df_CTL04E["area_um2"])
grouped_df_CTL04E['log_area'].hist(bins = 10)
model_CTL04E = smf.ols("log_area ~ C(Condition, Treatment(reference='DMSO'))",
data=grouped_df_CTL04E,
).fit()
print(model_CTL04E.summary())
OLS Regression Results
==============================================================================
Dep. Variable: log_area R-squared: 0.709
Model: OLS Adj. R-squared: 0.636
Method: Least Squares F-statistic: 9.730
Date: Tue, 28 Apr 2026 Prob (F-statistic): 3.22e-09
Time: 15:56:45 Log-Likelihood: 67.975
No. Observations: 61 AIC: -110.0
Df Residuals: 48 BIC: -82.51
Df Model: 12
Covariance Type: nonrobust
=========================================================================================================================
coef std err t P>|t| [0.025 0.975]
-------------------------------------------------------------------------------------------------------------------------
Intercept 3.5808 0.045 80.013 0.000 3.491 3.671
C(Condition, Treatment(reference='DMSO'))[T.ANDR_AG] 0.1083 0.063 1.712 0.093 -0.019 0.236
C(Condition, Treatment(reference='DMSO'))[T.ANDR_INH] 0.1091 0.068 1.596 0.117 -0.028 0.247
C(Condition, Treatment(reference='DMSO'))[T.ARYL_AG] -0.1309 0.058 -2.266 0.028 -0.247 -0.015
C(Condition, Treatment(reference='DMSO'))[T.ARYL_INH] 0.1562 0.058 2.703 0.009 0.040 0.272
C(Condition, Treatment(reference='DMSO'))[T.ESTR_AG] 0.0240 0.068 0.350 0.728 -0.113 0.161
C(Condition, Treatment(reference='DMSO'))[T.ESTR_INH] -0.0737 0.058 -1.275 0.208 -0.190 0.042
C(Condition, Treatment(reference='DMSO'))[T.GC_INH] -0.1863 0.058 -3.224 0.002 -0.302 -0.070
C(Condition, Treatment(reference='DMSO'))[T.LX_AG] -0.1903 0.060 -3.169 0.003 -0.311 -0.070
C(Condition, Treatment(reference='DMSO'))[T.LX_INH] -0.1523 0.058 -2.636 0.011 -0.268 -0.036
C(Condition, Treatment(reference='DMSO'))[T.RET_INH] -0.1244 0.063 -1.966 0.055 -0.252 0.003
C(Condition, Treatment(reference='DMSO'))[T.THYR_AG] -0.0581 0.058 -1.006 0.320 -0.174 0.058
C(Condition, Treatment(reference='DMSO'))[T.THYR_INH] 0.2152 0.078 2.776 0.008 0.059 0.371
==============================================================================
Omnibus: 5.053 Durbin-Watson: 2.590
Prob(Omnibus): 0.080 Jarque-Bera (JB): 3.099
Skew: -0.359 Prob(JB): 0.212
Kurtosis: 2.161 Cond. No. 15.1
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
/tmp/ipykernel_1121090/4157921110.py:2: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
grouped_df_CTL04E['Condition'] = grouped_df_CTL04E['Condition'].astype('category')
/tmp/ipykernel_1121090/4157921110.py:3: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
grouped_df_CTL04E["log_area"] = np.log(grouped_df_CTL04E["area_um2"])
resid_CTL08A = model_CTL08A.resid
stats.probplot(resid_CTL08A, dist="norm", plot=plt)
plt.show()
resid_CTL04E = model_CTL04E.resid
stats.probplot(resid_CTL04E, dist="norm", plot=plt)
plt.show()
pvals_CTL08A = model_CTL08A.pvalues[1:] # exclude intercept
corrected_pvals_CTL08A = multipletests(pvals_CTL08A, method='fdr_bh')[1]
df_results_CTL08A = pd.concat([model_CTL08A.params, pd.Series(corrected_pvals_CTL08A, index=model_CTL08A.params.index[1:])], axis = 1).iloc[1:]
df_results_CTL08A.columns = ['intercept', 'pvalue']
pvals_CTL04E = model_CTL04E.pvalues[1:] # exclude intercept
corrected_pvals_CTL04E = multipletests(pvals_CTL04E, method='fdr_bh')[1]
df_results_CTL04E = pd.concat([model_CTL04E.params, pd.Series(corrected_pvals_CTL04E, index=model_CTL04E.params.index[1:])], axis = 1).iloc[1:]
df_results_CTL04E.columns = ['intercept', 'pvalue']
pvals = pd.concat([df_results_CTL08A['pvalue'], df_results_CTL04E['pvalue']], axis = 1)
pvals.columns = ['CTL08A', 'CTL04E']
pvals.index = [i.split('C(Condition, Treatment(reference=\'DMSO\'))[T.')[1].replace(']', '') for i in pvals.index]
pvals
| CTL08A | CTL04E | |
|---|---|---|
| ANDR_AG | 3.861730e-01 | 0.140144 |
| ANDR_INH | 6.201731e-02 | 0.155963 |
| ARYL_AG | 1.204013e-01 | 0.055995 |
| ARYL_INH | 1.204013e-01 | 0.027070 |
| ESTR_AG | 1.204013e-01 | 0.727503 |
| ESTR_INH | 2.282874e-01 | 0.250067 |
| GC_AG | 4.645990e-01 | NaN |
| GC_INH | 1.393849e-01 | 0.015985 |
| LX_AG | 1.553794e-01 | 0.015985 |
| LX_INH | 7.368958e-01 | 0.027070 |
| RET_AG | 2.860717e-09 | NaN |
| RET_INH | 8.188953e-01 | 0.094554 |
| THYR_AG | 8.055180e-01 | 0.348721 |
| THYR_INH | 8.188953e-01 | 0.027070 |
intercepts = pd.concat([df_results_CTL08A['intercept'], df_results_CTL04E['intercept']], axis = 1)
intercepts.columns = ['CTL08A', 'CTL04E']
intercepts.index = [i.split('C(Condition, Treatment(reference=\'DMSO\'))[T.')[1].replace(']', '') for i in intercepts.index]
intercepts = (np.exp(intercepts) - 1) * 100
intercepts
| CTL08A | CTL04E | |
|---|---|---|
| ANDR_AG | 15.230298 | 11.441127 |
| ANDR_INH | 49.550300 | 11.530624 |
| ARYL_AG | 25.779160 | -12.271330 |
| ARYL_INH | 31.417438 | 16.903754 |
| ESTR_AG | 33.541879 | 2.424938 |
| ESTR_INH | 23.170375 | -7.102512 |
| GC_AG | 14.224804 | NaN |
| GC_INH | 27.712485 | -16.995242 |
| LX_AG | 24.379871 | -17.325295 |
| LX_INH | 8.664554 | -14.124428 |
| RET_AG | 151.044298 | NaN |
| RET_INH | 2.836367 | -11.697077 |
| THYR_AG | 5.236901 | -5.644258 |
| THYR_INH | 3.741964 | 24.006274 |
fig, ax = plt.subplots(figsize = (4,7))
intercepts = intercepts.applymap(lambda x: f"{x:+.1f}%" if pd.notnull(x) else "")
intercepts = intercepts[pvals < 0.05].fillna('')
sns.heatmap(pvals, annot=intercepts, fmt='', cmap='Greens_r', cbar_kws={'label': 'p-value'}, vmin=0, vmax=0.05, ax = ax)
plt.title('Condition vs DMSO\n')
plt.savefig('../../../../endpoints_figures/endpoints_organoids_nuclei_area_OLS_test.png', dpi=300, bbox_inches='tight')
/tmp/ipykernel_1121090/2973917183.py:2: FutureWarning: DataFrame.applymap has been deprecated. Use DataFrame.map instead.
intercepts = intercepts.applymap(lambda x: f"{x:+.1f}%" if pd.notnull(x) else "")
organoid_areas = pd.read_csv('/group/testa/Project/EndPoints/TPSSU/analysis/organoids_area.csv', index_col=0)
organoid_areas
| area | |
|---|---|
| 20240424_manuel_lessi_0141_ScanRegion1_rep_0 | 48618374 |
| 20240424_manuel_lessi_0131_ScanRegion0_rep_2 | 36008220 |
| 20240424_manuel_lessi_0133_ScanRegion4_rep_0 | 8422522 |
| 20240424_manuel_lessi_0143_ScanRegion2_rep_1 | 61481135 |
| 20240424_manuel_lessi_0147_ScanRegion0_rep_1 | 162545379 |
| ... | ... |
| 20240424_manuel_lessi_0129_ScanRegion1_rep_0 | 26572184 |
| 20240424_manuel_lessi_0129_ScanRegion0_rep_0 | 9292198 |
| 20240424_manuel_lessi_0142_ScanRegion1_rep_2 | 38017446 |
| 20240424_manuel_lessi_0129_ScanRegion2_rep_1 | 29459387 |
| 20240424_manuel_lessi_0134_ScanRegion4_rep_1 | 22517768 |
280 rows × 1 columns
organoid_areas['ImageName_ScanRegion'] = organoid_areas.reset_index()['index'].apply(lambda x: '_'.join(x.split('_')[0:5])).values
organoid_areas['Condition_Line'] = organoid_areas['ImageName_ScanRegion'].map(sample_dict)
organoid_areas['Line'] = organoid_areas['Condition_Line'].apply(lambda x: x.split('_')[-1] if pd.notnull(x) else x)
organoid_areas['Condition'] = organoid_areas['Condition_Line'].str.replace('_CTL08A', '', regex=True)
organoid_areas['Condition'] = organoid_areas['Condition'].str.replace('_CTL04E', '', regex=True)
organoid_areas = organoid_areas[organoid_areas['Condition'].isin(hormonal_conditions)]
organoid_areas
| area | ImageName_ScanRegion | Condition_Line | Line | Condition | |
|---|---|---|---|---|---|
| 20240424_manuel_lessi_0131_ScanRegion0_rep_2 | 36008220 | 20240424_manuel_lessi_0131_ScanRegion0 | GC_INH_CTL04E | CTL04E | GC_INH |
| 20240424_manuel_lessi_0133_ScanRegion4_rep_0 | 8422522 | 20240424_manuel_lessi_0133_ScanRegion4 | RET_AG_CTL08A | CTL08A | RET_AG |
| 20240424_manuel_lessi_0140_ScanRegion4_rep_2 | 32680044 | 20240424_manuel_lessi_0140_ScanRegion4 | THYR_INH_CTL08A | CTL08A | THYR_INH |
| 20240424_manuel_lessi_0140_ScanRegion0_rep_1 | 36008064 | 20240424_manuel_lessi_0140_ScanRegion0 | GC_INH_CTL08A | CTL08A | GC_INH |
| 20240424_manuel_lessi_0138_ScanRegion3_rep_1 | 16957648 | 20240424_manuel_lessi_0138_ScanRegion3 | ARYL_AG_CTL08A | CTL08A | ARYL_AG |
| ... | ... | ... | ... | ... | ... |
| 20240424_manuel_lessi_0131_ScanRegion4_rep_1 | 35725975 | 20240424_manuel_lessi_0131_ScanRegion4 | THYR_AG_CTL04E | CTL04E | THYR_AG |
| 20240424_manuel_lessi_0140_ScanRegion3_rep_0 | 46296832 | 20240424_manuel_lessi_0140_ScanRegion3 | THYR_AG_CTL04E | CTL04E | THYR_AG |
| 20240424_manuel_lessi_0128_ScanRegion4_rep_0 | 42198648 | 20240424_manuel_lessi_0128_ScanRegion4 | ESTR_INH_CTL08A | CTL08A | ESTR_INH |
| 20240424_manuel_lessi_0129_ScanRegion1_rep_0 | 26572184 | 20240424_manuel_lessi_0129_ScanRegion1 | ARYL_INH_CTL08A | CTL08A | ARYL_INH |
| 20240424_manuel_lessi_0129_ScanRegion2_rep_1 | 29459387 | 20240424_manuel_lessi_0129_ScanRegion2 | ARYL_INH_CTL04E | CTL04E | ARYL_INH |
146 rows × 5 columns
organoid_areas['area_um2'] = organoid_areas['area'] * (0.325 ** 2) # Convert area to um^2
/tmp/ipykernel_1121090/172599718.py:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy organoid_areas['area_um2'] = organoid_areas['area'] * (0.325 ** 2) # Convert area to um^2
summed_area = tot_df_morphological[['ImageName_ScanRegion_Rep', 'area_um2']].groupby('ImageName_ScanRegion_Rep').sum()
organoid_areas['tot_nuclei_areas'] = summed_area
/tmp/ipykernel_1121090/1334222756.py:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy organoid_areas['tot_nuclei_areas'] = summed_area
organoid_areas['nuclear_area'] = organoid_areas['tot_nuclei_areas'] / organoid_areas['area_um2'] * 100
/tmp/ipykernel_1121090/3125954352.py:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy organoid_areas['nuclear_area'] = organoid_areas['tot_nuclei_areas'] / organoid_areas['area_um2'] * 100
organoid_areas
| area | ImageName_ScanRegion | Condition_Line | Line | Condition | area_um2 | tot_nuclei_areas | nuclear_area | |
|---|---|---|---|---|---|---|---|---|
| 20240424_manuel_lessi_0131_ScanRegion0_rep_2 | 36008220 | 20240424_manuel_lessi_0131_ScanRegion0 | GC_INH_CTL04E | CTL04E | GC_INH | 3.803368e+06 | 1.145734e+06 | 30.124186 |
| 20240424_manuel_lessi_0133_ScanRegion4_rep_0 | 8422522 | 20240424_manuel_lessi_0133_ScanRegion4 | RET_AG_CTL08A | CTL08A | RET_AG | 8.896289e+05 | 2.439548e+05 | 27.422083 |
| 20240424_manuel_lessi_0140_ScanRegion4_rep_2 | 32680044 | 20240424_manuel_lessi_0140_ScanRegion4 | THYR_INH_CTL08A | CTL08A | THYR_INH | 3.451830e+06 | 1.302871e+06 | 37.744374 |
| 20240424_manuel_lessi_0140_ScanRegion0_rep_1 | 36008064 | 20240424_manuel_lessi_0140_ScanRegion0 | GC_INH_CTL08A | CTL08A | GC_INH | 3.803352e+06 | 1.457129e+06 | 38.311710 |
| 20240424_manuel_lessi_0138_ScanRegion3_rep_1 | 16957648 | 20240424_manuel_lessi_0138_ScanRegion3 | ARYL_AG_CTL08A | CTL08A | ARYL_AG | 1.791152e+06 | 6.871573e+05 | 38.363994 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 20240424_manuel_lessi_0131_ScanRegion4_rep_1 | 35725975 | 20240424_manuel_lessi_0131_ScanRegion4 | THYR_AG_CTL04E | CTL04E | THYR_AG | 3.773556e+06 | 1.162948e+06 | 30.818358 |
| 20240424_manuel_lessi_0140_ScanRegion3_rep_0 | 46296832 | 20240424_manuel_lessi_0140_ScanRegion3 | THYR_AG_CTL04E | CTL04E | THYR_AG | 4.890103e+06 | 1.751093e+06 | 35.808912 |
| 20240424_manuel_lessi_0128_ScanRegion4_rep_0 | 42198648 | 20240424_manuel_lessi_0128_ScanRegion4 | ESTR_INH_CTL08A | CTL08A | ESTR_INH | 4.457232e+06 | 1.589967e+06 | 35.671624 |
| 20240424_manuel_lessi_0129_ScanRegion1_rep_0 | 26572184 | 20240424_manuel_lessi_0129_ScanRegion1 | ARYL_INH_CTL08A | CTL08A | ARYL_INH | 2.806687e+06 | 1.140692e+06 | 40.641951 |
| 20240424_manuel_lessi_0129_ScanRegion2_rep_1 | 29459387 | 20240424_manuel_lessi_0129_ScanRegion2 | ARYL_INH_CTL04E | CTL04E | ARYL_INH | 3.111648e+06 | 1.188860e+06 | 38.206776 |
146 rows × 8 columns
fig, ax = plt.subplots(1, 2, figsize=(20, 5))
for i, cond in enumerate(hormonal_conditions):
data = organoid_areas[(organoid_areas['Line'] == 'CTL08A') &
(organoid_areas['Condition'] == cond)]['nuclear_area']
box = ax[0].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
# Add stripplot for CTL08A (single points per box)
dmso_median = organoid_areas[(organoid_areas['Condition'] == 'DMSO') &
(organoid_areas['Line'] == 'CTL08A')]['nuclear_area'].median()
ax[0].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=organoid_areas[(organoid_areas['Line'] == 'CTL08A')],
y='nuclear_area', x='Condition', order=hormonal_conditions, color='black', alpha=0.5, jitter=False, ax=ax[0], size=8
)
for i, cond in enumerate(hormonal_conditions):
data = organoid_areas[(organoid_areas['Line'] == 'CTL04E') &
(organoid_areas['Condition'] == cond)]['nuclear_area']
box = ax[1].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = organoid_areas[(organoid_areas['Condition'] == 'DMSO') &
(organoid_areas['Line'] == 'CTL04E')]['nuclear_area'].median()
ax[1].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=organoid_areas[(organoid_areas['Line'] == 'CTL04E')],
y='nuclear_area', x='Condition', order=hormonal_conditions, color='black', alpha=0.5, jitter=False, ax=ax[1], size=8
)
_ = ax[0].set_xticks(range(len(hormonal_conditions)))
_ = ax[0].set_xticklabels(hormonal_conditions, rotation=90)
_ = ax[1].set_xticks(range(len(hormonal_conditions)))
_ = ax[1].set_xticklabels(hormonal_conditions, rotation=90)
ax[0].set_title('CTL08A')
ax[1].set_title('CTL04E')
ax[0].set_ylabel('nuclear_area')
ax[1].set_ylabel('nuclear_area')
Text(0, 0.5, 'nuclear_area')
measurements_files = glob.glob("/group/testa/Project/EndPoints/TPSSU/analysis/measurements/*.csv")
measurements_files_mix_1 = [f for f in measurements_files if any(name in f for name in mix_1_names)]
tot_df_mix1_ch2 = pd.DataFrame()
measurements_files_mix_1_ch2 = [f for f in measurements_files_mix_1 if 'channel_2' in f]
for file in measurements_files_mix_1_ch2:
print(file)
df = pd.read_csv(file, index_col=0)
df['ImageName'] = file.split("/")[-1].split(".")[0]
print(df.shape)
tot_df_mix1_ch2 = pd.concat([tot_df_mix1_ch2, df], axis=0)
/group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0129_ScanRegion3_rep_1_channel_2_measures.csv (14032, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion2_rep_0_channel_2_measures.csv (36257, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion3_rep_1_channel_2_measures.csv (29165, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0133_ScanRegion2_rep_0_channel_2_measures.csv (28234, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0129_ScanRegion1_rep_2_channel_2_measures.csv (5186, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion2_rep_1_channel_2_measures.csv (30598, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0129_ScanRegion0_rep_0_channel_2_measures.csv (4420, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0133_ScanRegion4_rep_0_channel_2_measures.csv (5637, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0128_ScanRegion5_rep_2_channel_2_measures.csv (44878, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0128_ScanRegion2_rep_1_channel_2_measures.csv (25453, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion5_rep_0_channel_2_measures.csv (14547, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0132_ScanRegion2_rep_0_channel_2_measures.csv (65200, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion4_rep_1_channel_2_measures.csv (18423, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0129_ScanRegion0_rep_2_channel_2_measures.csv (12038, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0131_ScanRegion0_rep_1_channel_2_measures.csv (52451, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0133_ScanRegion0_rep_0_channel_2_measures.csv (69681, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0130_ScanRegion3_rep_0_channel_2_measures.csv (60277, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion7_rep_0_channel_2_measures.csv (36423, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0130_ScanRegion2_rep_1_channel_2_measures.csv (54724, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0132_ScanRegion3_rep_2_channel_2_measures.csv (48396, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0128_ScanRegion1_rep_0_channel_2_measures.csv (18479, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0132_ScanRegion5_rep_0_channel_2_measures.csv (61473, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0129_ScanRegion3_rep_2_channel_2_measures.csv (62393, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion5_rep_2_channel_2_measures.csv (27998, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion4_rep_0_channel_2_measures.csv (16418, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion0_rep_0_channel_2_measures.csv (54097, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0130_ScanRegion0_rep_1_channel_2_measures.csv (19128, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0130_ScanRegion2_rep_2_channel_2_measures.csv (7446, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0132_ScanRegion0_rep_0_channel_2_measures.csv (6943, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0130_ScanRegion3_rep_2_channel_2_measures.csv (44660, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0130_ScanRegion2_rep_0_channel_2_measures.csv (6134, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0131_ScanRegion2_rep_0_channel_2_measures.csv (43655, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0129_ScanRegion5_rep_0_channel_2_measures.csv (55824, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0131_ScanRegion4_rep_0_channel_2_measures.csv (43161, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion4_rep_2_channel_2_measures.csv (26186, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0132_ScanRegion5_rep_2_channel_2_measures.csv (42766, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0129_ScanRegion1_rep_0_channel_2_measures.csv (32479, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0133_ScanRegion0_rep_2_channel_2_measures.csv (46684, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0129_ScanRegion1_rep_1_channel_2_measures.csv (7889, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion7_rep_1_channel_2_measures.csv (1, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0133_ScanRegion3_rep_1_channel_2_measures.csv (4878, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion5_rep_1_channel_2_measures.csv (24682, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0128_ScanRegion3_rep_1_channel_2_measures.csv (31993, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion3_rep_2_channel_2_measures.csv (48939, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0129_ScanRegion4_rep_2_channel_2_measures.csv (1405, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion0_rep_2_channel_2_measures.csv (50003, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0130_ScanRegion4_rep_1_channel_2_measures.csv (26358, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0128_ScanRegion1_rep_1_channel_2_measures.csv (4685, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0133_ScanRegion0_rep_1_channel_2_measures.csv (42864, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0129_ScanRegion4_rep_1_channel_2_measures.csv (12551, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0132_ScanRegion1_rep_0_channel_2_measures.csv (128250, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0128_ScanRegion2_rep_2_channel_2_measures.csv (68825, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0129_ScanRegion0_rep_1_channel_2_measures.csv (10615, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion2_rep_2_channel_2_measures.csv (54944, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0129_ScanRegion2_rep_1_channel_2_measures.csv (32605, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0129_ScanRegion2_rep_0_channel_2_measures.csv (23699, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0131_ScanRegion3_rep_1_channel_2_measures.csv (20919, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0131_ScanRegion4_rep_2_channel_2_measures.csv (33055, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0132_ScanRegion3_rep_0_channel_2_measures.csv (70503, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion1_rep_0_channel_2_measures.csv (12349, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0130_ScanRegion1_rep_1_channel_2_measures.csv (30782, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion6_rep_0_channel_2_measures.csv (22787, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0128_ScanRegion4_rep_0_channel_2_measures.csv (42538, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0128_ScanRegion5_rep_1_channel_2_measures.csv (31370, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0129_ScanRegion3_rep_0_channel_2_measures.csv (4465, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion0_rep_1_channel_2_measures.csv (24746, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0133_ScanRegion1_rep_1_channel_2_measures.csv (5061, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0131_ScanRegion5_rep_2_channel_2_measures.csv (45127, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion1_rep_1_channel_2_measures.csv (12207, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0128_ScanRegion5_rep_0_channel_2_measures.csv (36668, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0130_ScanRegion4_rep_0_channel_2_measures.csv (22478, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0131_ScanRegion0_rep_0_channel_2_measures.csv (75915, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0129_ScanRegion4_rep_0_channel_2_measures.csv (881, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0133_ScanRegion1_rep_2_channel_2_measures.csv (25173, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0128_ScanRegion0_rep_1_channel_2_measures.csv (9836, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion7_rep_2_channel_2_measures.csv (27770, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0131_ScanRegion5_rep_0_channel_2_measures.csv (52956, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0131_ScanRegion2_rep_2_channel_2_measures.csv (55563, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0132_ScanRegion1_rep_1_channel_2_measures.csv (92340, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0131_ScanRegion2_rep_1_channel_2_measures.csv (2185, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0129_ScanRegion2_rep_2_channel_2_measures.csv (13307, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0133_ScanRegion3_rep_0_channel_2_measures.csv (47582, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0130_ScanRegion0_rep_2_channel_2_measures.csv (1122, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0131_ScanRegion1_rep_0_channel_2_measures.csv (5646, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion6_rep_1_channel_2_measures.csv (22272, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0131_ScanRegion5_rep_1_channel_2_measures.csv (59825, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0128_ScanRegion3_rep_0_channel_2_measures.csv (11258, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0133_ScanRegion4_rep_2_channel_2_measures.csv (6712, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0130_ScanRegion1_rep_0_channel_2_measures.csv (26007, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion7_rep_3_channel_2_measures.csv (72679, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0133_ScanRegion2_rep_1_channel_2_measures.csv (17407, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion6_rep_2_channel_2_measures.csv (4246, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0129_ScanRegion5_rep_1_channel_2_measures.csv (79266, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0132_ScanRegion4_rep_1_channel_2_measures.csv (10935, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0128_ScanRegion2_rep_0_channel_2_measures.csv (24890, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0132_ScanRegion0_rep_1_channel_2_measures.csv (24601, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0129_ScanRegion5_rep_2_channel_2_measures.csv (58504, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0133_ScanRegion2_rep_2_channel_2_measures.csv (7832, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0132_ScanRegion2_rep_1_channel_2_measures.csv (194410, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0133_ScanRegion1_rep_0_channel_2_measures.csv (2649, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0131_ScanRegion0_rep_2_channel_2_measures.csv (35739, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0132_ScanRegion5_rep_1_channel_2_measures.csv (72165, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0132_ScanRegion4_rep_0_channel_2_measures.csv (79123, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0128_ScanRegion4_rep_1_channel_2_measures.csv (17120, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0131_ScanRegion3_rep_0_channel_2_measures.csv (43389, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0131_ScanRegion3_rep_2_channel_2_measures.csv (19504, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0131_ScanRegion4_rep_1_channel_2_measures.csv (38346, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0128_ScanRegion0_rep_0_channel_2_measures.csv (70479, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0134_ScanRegion3_rep_0_channel_2_measures.csv (50144, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0133_ScanRegion3_rep_2_channel_2_measures.csv (1195, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0130_ScanRegion3_rep_1_channel_2_measures.csv (54110, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0133_ScanRegion4_rep_1_channel_2_measures.csv (4832, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0132_ScanRegion3_rep_1_channel_2_measures.csv (39112, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0130_ScanRegion0_rep_0_channel_2_measures.csv (41176, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0129_ScanRegion3_rep_3_channel_2_measures.csv (9818, 19) /group/testa/Project/EndPoints/TPSSU/analysis/measurements/20240424_manuel_lessi_0129_ScanRegion3_rep_4_channel_2_measures.csv (23465, 19)
tot_pos_SOX2 = {}
density_SOX2 = {}
n_nuclei = {}
n_nuclei_tot_pos_SOX2 = {}
tot_area_SOX2 = {}
tot_area_no_SOX2 = {}
for file in measurements_files_mix_1_ch2:
#print(file)
df = pd.read_csv(file, index_col=0)
imageName_scanRegion_rep = file.split('/')[-1].split('.')[0].replace('_channel_2_measures', '')
imageName_scanRegion = '_'.join(imageName_scanRegion_rep.split('_')[:5])
if imageName_scanRegion_rep in good_tissue_to_keep_limit and imageName_scanRegion in sample_sheet['ImageName_ScanRegion'].values:
df['ImageName'] = file.split("/")[-1].split(".")[0]
tot_pos_SOX2[file.split("/")[-1].split(".")[0]] = {}
density_SOX2[imageName_scanRegion_rep] = {}
n_nuclei_tot_pos_SOX2[imageName_scanRegion_rep] = {}
df['area_um2'] = df['area'] * (0.325 ** 2) # Convert area to um^2
min_quantile = np.quantile(df['area_um2'], 0.01)
max_quantile = np.quantile(df['area_um2'], 0.99)
df = df[(df['area_um2'] > min_quantile) & (df['area_um2'] < max_quantile)]
n_nuclei[file.split("/")[-1].split(".")[0]] = df.shape[0]
otsu_thrs = filters.threshold_multiotsu(np.array(df['intensity_mean']), classes = 4)
for i, thr in enumerate(otsu_thrs):
tot_pos_SOX2[file.split("/")[-1].split(".")[0]][f'otsu_{i}'] = np.sum(df['intensity_mean'] > thr) / df.shape[0] * 100
n_nuclei_tot_pos_SOX2[imageName_scanRegion_rep][f'otsu_{i}'] = np.sum(df['intensity_mean'] > thr)
if i == 1:
tot_area_SOX2[imageName_scanRegion_rep] = df[df['intensity_mean'] > thr]['area_um2'].sum()
tot_area_no_SOX2[imageName_scanRegion_rep] = df[df['intensity_mean'] <= thr]['area_um2'].sum()
organoid_areas['SOX2_pos_area'] = organoid_areas.index.map(tot_area_SOX2)
organoid_areas['SOX2_neg_area'] = organoid_areas.index.map(tot_area_no_SOX2)
/tmp/ipykernel_1121090/4008132345.py:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy organoid_areas['SOX2_pos_area'] = organoid_areas.index.map(tot_area_SOX2) /tmp/ipykernel_1121090/4008132345.py:2: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy organoid_areas['SOX2_neg_area'] = organoid_areas.index.map(tot_area_no_SOX2)
organoid_areas['SOX2_pos_area_over_tot'] = organoid_areas['SOX2_pos_area'] / organoid_areas['area_um2'] * 100
organoid_areas['SOX2_neg_area_over_tot'] = organoid_areas['SOX2_neg_area'] / organoid_areas['area_um2'] * 100
/tmp/ipykernel_1121090/1300664090.py:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy organoid_areas['SOX2_pos_area_over_tot'] = organoid_areas['SOX2_pos_area'] / organoid_areas['area_um2'] * 100 /tmp/ipykernel_1121090/1300664090.py:2: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy organoid_areas['SOX2_neg_area_over_tot'] = organoid_areas['SOX2_neg_area'] / organoid_areas['area_um2'] * 100
fig, ax = plt.subplots(1, 2, figsize=(20, 5))
organoid_area_mix1 = organoid_areas[~organoid_areas['SOX2_pos_area'].isna()]
for i, cond in enumerate(hormonal_conditions):
data = organoid_area_mix1[(organoid_area_mix1['Line'] == 'CTL08A') &
(organoid_area_mix1['Condition'] == cond)]['nuclear_area']
box = ax[0].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
# Add stripplot for CTL08A (single points per box)
dmso_median = organoid_area_mix1[(organoid_area_mix1['Condition'] == 'DMSO') &
(organoid_area_mix1['Line'] == 'CTL08A')]['nuclear_area'].median()
ax[0].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=organoid_area_mix1[(organoid_area_mix1['Line'] == 'CTL08A')],
y='nuclear_area', x='Condition', order=hormonal_conditions, color='black', alpha=0.5, jitter=False, ax=ax[0], size=8
)
for i, cond in enumerate(hormonal_conditions):
data = organoid_area_mix1[(organoid_area_mix1['Line'] == 'CTL04E') &
(organoid_area_mix1['Condition'] == cond)]['nuclear_area']
box = ax[1].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = organoid_area_mix1[(organoid_area_mix1['Condition'] == 'DMSO') &
(organoid_area_mix1['Line'] == 'CTL04E')]['nuclear_area'].median()
ax[1].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=organoid_area_mix1[(organoid_area_mix1['Line'] == 'CTL04E')],
y='nuclear_area', x='Condition', order=hormonal_conditions, color='black', alpha=0.5, jitter=False, ax=ax[1], size=8
)
_ = ax[0].set_xticks(range(len(hormonal_conditions)))
_ = ax[0].set_xticklabels(hormonal_conditions, rotation=90)
_ = ax[1].set_xticks(range(len(hormonal_conditions)))
_ = ax[1].set_xticklabels(hormonal_conditions, rotation=90)
ax[0].set_title('CTL08A')
ax[1].set_title('CTL04E')
ax[0].set_ylabel('nuclear_area/organoid area')
ax[1].set_ylabel('nuclear_area/organoid area')
Text(0, 0.5, 'nuclear_area/organoid area')
fig, ax = plt.subplots(1, 2, figsize=(20, 5))
organoid_area_mix1 = organoid_areas[~organoid_areas['SOX2_pos_area'].isna()]
for i, cond in enumerate(hormonal_conditions):
data = organoid_area_mix1[(organoid_area_mix1['Line'] == 'CTL08A') &
(organoid_area_mix1['Condition'] == cond)]['SOX2_pos_area_over_tot']
box = ax[0].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
# Add stripplot for CTL08A (single points per box)
dmso_median = organoid_area_mix1[(organoid_area_mix1['Condition'] == 'DMSO') &
(organoid_area_mix1['Line'] == 'CTL08A')]['SOX2_pos_area_over_tot'].median()
ax[0].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=organoid_area_mix1[(organoid_area_mix1['Line'] == 'CTL08A')],
y='SOX2_pos_area_over_tot', x='Condition', order=hormonal_conditions, color='black', alpha=0.5, jitter=False, ax=ax[0], size=8
)
for i, cond in enumerate(hormonal_conditions):
data = organoid_area_mix1[(organoid_area_mix1['Line'] == 'CTL04E') &
(organoid_area_mix1['Condition'] == cond)]['SOX2_pos_area_over_tot']
box = ax[1].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = organoid_area_mix1[(organoid_area_mix1['Condition'] == 'DMSO') &
(organoid_area_mix1['Line'] == 'CTL04E')]['SOX2_pos_area_over_tot'].median()
ax[1].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=organoid_area_mix1[(organoid_area_mix1['Line'] == 'CTL04E')],
y='SOX2_pos_area_over_tot', x='Condition', order=hormonal_conditions, color='black', alpha=0.5, jitter=False, ax=ax[1], size=8
)
_ = ax[0].set_xticks(range(len(hormonal_conditions)))
_ = ax[0].set_xticklabels(hormonal_conditions, rotation=90)
_ = ax[1].set_xticks(range(len(hormonal_conditions)))
_ = ax[1].set_xticklabels(hormonal_conditions, rotation=90)
ax[0].set_title('CTL08A')
ax[1].set_title('CTL04E')
ax[0].set_ylabel('SOX2_pos_area_over_tot')
ax[1].set_ylabel('SOX2_pos_area_over_tot')
Text(0, 0.5, 'SOX2_pos_area_over_tot')
fig, ax = plt.subplots(1, 2, figsize=(20, 5))
for i, cond in enumerate(hormonal_conditions):
data = organoid_area_mix1[(organoid_area_mix1['Line'] == 'CTL08A') &
(organoid_area_mix1['Condition'] == cond)]['SOX2_neg_area_over_tot']
box = ax[0].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
# Add stripplot for CTL08A (single points per box)
dmso_median = organoid_area_mix1[(organoid_area_mix1['Condition'] == 'DMSO') &
(organoid_area_mix1['Line'] == 'CTL08A')]['SOX2_neg_area_over_tot'].median()
ax[0].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=organoid_area_mix1[(organoid_area_mix1['Line'] == 'CTL08A')],
y='SOX2_neg_area_over_tot', x='Condition', order=hormonal_conditions, color='black', alpha=0.5, jitter=False, ax=ax[0], size=8
)
for i, cond in enumerate(hormonal_conditions):
data = organoid_area_mix1[(organoid_area_mix1['Line'] == 'CTL04E') &
(organoid_area_mix1['Condition'] == cond)]['SOX2_neg_area_over_tot']
box = ax[1].boxplot(data, positions=[i], patch_artist=True, widths=.8)
for patch in box['boxes']:
patch.set_facecolor(color_palette[cond])
box['medians'][0].set_color('black')
dmso_median = organoid_area_mix1[(organoid_area_mix1['Condition'] == 'DMSO') &
(organoid_area_mix1['Line'] == 'CTL04E')]['SOX2_neg_area_over_tot'].median()
ax[1].axhline(dmso_median, color='red', linestyle='--', linewidth=.7, alpha=0.7)
sns.stripplot(
data=organoid_area_mix1[(organoid_area_mix1['Line'] == 'CTL04E')],
y='SOX2_neg_area_over_tot', x='Condition', order=hormonal_conditions, color='black', alpha=0.5, jitter=False, ax=ax[1], size=8
)
_ = ax[0].set_xticks(range(len(hormonal_conditions)))
_ = ax[0].set_xticklabels(hormonal_conditions, rotation=90)
_ = ax[1].set_xticks(range(len(hormonal_conditions)))
_ = ax[1].set_xticklabels(hormonal_conditions, rotation=90)
ax[0].set_title('CTL08A')
ax[1].set_title('CTL04E')
ax[0].set_ylabel('SOX2_neg_area_over_tot')
ax[1].set_ylabel('SOX2_neg_area_over_tot')
Text(0, 0.5, 'SOX2_neg_area_over_tot')