{
"cells": [
{
"cell_type": "markdown",
"id": "2f333c50",
"metadata": {},
"source": [
"# FBN1 Cohort Analysis: Correlation and Synergy\n",
"\n",
"In this tutorial, we analyze a cohort of phenopackets associated with the gene **FBN1**. The example data is retrieved from the [phenopacket store](https://github.com/monarch-initiative/phenopacket-store).\n",
"\n",
"Using this dataset, we demonstrate a complete workflow with **phenosign**, including:\n",
"\n",
"- dataset construction\n",
"- correlation analysis\n",
"- synergy analysis of phenotypic features\n",
"\n",
"We recommend running this tutorial in a **Jupyter notebook** for interactive exploration and visualization, although it can also be executed as a standard Python script.\n",
"\n",
"\n",
"## 1. Load phenopackets\n",
"\n",
"We start by loading phenopackets for the **FBN1** cohort:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "deec03c5",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Loaded 143 phenopackets\n"
]
}
],
"source": [
"from ppktstore.registry import configure_phenopacket_registry\n",
"registry = configure_phenopacket_registry()\n",
"with registry.open_phenopacket_store() as ps:\n",
" phenopackets = [\n",
" p for p in ps.iter_cohort_phenopackets(\"FBN1\")\n",
" ]\n",
"\n",
"print(f\"Loaded {len(phenopackets)} phenopackets\")"
]
},
{
"cell_type": "markdown",
"id": "3a47822d",
"metadata": {},
"source": [
"The function `load_phenopackets_by_cohort` provides convenient access to publicly available datasets from the phenopacket store.\n",
"\n",
"> **Note:** \n",
"> You can also use your own phenopacket data. As long as your data follows the [GA4GH Phenopacket schema](https://phenopacket-schema.readthedocs.io/en/latest/index.html), it can be directly used in the workflow.\n",
"\n",
"## 2. Build the dataset\n",
"\n",
"Next, we convert phenopackets into a structured dataset suitable for downstream statistical analysis. "
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "01d4d77a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Individuals Processed: 100%|██████████| 143/143 [01:27<00:00, 1.64 individuals/s]\n"
]
}
],
"source": [
"from phenosign import PhenotypeDatasetBuilder\n",
"\n",
"dataset = PhenotypeDatasetBuilder(phenopackets).build()"
]
},
{
"cell_type": "markdown",
"id": "f5029d84",
"metadata": {},
"source": [
"The parameters specify the transcript of interest, the variant class to include. Detailed explanations are provided in the **Usage** section.\n",
"\n",
"The resulting `dataset` is now ready for correlation and synergy analysis.\n",
"\n",
"\n",
"## 3. Correlation analysis\n",
"\n",
"Next, we compute pairwise correlations between HPO features across individuals in the cohort."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "69656de4",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Calculating pairwise correlation: 100%|██████████| 728/728 [00:01<00:00, 394.09it/s]\n"
]
},
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" HPO_A | \n",
" HPO_A_label | \n",
" HPO_B | \n",
" HPO_B_label | \n",
" correlation | \n",
" p_value | \n",
" adj_p_value | \n",
" n(A:E/B:E) | \n",
" n(A:E/B:O) | \n",
" n(A:O/B:E) | \n",
" n(A:O/B:O) | \n",
" n_individuals | \n",
" n_pmids | \n",
" pmids | \n",
"
\n",
" \n",
" \n",
" \n",
" | 467 | \n",
" HP:0004322 | \n",
" Short stature | \n",
" HP:0004942 | \n",
" Aortic aneurysm | \n",
" -0.827131 | \n",
" 2.049015e-14 | \n",
" 9.773799e-12 | \n",
" 7 | \n",
" 34 | \n",
" 33 | \n",
" 0 | \n",
" 74 | \n",
" 5 | \n",
" 10756346;11175294;12203992;20375004;21683322 | \n",
"
\n",
" \n",
" | 50 | \n",
" HP:0000098 | \n",
" Tall stature | \n",
" HP:0004942 | \n",
" Aortic aneurysm | \n",
" 0.796637 | \n",
" 1.940118e-13 | \n",
" 4.627183e-11 | \n",
" 45 | \n",
" 7 | \n",
" 1 | \n",
" 26 | \n",
" 79 | \n",
" 13 | \n",
" 10756346;11175294;12203992;20375004;20979188;2... | \n",
"
\n",
" \n",
" | 48 | \n",
" HP:0000098 | \n",
" Tall stature | \n",
" HP:0004322 | \n",
" Short stature | \n",
" -0.685681 | \n",
" 5.424742e-12 | \n",
" 8.625340e-10 | \n",
" 16 | \n",
" 33 | \n",
" 37 | \n",
" 0 | \n",
" 86 | \n",
" 5 | \n",
" 10756346;11175294;12203992;20375004;21683322 | \n",
"
\n",
" \n",
" | 44 | \n",
" HP:0000098 | \n",
" Tall stature | \n",
" HP:0002616 | \n",
" Aortic root aneurysm | \n",
" 0.646903 | \n",
" 1.766457e-11 | \n",
" 2.106500e-09 | \n",
" 70 | \n",
" 7 | \n",
" 10 | \n",
" 26 | \n",
" 113 | \n",
" 18 | \n",
" 10756346;11175294;12203992;20375004;20979188;2... | \n",
"
\n",
" \n",
" | 439 | \n",
" HP:0002616 | \n",
" Aortic root aneurysm | \n",
" HP:0004322 | \n",
" Short stature | \n",
" -0.634615 | \n",
" 2.474657e-10 | \n",
" 2.360823e-08 | \n",
" 19 | \n",
" 33 | \n",
" 33 | \n",
" 0 | \n",
" 85 | \n",
" 5 | \n",
" 10756346;11175294;12203992;20375004;21683322 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" HPO_A HPO_A_label HPO_B HPO_B_label \\\n",
"467 HP:0004322 Short stature HP:0004942 Aortic aneurysm \n",
"50 HP:0000098 Tall stature HP:0004942 Aortic aneurysm \n",
"48 HP:0000098 Tall stature HP:0004322 Short stature \n",
"44 HP:0000098 Tall stature HP:0002616 Aortic root aneurysm \n",
"439 HP:0002616 Aortic root aneurysm HP:0004322 Short stature \n",
"\n",
" correlation p_value adj_p_value n(A:E/B:E) n(A:E/B:O) \\\n",
"467 -0.827131 2.049015e-14 9.773799e-12 7 34 \n",
"50 0.796637 1.940118e-13 4.627183e-11 45 7 \n",
"48 -0.685681 5.424742e-12 8.625340e-10 16 33 \n",
"44 0.646903 1.766457e-11 2.106500e-09 70 7 \n",
"439 -0.634615 2.474657e-10 2.360823e-08 19 33 \n",
"\n",
" n(A:O/B:E) n(A:O/B:O) n_individuals n_pmids \\\n",
"467 33 0 74 5 \n",
"50 1 26 79 13 \n",
"48 37 0 86 5 \n",
"44 10 26 113 18 \n",
"439 33 0 85 5 \n",
"\n",
" pmids \n",
"467 10756346;11175294;12203992;20375004;21683322 \n",
"50 10756346;11175294;12203992;20375004;20979188;2... \n",
"48 10756346;11175294;12203992;20375004;21683322 \n",
"44 10756346;11175294;12203992;20375004;20979188;2... \n",
"439 10756346;11175294;12203992;20375004;21683322 "
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from phenosign import HPOCorrelationAnalyzer\n",
"\n",
"analyzer = HPOCorrelationAnalyzer(dataset=dataset)\n",
"\n",
"results = analyzer.compute_correlation_matrix()\n",
"\n",
"results.results_table.head()"
]
},
{
"cell_type": "markdown",
"id": "7d9459e6",
"metadata": {},
"source": [
"This step identifies pairs of HPO terms that tend to co-occur or show mutually exclusive patterns.\n",
"\n",
"In the result table:\n",
"\n",
"- `HPO_A` and `HPO_B` are the two HPO terms being compared \n",
"- `correlation` indicates the strength and direction of association \n",
"- `p_value_corrected` provides the adjusted significance level \n",
"\n",
"Interpretation:\n",
"\n",
"- **positive correlation** → the two phenotypes tend to appear together \n",
"- **negative correlation** → the phenotypes tend to occur in different individuals \n",
"- **values near zero** → little or no association \n",
"\n",
"Detailed descriptions of parameters and output columns are provided in the **Usage** section.\n",
"\n",
"## 4. Visualize correlation results\n",
"\n",
"To better interpret these relationships, we visualize them as a heatmap."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "935e51e3",
"metadata": {
"nbsphinx": {
"hide-input": true
},
"tags": [
"hide_input"
]
},
"outputs": [],
"source": [
"import os\n",
"from IPython.display import HTML\n",
"\n",
"STATIC_DIR = \"_static\" \n",
"os.makedirs(STATIC_DIR, exist_ok=True)\n",
"\n",
"def plotly_html_link(fig, filename, link_text=\"View interactive heatmap\"):\n",
" \"\"\"\n",
" Generate Plotly HTML file and return an RTD-friendly link.\n",
" \"\"\"\n",
" filepath = os.path.join(STATIC_DIR, filename)\n",
" fig.write_html(filepath, include_plotlyjs=\"cdn\", full_html=True)\n",
" return HTML(f'To view the interactive plot, click the link below:
'\n",
" f'{link_text}')"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "66c2e84d",
"metadata": {},
"outputs": [],
"source": [
"fig1 = results.plot_correlation_heatmap_with_significance(\n",
" title_name=\"Cohort FBN1\",\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "11a16cf9",
"metadata": {
"nbsphinx": {
"hide-input": true
},
"tags": [
"hide_input"
]
},
"outputs": [
{
"data": {
"text/html": [
"To view the interactive plot, click the link below:
Click here to view interactive correlation heatmap"
],
"text/plain": [
""
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"plotly_html_link(fig1, \"correlation_heatmap.html\", link_text=\"Click here to view interactive correlation heatmap\")"
]
},
{
"cell_type": "markdown",
"id": "5954dd69",
"metadata": {},
"source": [
"This visualization highlights the strongest and most statistically significant associations between phenotypic features.\n",
"\n",
"- Strong positive correlations indicate phenotypes that frequently co-occur\n",
"- Strong negative correlations indicate phenotypes that tend to occur in different individuals\n",
"\n",
"> **Note:** \n",
"> Hover over the heatmap to see detailed information for each phenotype pair. \n",
"> The thresholds control which interactions are displayed. Lower thresholds include more pairs, while higher thresholds focus on the strongest signals. \n",
"\n",
"## 5. Inspect available targets\n",
"\n",
"Before running synergy analysis, we inspect the available target variables in the dataset."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "39d7271b",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" label | \n",
" n_individuals | \n",
"
\n",
" \n",
" | disease_id | \n",
" | \n",
" | \n",
"
\n",
" \n",
" \n",
" \n",
" | OMIM:154700 | \n",
" Marfan syndrome | \n",
" 50 (35.0%) | \n",
"
\n",
" \n",
" | OMIM:129600 | \n",
" Ectopia lentis, familial | \n",
" 44 (30.8%) | \n",
"
\n",
" \n",
" | OMIM:614185 | \n",
" Geleophysic dysplasia 2 | \n",
" 19 (13.3%) | \n",
"
\n",
" \n",
" | OMIM:102370 | \n",
" Acromicric dysplasia | \n",
" 13 (9.1%) | \n",
"
\n",
" \n",
" | OMIM:616914 | \n",
" Marfan lipodystrophy syndrome | \n",
" 9 (6.3%) | \n",
"
\n",
" \n",
" | OMIM:184900 | \n",
" Stiff skin syndrome | \n",
" 8 (5.6%) | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" label n_individuals\n",
"disease_id \n",
"OMIM:154700 Marfan syndrome 50 (35.0%)\n",
"OMIM:129600 Ectopia lentis, familial 44 (30.8%)\n",
"OMIM:614185 Geleophysic dysplasia 2 19 (13.3%)\n",
"OMIM:102370 Acromicric dysplasia 13 (9.1%)\n",
"OMIM:616914 Marfan lipodystrophy syndrome 9 (6.3%)\n",
"OMIM:184900 Stiff skin syndrome 8 (5.6%)"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"diseases_df, sex_df, genes_df, variant_effects_df = dataset.describe_conditions()\n",
"\n",
"diseases_df"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "d9c543f9",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" n_individuals | \n",
"
\n",
" \n",
" | sex | \n",
" | \n",
"
\n",
" \n",
" \n",
" \n",
" | female | \n",
" 57 (39.9%) | \n",
"
\n",
" \n",
" | male | \n",
" 54 (37.8%) | \n",
"
\n",
" \n",
" | unknown | \n",
" 32 (22.4%) | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" n_individuals\n",
"sex \n",
"female 57 (39.9%)\n",
"male 54 (37.8%)\n",
"unknown 32 (22.4%)"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sex_df"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "041b7f81",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" n_individuals | \n",
"
\n",
" \n",
" | gene_symbol | \n",
" | \n",
"
\n",
" \n",
" \n",
" \n",
" | FBN1 | \n",
" 143 (100.0%) | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" n_individuals\n",
"gene_symbol \n",
"FBN1 143 (100.0%)"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"genes_df"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "da60f30f",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | transcript_id | \n",
" NM_000138.5 | \n",
" NM_001406716.1 | \n",
" NM_001406717.1 | \n",
"
\n",
" \n",
" | variant_effect | \n",
" | \n",
" | \n",
" | \n",
"
\n",
" \n",
" \n",
" \n",
" | MISSENSE_VARIANT | \n",
" 119 (78.8%) | \n",
" 119 (78.8%) | \n",
" 8 (88.9%) | \n",
"
\n",
" \n",
" | SPLICE_REGION_VARIANT | \n",
" 6 (4.0%) | \n",
" 6 (4.0%) | \n",
" 1 (11.1%) | \n",
"
\n",
" \n",
" | STOP_GAINED | \n",
" 4 (2.6%) | \n",
" 4 (2.6%) | \n",
" 0 (0.0%) | \n",
"
\n",
" \n",
" | SPLICE_DONOR_VARIANT | \n",
" 6 (4.0%) | \n",
" 6 (4.0%) | \n",
" 0 (0.0%) | \n",
"
\n",
" \n",
" | INFRAME_DELETION | \n",
" 1 (0.7%) | \n",
" 1 (0.7%) | \n",
" 0 (0.0%) | \n",
"
\n",
" \n",
" | INFRAME_INSERTION | \n",
" 1 (0.7%) | \n",
" 1 (0.7%) | \n",
" 0 (0.0%) | \n",
"
\n",
" \n",
" | FRAMESHIFT_VARIANT | \n",
" 7 (4.6%) | \n",
" 7 (4.6%) | \n",
" 0 (0.0%) | \n",
"
\n",
" \n",
" | SPLICE_DONOR_5TH_BASE_VARIANT | \n",
" 1 (0.7%) | \n",
" 1 (0.7%) | \n",
" 0 (0.0%) | \n",
"
\n",
" \n",
" | INTRON_VARIANT | \n",
" 2 (1.3%) | \n",
" 2 (1.3%) | \n",
" 0 (0.0%) | \n",
"
\n",
" \n",
" | SYNONYMOUS_VARIANT | \n",
" 1 (0.7%) | \n",
" 1 (0.7%) | \n",
" 0 (0.0%) | \n",
"
\n",
" \n",
" | SPLICE_DONOR_REGION_VARIANT | \n",
" 1 (0.7%) | \n",
" 1 (0.7%) | \n",
" 0 (0.0%) | \n",
"
\n",
" \n",
" | SPLICE_ACCEPTOR_VARIANT | \n",
" 2 (1.3%) | \n",
" 2 (1.3%) | \n",
" 0 (0.0%) | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
"transcript_id NM_000138.5 NM_001406716.1 NM_001406717.1\n",
"variant_effect \n",
"MISSENSE_VARIANT 119 (78.8%) 119 (78.8%) 8 (88.9%)\n",
"SPLICE_REGION_VARIANT 6 (4.0%) 6 (4.0%) 1 (11.1%)\n",
"STOP_GAINED 4 (2.6%) 4 (2.6%) 0 (0.0%)\n",
"SPLICE_DONOR_VARIANT 6 (4.0%) 6 (4.0%) 0 (0.0%)\n",
"INFRAME_DELETION 1 (0.7%) 1 (0.7%) 0 (0.0%)\n",
"INFRAME_INSERTION 1 (0.7%) 1 (0.7%) 0 (0.0%)\n",
"FRAMESHIFT_VARIANT 7 (4.6%) 7 (4.6%) 0 (0.0%)\n",
"SPLICE_DONOR_5TH_BASE_VARIANT 1 (0.7%) 1 (0.7%) 0 (0.0%)\n",
"INTRON_VARIANT 2 (1.3%) 2 (1.3%) 0 (0.0%)\n",
"SYNONYMOUS_VARIANT 1 (0.7%) 1 (0.7%) 0 (0.0%)\n",
"SPLICE_DONOR_REGION_VARIANT 1 (0.7%) 1 (0.7%) 0 (0.0%)\n",
"SPLICE_ACCEPTOR_VARIANT 2 (1.3%) 2 (1.3%) 0 (0.0%)"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"variant_effects_df"
]
},
{
"cell_type": "markdown",
"id": "5348693b",
"metadata": {},
"source": [
"This summary shows which target variables (e.g., disease labels or variant conditions) can be used for downstream analysis.\n",
"\n",
"These targets define the conditions under which phenotype–phenotype relationships are evaluated in the synergy analysis.\n",
"\n",
"In other words, synergy analysis asks whether the association between two phenotypes changes across different conditions (e.g., variant classes or disease groups).\n",
"\n",
"\n",
"## 6. Synergy analysis\n",
"\n",
"While correlation captures overall associations between phenotypes, it does not account for how these relationships may differ across conditions.\n",
"\n",
"Synergy analysis addresses this by evaluating whether the association between two phenotypes changes depending on a target variable (e.g., variant class or disease group).\n",
"\n",
"We begin by initializing the synergy analyzer:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "4a4b346d",
"metadata": {},
"outputs": [],
"source": [
"from phenosign import SynergyAnalyzer\n",
"\n",
"synergy_analyzer = SynergyAnalyzer(dataset=dataset)"
]
},
{
"cell_type": "markdown",
"id": "2564e1e8",
"metadata": {},
"source": [
"Next, we compute the synergy matrix for the selected target:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "90be1d8c",
"metadata": {},
"outputs": [],
"source": [
"from gpsea.model import VariantEffect\n",
"from phenosign import has_variant_effect\n",
"condition = dataset.get_variant_condition(has_variant_effect(transcript_id = \"NM_000138.5\",\n",
" variant_effect=VariantEffect.MISSENSE_VARIANT) \n",
")\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "61dba5b3",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Calculating pairwise synergy: 100%|██████████| 606/606 [03:05<00:00, 3.27it/s]\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" HPO_A | \n",
" HPO_A_label | \n",
" HPO_B | \n",
" HPO_B_label | \n",
" synergy | \n",
" p_value | \n",
" adj_p_value | \n",
" n(A:E/B:E)_y0 | \n",
" n(A:E/B:O)_y0 | \n",
" n(A:O/B:E)_y0 | \n",
" n(A:O/B:O)_y0 | \n",
" N_y0 | \n",
" n(A:E/B:E)_y1 | \n",
" n(A:E/B:O)_y1 | \n",
" n(A:O/B:E)_y1 | \n",
" n(A:O/B:O)_y1 | \n",
" N_y1 | \n",
" n_individuals | \n",
" n_pmids | \n",
" pmids | \n",
"
\n",
" \n",
" \n",
" \n",
" | 39 | \n",
" HP:0000098 | \n",
" Tall stature | \n",
" HP:0002650 | \n",
" Scoliosis | \n",
" 0.148600 | \n",
" 0.0002 | \n",
" 0.016157 | \n",
" 2 | \n",
" 4 | \n",
" 7 | \n",
" 2 | \n",
" 15 | \n",
" 36 | \n",
" 1 | \n",
" 12 | \n",
" 16 | \n",
" 65 | \n",
" 80 | \n",
" 11 | \n",
" 10756346;11175294;12203992;20375004;22219643;2... | \n",
"
\n",
" \n",
" | 33 | \n",
" HP:0000098 | \n",
" Tall stature | \n",
" HP:0001382 | \n",
" Joint hypermobility | \n",
" 0.106631 | \n",
" 0.0002 | \n",
" 0.016157 | \n",
" 2 | \n",
" 4 | \n",
" 6 | \n",
" 2 | \n",
" 14 | \n",
" 58 | \n",
" 2 | \n",
" 12 | \n",
" 17 | \n",
" 89 | \n",
" 103 | \n",
" 12 | \n",
" 10756346;11175294;12203992;20979188;21594992;2... | \n",
"
\n",
" \n",
" | 31 | \n",
" HP:0000098 | \n",
" Tall stature | \n",
" HP:0001187 | \n",
" Hyperextensibility of the finger joints | \n",
" 0.041146 | \n",
" 0.0002 | \n",
" 0.016157 | \n",
" 2 | \n",
" 3 | \n",
" 6 | \n",
" 0 | \n",
" 11 | \n",
" 58 | \n",
" 0 | \n",
" 12 | \n",
" 0 | \n",
" 70 | \n",
" 81 | \n",
" 12 | \n",
" 10756346;11175294;12203992;20979188;21594992;2... | \n",
"
\n",
" \n",
" | 277 | \n",
" HP:0001187 | \n",
" Hyperextensibility of the finger joints | \n",
" HP:0001519 | \n",
" Disproportionate tall stature | \n",
" 0.028099 | \n",
" 0.0002 | \n",
" 0.016157 | \n",
" 4 | \n",
" 5 | \n",
" 3 | \n",
" 0 | \n",
" 12 | \n",
" 67 | \n",
" 4 | \n",
" 0 | \n",
" 0 | \n",
" 71 | \n",
" 83 | \n",
" 11 | \n",
" 10756346;11175294;12203992;20979188;21594992;2... | \n",
"
\n",
" \n",
" | 291 | \n",
" HP:0001382 | \n",
" Joint hypermobility | \n",
" HP:0001519 | \n",
" Disproportionate tall stature | \n",
" 0.078793 | \n",
" 0.0002 | \n",
" 0.016157 | \n",
" 4 | \n",
" 5 | \n",
" 5 | \n",
" 1 | \n",
" 15 | \n",
" 67 | \n",
" 4 | \n",
" 9 | \n",
" 10 | \n",
" 90 | \n",
" 105 | \n",
" 11 | \n",
" 10756346;11175294;12203992;20979188;21594992;2... | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" HPO_A HPO_A_label HPO_B \\\n",
"39 HP:0000098 Tall stature HP:0002650 \n",
"33 HP:0000098 Tall stature HP:0001382 \n",
"31 HP:0000098 Tall stature HP:0001187 \n",
"277 HP:0001187 Hyperextensibility of the finger joints HP:0001519 \n",
"291 HP:0001382 Joint hypermobility HP:0001519 \n",
"\n",
" HPO_B_label synergy p_value adj_p_value \\\n",
"39 Scoliosis 0.148600 0.0002 0.016157 \n",
"33 Joint hypermobility 0.106631 0.0002 0.016157 \n",
"31 Hyperextensibility of the finger joints 0.041146 0.0002 0.016157 \n",
"277 Disproportionate tall stature 0.028099 0.0002 0.016157 \n",
"291 Disproportionate tall stature 0.078793 0.0002 0.016157 \n",
"\n",
" n(A:E/B:E)_y0 n(A:E/B:O)_y0 n(A:O/B:E)_y0 n(A:O/B:O)_y0 N_y0 \\\n",
"39 2 4 7 2 15 \n",
"33 2 4 6 2 14 \n",
"31 2 3 6 0 11 \n",
"277 4 5 3 0 12 \n",
"291 4 5 5 1 15 \n",
"\n",
" n(A:E/B:E)_y1 n(A:E/B:O)_y1 n(A:O/B:E)_y1 n(A:O/B:O)_y1 N_y1 \\\n",
"39 36 1 12 16 65 \n",
"33 58 2 12 17 89 \n",
"31 58 0 12 0 70 \n",
"277 67 4 0 0 71 \n",
"291 67 4 9 10 90 \n",
"\n",
" n_individuals n_pmids pmids \n",
"39 80 11 10756346;11175294;12203992;20375004;22219643;2... \n",
"33 103 12 10756346;11175294;12203992;20979188;21594992;2... \n",
"31 81 12 10756346;11175294;12203992;20979188;21594992;2... \n",
"277 83 11 10756346;11175294;12203992;20979188;21594992;2... \n",
"291 105 11 10756346;11175294;12203992;20979188;21594992;2... "
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"results_variant = synergy_analyzer.compute_synergy_matrix(\n",
" condition=condition\n",
")\n",
"\n",
"results_variant.results_table.head()"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "af166de8",
"metadata": {},
"outputs": [],
"source": [
"from phenosign import has_disease\n",
"condition_disease = dataset.get_condition(has_disease(\"OMIM:154700\"), name=\"disease:Marfan syndrome\")"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "ce341f8b",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Calculating pairwise synergy: 100%|██████████| 606/606 [01:44<00:00, 5.78it/s]\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" HPO_A | \n",
" HPO_A_label | \n",
" HPO_B | \n",
" HPO_B_label | \n",
" synergy | \n",
" p_value | \n",
" adj_p_value | \n",
" n(A:E/B:E)_y0 | \n",
" n(A:E/B:O)_y0 | \n",
" n(A:O/B:E)_y0 | \n",
" n(A:O/B:O)_y0 | \n",
" N_y0 | \n",
" n(A:E/B:E)_y1 | \n",
" n(A:E/B:O)_y1 | \n",
" n(A:O/B:E)_y1 | \n",
" n(A:O/B:O)_y1 | \n",
" N_y1 | \n",
" n_individuals | \n",
" n_pmids | \n",
" pmids | \n",
"
\n",
" \n",
" \n",
" \n",
" | 180 | \n",
" HP:0001519 | \n",
" Disproportionate tall stature | \n",
" HP:0004959 | \n",
" Descending thoracic aorta aneurysm | \n",
" 0.073524 | \n",
" 0.0002 | \n",
" 0.00103 | \n",
" 45 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 45 | \n",
" 0 | \n",
" 1 | \n",
" 5 | \n",
" 0 | \n",
" 6 | \n",
" 51 | \n",
" 8 | \n",
" 10756346;20375004;21594992;21683322;24039054;2... | \n",
"
\n",
" \n",
" | 181 | \n",
" HP:0001519 | \n",
" Disproportionate tall stature | \n",
" HP:0008848 | \n",
" Moderately short stature | \n",
" -0.045049 | \n",
" 0.0002 | \n",
" 0.00103 | \n",
" 27 | \n",
" 9 | \n",
" 0 | \n",
" 0 | \n",
" 36 | \n",
" 29 | \n",
" 0 | \n",
" 21 | \n",
" 0 | \n",
" 50 | \n",
" 86 | \n",
" 5 | \n",
" 10756346;11175294;12203992;20375004;21683322 | \n",
"
\n",
" \n",
" | 229 | \n",
" HP:0003502 | \n",
" Mild short stature | \n",
" HP:0003510 | \n",
" Severe short stature | \n",
" 0.016259 | \n",
" 0.0002 | \n",
" 0.00103 | \n",
" 16 | \n",
" 18 | \n",
" 2 | \n",
" 0 | \n",
" 36 | \n",
" 50 | \n",
" 0 | \n",
" 0 | \n",
" 0 | \n",
" 50 | \n",
" 86 | \n",
" 5 | \n",
" 10756346;11175294;12203992;20375004;21683322 | \n",
"
\n",
" \n",
" | 163 | \n",
" HP:0001382 | \n",
" Joint hypermobility | \n",
" HP:0003510 | \n",
" Severe short stature | \n",
" -0.133008 | \n",
" 0.0002 | \n",
" 0.00103 | \n",
" 11 | \n",
" 18 | \n",
" 0 | \n",
" 0 | \n",
" 29 | \n",
" 26 | \n",
" 0 | \n",
" 22 | \n",
" 0 | \n",
" 48 | \n",
" 77 | \n",
" 4 | \n",
" 10756346;11175294;12203992;21683322 | \n",
"
\n",
" \n",
" | 164 | \n",
" HP:0001382 | \n",
" Joint hypermobility | \n",
" HP:0004322 | \n",
" Short stature | \n",
" -0.251557 | \n",
" 0.0002 | \n",
" 0.00103 | \n",
" 0 | \n",
" 32 | \n",
" 0 | \n",
" 0 | \n",
" 32 | \n",
" 26 | \n",
" 0 | \n",
" 22 | \n",
" 0 | \n",
" 48 | \n",
" 80 | \n",
" 4 | \n",
" 10756346;11175294;12203992;21683322 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" HPO_A HPO_A_label HPO_B \\\n",
"180 HP:0001519 Disproportionate tall stature HP:0004959 \n",
"181 HP:0001519 Disproportionate tall stature HP:0008848 \n",
"229 HP:0003502 Mild short stature HP:0003510 \n",
"163 HP:0001382 Joint hypermobility HP:0003510 \n",
"164 HP:0001382 Joint hypermobility HP:0004322 \n",
"\n",
" HPO_B_label synergy p_value adj_p_value \\\n",
"180 Descending thoracic aorta aneurysm 0.073524 0.0002 0.00103 \n",
"181 Moderately short stature -0.045049 0.0002 0.00103 \n",
"229 Severe short stature 0.016259 0.0002 0.00103 \n",
"163 Severe short stature -0.133008 0.0002 0.00103 \n",
"164 Short stature -0.251557 0.0002 0.00103 \n",
"\n",
" n(A:E/B:E)_y0 n(A:E/B:O)_y0 n(A:O/B:E)_y0 n(A:O/B:O)_y0 N_y0 \\\n",
"180 45 0 0 0 45 \n",
"181 27 9 0 0 36 \n",
"229 16 18 2 0 36 \n",
"163 11 18 0 0 29 \n",
"164 0 32 0 0 32 \n",
"\n",
" n(A:E/B:E)_y1 n(A:E/B:O)_y1 n(A:O/B:E)_y1 n(A:O/B:O)_y1 N_y1 \\\n",
"180 0 1 5 0 6 \n",
"181 29 0 21 0 50 \n",
"229 50 0 0 0 50 \n",
"163 26 0 22 0 48 \n",
"164 26 0 22 0 48 \n",
"\n",
" n_individuals n_pmids pmids \n",
"180 51 8 10756346;20375004;21594992;21683322;24039054;2... \n",
"181 86 5 10756346;11175294;12203992;20375004;21683322 \n",
"229 86 5 10756346;11175294;12203992;20375004;21683322 \n",
"163 77 4 10756346;11175294;12203992;21683322 \n",
"164 80 4 10756346;11175294;12203992;21683322 "
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"results_disease = synergy_analyzer.compute_synergy_matrix(\n",
" condition=condition_disease\n",
")\n",
"results_disease.results_table.head()"
]
},
{
"cell_type": "markdown",
"id": "280b6517",
"metadata": {},
"source": [
"The resulting table reports pairwise synergy scores between HPO terms with respect to the selected target.\n",
"\n",
"- `HPO_A` and `HPO_B` are the two phenotypes being evaluated\n",
"- `synergy` measures how much additional information the pair provides about the target compared to individual features\n",
"- `p_value_corrected` indicates statistical significance after multiple testing correction\n",
"\n",
"Interpretation:\n",
"\n",
"- **positive synergy** → the two phenotypes jointly provide additional information about the target \n",
"- **near zero** → the phenotypes contribute largely independently \n",
"- **negative synergy** → the phenotypes are redundant with respect to the target \n",
"\n",
"Detailed descriptions of all output columns are provided in the **Usage** section.\n",
"\n",
"\n",
"\n",
"## 7. Visualize synergy results\n",
"\n",
"We can visualize synergy results as a heatmap."
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "b93c47b3",
"metadata": {},
"outputs": [],
"source": [
"fig2 = results_variant.plot_synergy_heatmap(\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "301d1b29",
"metadata": {
"nbsphinx": {
"hide-input": true
},
"tags": [
"hide_input"
]
},
"outputs": [
{
"data": {
"text/html": [
"To view the interactive plot, click the link below:
Click here to view interactive synergy heatmap"
],
"text/plain": [
""
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"plotly_html_link(fig2, \"synergy_heatmap.html\", link_text=\"Click here to view interactive synergy heatmap\")"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "700efb0b",
"metadata": {},
"outputs": [],
"source": [
"fig3 = results_disease.plot_synergy_heatmap(\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "8ed85fd4",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"To view the interactive plot, click the link below:
Click here to view interactive synergy heatmap for Marfan syndrome"
],
"text/plain": [
""
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"plotly_html_link(fig3, \"synergy_heatmap_disease.html\", link_text=\"Click here to view interactive synergy heatmap for Marfan syndrome\")"
]
},
{
"cell_type": "markdown",
"id": "95a50303",
"metadata": {},
"source": [
"This visualization highlights phenotype pairs that show strong and statistically significant synergy with respect to the selected target.\n",
"\n",
"> **Note:** \n",
"> Hover over the heatmap to see detailed information for each phenotype pair. \n",
"> The thresholds control which interactions are displayed. Lower thresholds include more pairs, while higher thresholds focus on the strongest signals. \n",
"\n",
"## Summary\n",
"\n",
"In this tutorial, we:\n",
"\n",
"- Loaded phenopacket data \n",
"- Constructed a structured dataset \n",
"- Explored phenotype–phenotype relationships using correlation \n",
"- Identified condition-specific interactions using synergy analysis \n",
"\n",
"Together, these steps provide a workflow for uncovering both global and condition-dependent relationships between phenotypic features.\n",
"\n",
"For additional usage patterns and parameter options, see the **Usage** section."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "ppkt2synergy",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.20"
}
},
"nbformat": 4,
"nbformat_minor": 5
}