pythonflex 0.3.2__tar.gz → 0.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pythonflex-0.3.2 → pythonflex-0.3.3}/PKG-INFO +1 -1
- {pythonflex-0.3.2 → pythonflex-0.3.3}/pyproject.toml +1 -1
- {pythonflex-0.3.2 → pythonflex-0.3.3}/src/pythonflex/__init__.py +2 -2
- {pythonflex-0.3.2 → pythonflex-0.3.3}/src/pythonflex/analysis.py +82 -1
- {pythonflex-0.3.2 → pythonflex-0.3.3}/src/pythonflex/examples/basic_usage.py +11 -10
- pythonflex-0.3.3/src/pythonflex/examples/manuscript.py +111 -0
- {pythonflex-0.3.2 → pythonflex-0.3.3}/src/pythonflex/plotting.py +128 -7
- {pythonflex-0.3.2 → pythonflex-0.3.3}/.gitignore +0 -0
- {pythonflex-0.3.2 → pythonflex-0.3.3}/.python-version +0 -0
- {pythonflex-0.3.2 → pythonflex-0.3.3}/README.md +0 -0
- {pythonflex-0.3.2 → pythonflex-0.3.3}/src/pythonflex/data/__init__.py +0 -0
- {pythonflex-0.3.2 → pythonflex-0.3.3}/src/pythonflex/data/dataset/__init__.py +0 -0
- {pythonflex-0.3.2 → pythonflex-0.3.3}/src/pythonflex/data/dataset/liver_cell_lines_500_genes.csv +0 -0
- {pythonflex-0.3.2 → pythonflex-0.3.3}/src/pythonflex/data/dataset/melanoma_cell_lines_500_genes.csv +0 -0
- {pythonflex-0.3.2 → pythonflex-0.3.3}/src/pythonflex/data/dataset/neuroblastoma_cell_lines_500_genes.csv +0 -0
- {pythonflex-0.3.2 → pythonflex-0.3.3}/src/pythonflex/data/gold_standard/CORUM.parquet +0 -0
- {pythonflex-0.3.2 → pythonflex-0.3.3}/src/pythonflex/data/gold_standard/GOBP.parquet +0 -0
- {pythonflex-0.3.2 → pythonflex-0.3.3}/src/pythonflex/data/gold_standard/PATHWAY.parquet +0 -0
- {pythonflex-0.3.2 → pythonflex-0.3.3}/src/pythonflex/data/gold_standard/__init__.py +0 -0
- {pythonflex-0.3.2 → pythonflex-0.3.3}/src/pythonflex/data/gold_standard/corum.csv +0 -0
- {pythonflex-0.3.2 → pythonflex-0.3.3}/src/pythonflex/data/gold_standard/gobp.csv +0 -0
- {pythonflex-0.3.2 → pythonflex-0.3.3}/src/pythonflex/data/gold_standard/pathway.csv +0 -0
- {pythonflex-0.3.2 → pythonflex-0.3.3}/src/pythonflex/logging_config.py +0 -0
- {pythonflex-0.3.2 → pythonflex-0.3.3}/src/pythonflex/preprocessing.py +0 -0
- {pythonflex-0.3.2 → pythonflex-0.3.3}/src/pythonflex/utils.py +0 -0
- {pythonflex-0.3.2 → pythonflex-0.3.3}/todo.txt +0 -0
- {pythonflex-0.3.2 → pythonflex-0.3.3}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pythonflex
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: pythonFLEX is a benchmarking toolkit for evaluating CRISPR screen results against biological gold standards. The toolkit computes gene-level and complex-level performance metrics, helping researchers systematically assess the biological relevance and resolution of their CRISPR screening data.
|
|
5
5
|
Author-email: Yasir Demirtaş <tyasird@hotmail.com>
|
|
6
6
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "pythonflex"
|
|
3
|
-
version = "0.3.
|
|
3
|
+
version = "0.3.3"
|
|
4
4
|
description = "pythonFLEX is a benchmarking toolkit for evaluating CRISPR screen results against biological gold standards. The toolkit computes gene-level and complex-level performance metrics, helping researchers systematically assess the biological relevance and resolution of their CRISPR screening data."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [
|
|
@@ -5,7 +5,7 @@ from .analysis import initialize, pra, pra_percomplex, fast_corr, perform_corr,
|
|
|
5
5
|
from .plotting import (
|
|
6
6
|
adjust_text_positions, plot_precision_recall_curve, plot_aggregated_pra, plot_iqr_pra, plot_all_runs_pra, plot_percomplex_scatter,
|
|
7
7
|
plot_percomplex_scatter_bysize, plot_complex_contributions, plot_significant_complexes, plot_auc_scores,
|
|
8
|
-
plot_mpr_tp, plot_mpr_complexes, plot_mpr_tp_multi, plot_mpr_complexes_multi
|
|
8
|
+
plot_mpr_tp, plot_mpr_complexes, plot_mpr_tp_multi, plot_mpr_complexes_multi, plot_mpr_complexes_auc_scores
|
|
9
9
|
)
|
|
10
10
|
|
|
11
11
|
__all__ = [ "log", "get_example_data_path", "fast_corr",
|
|
@@ -14,7 +14,7 @@ __all__ = [ "log", "get_example_data_path", "fast_corr",
|
|
|
14
14
|
"perform_corr", "is_symmetric", "binary", "has_mirror_of_first_pair", "convert_full_to_half_matrix",
|
|
15
15
|
"drop_mirror_pairs", "quick_sort", "complex_contributions", "adjust_text_positions", "plot_precision_recall_curve",
|
|
16
16
|
"plot_aggregated_pra", "plot_iqr_pra", "plot_all_runs_pra", "plot_percomplex_scatter", "plot_percomplex_scatter_bysize", "plot_complex_contributions",
|
|
17
|
-
"plot_significant_complexes", "plot_auc_scores", "save_results_to_csv", "update_matploblib_config",
|
|
17
|
+
"plot_significant_complexes", "plot_auc_scores", "plot_mpr_complexes_auc_scores", "save_results_to_csv", "update_matploblib_config",
|
|
18
18
|
"mpr_prepare", "plot_mpr_tp", "plot_mpr_complexes",
|
|
19
19
|
"plot_mpr_tp_multi", "plot_mpr_complexes_multi"
|
|
20
20
|
]
|
|
@@ -844,7 +844,7 @@ def quick_sort(df, ascending=False):
|
|
|
844
844
|
log.done("Pair-wise matrix sorting.")
|
|
845
845
|
return sorted_df
|
|
846
846
|
|
|
847
|
-
def save_results_to_csv(categories = ["complex_contributions", "pr_auc", "pra_percomplex"]):
|
|
847
|
+
def save_results_to_csv(categories = ["complex_contributions", "pr_auc", "pra_percomplex", "mpr_complexes_auc"]):
|
|
848
848
|
|
|
849
849
|
config = dload("config") # Load config to get output folder
|
|
850
850
|
output_folder = Path(config.get("output_folder", "output"))
|
|
@@ -856,6 +856,18 @@ def save_results_to_csv(categories = ["complex_contributions", "pr_auc", "pra_pe
|
|
|
856
856
|
if data is None:
|
|
857
857
|
log.warning(f"No data found for category '{category}'. Skipping save.")
|
|
858
858
|
continue
|
|
859
|
+
|
|
860
|
+
if category == "mpr_complexes_auc" and isinstance(data, dict):
|
|
861
|
+
# Dict[dataset_name -> Dict[filter_key -> auc]]
|
|
862
|
+
try:
|
|
863
|
+
df = pd.DataFrame.from_dict(data, orient="index")
|
|
864
|
+
df.index.name = "Dataset"
|
|
865
|
+
csv_path = output_folder / f"{category}.csv"
|
|
866
|
+
df.to_csv(csv_path, index=True)
|
|
867
|
+
log.info(f"Saved '{category}' to {csv_path}")
|
|
868
|
+
except Exception as e:
|
|
869
|
+
log.warning(f"Failed to convert and save '{category}': {e}")
|
|
870
|
+
continue
|
|
859
871
|
|
|
860
872
|
if category == "pr_auc" and isinstance(data, dict):
|
|
861
873
|
# Special handling: Convert dict to DataFrame (assuming keys are indices, values are data)
|
|
@@ -1312,6 +1324,64 @@ def _mpr_module_coverage(contrib_df, terms, tp_th=1, percent_th=0.1):
|
|
|
1312
1324
|
return coverage
|
|
1313
1325
|
|
|
1314
1326
|
|
|
1327
|
+
def _mpr_complexes_auc(
|
|
1328
|
+
coverage: np.ndarray,
|
|
1329
|
+
precision_cutoffs: np.ndarray,
|
|
1330
|
+
max_complexes: float = 200.0,
|
|
1331
|
+
) -> float:
|
|
1332
|
+
"""Compute AUC for the Fig. 1F-style mPR curve (#complexes vs precision).
|
|
1333
|
+
|
|
1334
|
+
The plot uses:
|
|
1335
|
+
x = #covered complexes (capped at `max_complexes`, shown on a log axis)
|
|
1336
|
+
y = precision cutoff
|
|
1337
|
+
|
|
1338
|
+
We compute a normalized AUC by integrating precision over the *normalized*
|
|
1339
|
+
coverage axis:
|
|
1340
|
+
AUC = \int y \, d(x/max_complexes)
|
|
1341
|
+
|
|
1342
|
+
This yields a score in [0, 1] (or NaN if insufficient data).
|
|
1343
|
+
"""
|
|
1344
|
+
cov = np.asarray(coverage, dtype=float)
|
|
1345
|
+
prec = np.asarray(precision_cutoffs, dtype=float)
|
|
1346
|
+
|
|
1347
|
+
if cov.size == 0 or prec.size == 0:
|
|
1348
|
+
return 0.0
|
|
1349
|
+
|
|
1350
|
+
# Match plot_mpr_complexes_multi(): only count cov>0 (log-x cannot show 0)
|
|
1351
|
+
mask = (
|
|
1352
|
+
np.isfinite(cov)
|
|
1353
|
+
& np.isfinite(prec)
|
|
1354
|
+
& (cov > 0)
|
|
1355
|
+
& (cov <= max_complexes)
|
|
1356
|
+
& (prec >= 0)
|
|
1357
|
+
& (prec <= 1.0)
|
|
1358
|
+
)
|
|
1359
|
+
if not np.any(mask):
|
|
1360
|
+
return 0.0
|
|
1361
|
+
|
|
1362
|
+
x_cov = cov[mask]
|
|
1363
|
+
y = prec[mask]
|
|
1364
|
+
|
|
1365
|
+
# x-axis is log-scaled in the plot; normalize so cov=1 -> 0, cov=max_complexes -> 1
|
|
1366
|
+
# (This matches the plot's tick hack where 1 is labeled as "0".)
|
|
1367
|
+
x = np.log10(x_cov) / np.log10(float(max_complexes))
|
|
1368
|
+
|
|
1369
|
+
# Sort by x and collapse duplicate x values by taking max y (upper envelope)
|
|
1370
|
+
order = np.argsort(x)
|
|
1371
|
+
x = x[order]
|
|
1372
|
+
y = y[order]
|
|
1373
|
+
|
|
1374
|
+
x_unique = np.unique(x)
|
|
1375
|
+
if x_unique.size != x.size:
|
|
1376
|
+
y = np.array([float(np.nanmax(y[x == xv])) for xv in x_unique], dtype=float)
|
|
1377
|
+
x = x_unique
|
|
1378
|
+
|
|
1379
|
+
if x.size < 2:
|
|
1380
|
+
return 0.0
|
|
1381
|
+
|
|
1382
|
+
return float(np.trapz(y, x))
|
|
1383
|
+
|
|
1384
|
+
|
|
1315
1385
|
|
|
1316
1386
|
|
|
1317
1387
|
|
|
@@ -1379,6 +1449,7 @@ def mpr_prepare(
|
|
|
1379
1449
|
|
|
1380
1450
|
tp_curves = {}
|
|
1381
1451
|
coverage_curves = {}
|
|
1452
|
+
complexes_auc = {}
|
|
1382
1453
|
precision_cutoffs = None
|
|
1383
1454
|
|
|
1384
1455
|
for label, removed in filter_sets.items():
|
|
@@ -1393,6 +1464,7 @@ def mpr_prepare(
|
|
|
1393
1464
|
"precision": np.array([], dtype=float),
|
|
1394
1465
|
}
|
|
1395
1466
|
coverage_curves[label] = np.zeros(0, dtype=float)
|
|
1467
|
+
complexes_auc[label] = float("nan")
|
|
1396
1468
|
continue
|
|
1397
1469
|
|
|
1398
1470
|
tp_cum = true.cumsum()
|
|
@@ -1417,11 +1489,17 @@ def mpr_prepare(
|
|
|
1417
1489
|
percent_th=percent_th,
|
|
1418
1490
|
)
|
|
1419
1491
|
coverage_curves[label] = cov
|
|
1492
|
+
complexes_auc[label] = _mpr_complexes_auc(
|
|
1493
|
+
cov,
|
|
1494
|
+
precision_cutoffs,
|
|
1495
|
+
max_complexes=200.0,
|
|
1496
|
+
)
|
|
1420
1497
|
|
|
1421
1498
|
mpr_data = {
|
|
1422
1499
|
"precision_cutoffs": precision_cutoffs,
|
|
1423
1500
|
"tp_curves": tp_curves,
|
|
1424
1501
|
"coverage_curves": coverage_curves,
|
|
1502
|
+
"complexes_auc": complexes_auc,
|
|
1425
1503
|
"filters": {
|
|
1426
1504
|
"no_mtRibo_ETCI": sorted(mtRibo_ids),
|
|
1427
1505
|
"no_small_highAUPRC": sorted(small_hi_ids),
|
|
@@ -1435,6 +1513,9 @@ def mpr_prepare(
|
|
|
1435
1513
|
|
|
1436
1514
|
dsave(mpr_data, "mpr", name)
|
|
1437
1515
|
|
|
1516
|
+
# Convenience: store AUCs as their own category for easy export / plotting.
|
|
1517
|
+
dsave(complexes_auc, "mpr_complexes_auc", name)
|
|
1518
|
+
|
|
1438
1519
|
|
|
1439
1520
|
|
|
1440
1521
|
### OLD FUNCTIONS
|
|
@@ -67,20 +67,21 @@ for name, dataset in data.items():
|
|
|
67
67
|
|
|
68
68
|
#%%
|
|
69
69
|
# Generate plots
|
|
70
|
-
flex.plot_precision_recall_curve()
|
|
71
|
-
flex.plot_auc_scores()
|
|
72
|
-
flex.plot_significant_complexes()
|
|
73
|
-
flex.plot_percomplex_scatter(n_top=20)
|
|
74
|
-
flex.plot_percomplex_scatter_bysize()
|
|
75
|
-
flex.plot_complex_contributions()
|
|
76
|
-
|
|
77
|
-
flex.plot_mpr_tp_multi()
|
|
78
|
-
flex.plot_mpr_complexes_multi()
|
|
70
|
+
# flex.plot_precision_recall_curve()
|
|
71
|
+
# flex.plot_auc_scores()
|
|
72
|
+
# flex.plot_significant_complexes()
|
|
73
|
+
# flex.plot_percomplex_scatter(n_top=20)
|
|
74
|
+
# flex.plot_percomplex_scatter_bysize()
|
|
75
|
+
# flex.plot_complex_contributions()
|
|
76
|
+
#%%
|
|
77
|
+
#flex.plot_mpr_tp_multi(show_filters="all")
|
|
78
|
+
flex.plot_mpr_complexes_multi(show_filters="all")
|
|
79
79
|
|
|
80
80
|
#%%
|
|
81
81
|
# Save results to CSV
|
|
82
82
|
flex.save_results_to_csv()
|
|
83
83
|
|
|
84
|
+
|
|
84
85
|
# %%
|
|
85
|
-
flex.
|
|
86
|
+
flex.plot_mpr_complexes_auc_scores("all")
|
|
86
87
|
# %%
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Basic usage example of the pythonFLEX package.
|
|
3
|
+
Demonstrates initialization, data loading, analysis, and plotting.
|
|
4
|
+
"""
|
|
5
|
+
#%%
|
|
6
|
+
import pythonflex as flex
|
|
7
|
+
import pandas as pd
|
|
8
|
+
|
|
9
|
+
gene_effect = pd.read_csv('C:/Users/yd/Desktop/projects/_datasets/depmap/25Q2/gene_effect.csv', index_col=0)
|
|
10
|
+
|
|
11
|
+
skin = pd.read_csv('C:/Users/yd/Desktop/projects/_datasets/depmap/25Q2/subset/skin_cell_lines.csv', index_col=0)
|
|
12
|
+
|
|
13
|
+
soft = pd.read_csv('C:/Users/yd/Desktop/projects/_datasets/depmap/25Q2/subset/soft_tissue_cell_lines.csv', index_col=0)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
cholesky = pd.read_csv('C:/Users/yd/Desktop/projects/_datasets/depmap/25Q2/25Q2_chronos_whitened_Cholesky.csv', index_col=0).T
|
|
17
|
+
|
|
18
|
+
# inputs = {
|
|
19
|
+
# "All Screens": {
|
|
20
|
+
# "path": gene_effect,
|
|
21
|
+
# "sort": "high",
|
|
22
|
+
# "color": "#000000"
|
|
23
|
+
# },
|
|
24
|
+
# "Skin": {
|
|
25
|
+
# "path": skin,
|
|
26
|
+
# "sort": "high",
|
|
27
|
+
# "color": "#FF0000"
|
|
28
|
+
# },
|
|
29
|
+
# "Soft Tissue": {
|
|
30
|
+
# "path": soft,
|
|
31
|
+
# "sort": "high",
|
|
32
|
+
# "color": "#FFFF00"
|
|
33
|
+
# },
|
|
34
|
+
# }
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
inputs = {
|
|
38
|
+
"DM All Screens": {
|
|
39
|
+
"path": gene_effect,
|
|
40
|
+
"sort": "high",
|
|
41
|
+
"color": "#000000"
|
|
42
|
+
},
|
|
43
|
+
"DM Cholesky Whitening": {
|
|
44
|
+
"path": cholesky,
|
|
45
|
+
"sort": "high",
|
|
46
|
+
"color": "#FF0000"
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
default_config = {
|
|
55
|
+
"min_genes_in_complex": 2,
|
|
56
|
+
"min_genes_per_complex_analysis": 3,
|
|
57
|
+
"output_folder": "CORUM_DMvsCholesky",
|
|
58
|
+
"gold_standard": "CORUM",
|
|
59
|
+
"color_map": "BuGn",
|
|
60
|
+
"jaccard": False,
|
|
61
|
+
"use_common_genes": False, # Set to False for individual dataset-gold standard intersections
|
|
62
|
+
"plotting": {
|
|
63
|
+
"save_plot": True,
|
|
64
|
+
"output_type": "pdf",
|
|
65
|
+
},
|
|
66
|
+
"preprocessing": {
|
|
67
|
+
"fill_na": True,
|
|
68
|
+
"normalize": False,
|
|
69
|
+
},
|
|
70
|
+
"corr_function": "numpy",
|
|
71
|
+
"logging": {
|
|
72
|
+
"visible_levels": ["DONE"]
|
|
73
|
+
# "PROGRESS", "STARTED", ,"INFO","WARNING"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
# Initialize logger, config, and output folder
|
|
78
|
+
flex.initialize(default_config)
|
|
79
|
+
|
|
80
|
+
# Load datasets and gold standard terms
|
|
81
|
+
data, _ = flex.load_datasets(inputs)
|
|
82
|
+
terms, genes_in_terms = flex.load_gold_standard()
|
|
83
|
+
|
|
84
|
+
# Run analysis
|
|
85
|
+
for name, dataset in data.items():
|
|
86
|
+
pra = flex.pra(name, dataset, is_corr=False)
|
|
87
|
+
fpc = flex.pra_percomplex(name, dataset, is_corr=False)
|
|
88
|
+
cc = flex.complex_contributions(name)
|
|
89
|
+
flex.mpr_prepare(name)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
#%%
|
|
95
|
+
# Generate plots
|
|
96
|
+
flex.plot_precision_recall_curve()
|
|
97
|
+
flex.plot_auc_scores()
|
|
98
|
+
flex.plot_significant_complexes()
|
|
99
|
+
flex.plot_percomplex_scatter(n_top=20)
|
|
100
|
+
flex.plot_percomplex_scatter_bysize()
|
|
101
|
+
flex.plot_complex_contributions()
|
|
102
|
+
##
|
|
103
|
+
#%%
|
|
104
|
+
flex.plot_mpr_tp_multi(show_filters="all")
|
|
105
|
+
flex.plot_mpr_complexes_multi(show_filters="all")
|
|
106
|
+
|
|
107
|
+
# Save results to CSV
|
|
108
|
+
flex.save_results_to_csv()
|
|
109
|
+
|
|
110
|
+
# %%
|
|
111
|
+
# %%
|
|
@@ -1220,6 +1220,107 @@ def plot_auc_scores():
|
|
|
1220
1220
|
plt.close(fig)
|
|
1221
1221
|
return pra_dict
|
|
1222
1222
|
|
|
1223
|
+
|
|
1224
|
+
def plot_mpr_complexes_auc_scores(filter_key: str = "all"):
|
|
1225
|
+
"""Plot AUC scores for the mPR complexes curve (Fig 1F-style).
|
|
1226
|
+
|
|
1227
|
+
Requires `mpr_prepare()` to have been run for each dataset.
|
|
1228
|
+
|
|
1229
|
+
Parameters
|
|
1230
|
+
----------
|
|
1231
|
+
filter_key : str
|
|
1232
|
+
One of: "all", "no_mtRibo_ETCI", "no_small_highAUPRC".
|
|
1233
|
+
|
|
1234
|
+
Returns
|
|
1235
|
+
-------
|
|
1236
|
+
pd.Series
|
|
1237
|
+
AUC values indexed by dataset name (sorted descending).
|
|
1238
|
+
"""
|
|
1239
|
+
config = dload("config")
|
|
1240
|
+
plot_config = config["plotting"]
|
|
1241
|
+
mpr_auc_dict = dload("mpr_complexes_auc")
|
|
1242
|
+
input_colors = dload("input", "colors")
|
|
1243
|
+
|
|
1244
|
+
if input_colors:
|
|
1245
|
+
input_colors = {_sanitize(k): v for k, v in input_colors.items()}
|
|
1246
|
+
|
|
1247
|
+
if not isinstance(mpr_auc_dict, dict) or not mpr_auc_dict:
|
|
1248
|
+
log.warning(
|
|
1249
|
+
"No mPR complexes AUC data found. Run mpr_prepare() first (it stores 'mpr_complexes_auc')."
|
|
1250
|
+
)
|
|
1251
|
+
return pd.Series(dtype=float)
|
|
1252
|
+
|
|
1253
|
+
# Build Series: dataset -> auc
|
|
1254
|
+
auc_by_dataset = {}
|
|
1255
|
+
for dataset, per_filter in mpr_auc_dict.items():
|
|
1256
|
+
if not isinstance(per_filter, dict):
|
|
1257
|
+
continue
|
|
1258
|
+
val = per_filter.get(filter_key)
|
|
1259
|
+
if val is None:
|
|
1260
|
+
continue
|
|
1261
|
+
try:
|
|
1262
|
+
auc_by_dataset[dataset] = float(val)
|
|
1263
|
+
except (TypeError, ValueError):
|
|
1264
|
+
continue
|
|
1265
|
+
|
|
1266
|
+
if not auc_by_dataset:
|
|
1267
|
+
log.warning(
|
|
1268
|
+
f"No mPR complexes AUC scores found for filter '{filter_key}'. Available filters: {list(FILTER_STYLES.keys())}"
|
|
1269
|
+
)
|
|
1270
|
+
return pd.Series(dtype=float)
|
|
1271
|
+
|
|
1272
|
+
s = pd.Series(auc_by_dataset).sort_values(ascending=False)
|
|
1273
|
+
datasets = list(s.index)
|
|
1274
|
+
auc_scores = list(s.values)
|
|
1275
|
+
|
|
1276
|
+
fig, ax = plt.subplots()
|
|
1277
|
+
|
|
1278
|
+
# Color logic (match other bar plots)
|
|
1279
|
+
cmap_name = config.get("color_map", "tab10")
|
|
1280
|
+
try:
|
|
1281
|
+
cmap = get_cmap(cmap_name)
|
|
1282
|
+
except ValueError:
|
|
1283
|
+
cmap = get_cmap("tab10")
|
|
1284
|
+
|
|
1285
|
+
num_datasets = len(datasets)
|
|
1286
|
+
if num_datasets <= 10 and cmap_name == "tab10":
|
|
1287
|
+
default_colors = [cmap(i) for i in range(num_datasets)]
|
|
1288
|
+
else:
|
|
1289
|
+
default_colors = [cmap(float(i) / max(num_datasets - 1, 1)) for i in range(num_datasets)]
|
|
1290
|
+
|
|
1291
|
+
final_colors = []
|
|
1292
|
+
for i, dataset in enumerate(datasets):
|
|
1293
|
+
color = input_colors.get(dataset) if input_colors else None
|
|
1294
|
+
if color is None:
|
|
1295
|
+
color = default_colors[i]
|
|
1296
|
+
final_colors.append(color)
|
|
1297
|
+
|
|
1298
|
+
ax.bar(datasets, auc_scores, color=final_colors, edgecolor="black")
|
|
1299
|
+
|
|
1300
|
+
ymax = max([v for v in auc_scores if np.isfinite(v)], default=0.0)
|
|
1301
|
+
ax.set_ylim(0, ymax + 0.01)
|
|
1302
|
+
ax.set_ylabel("mPR complexes AUC")
|
|
1303
|
+
plt.xticks(rotation=45, ha="right")
|
|
1304
|
+
|
|
1305
|
+
# Styling consistent with other plots
|
|
1306
|
+
ax.grid(visible=False, which="both", axis="both")
|
|
1307
|
+
ax.set_axisbelow(False)
|
|
1308
|
+
ax.spines["top"].set_visible(False)
|
|
1309
|
+
ax.spines["right"].set_visible(False)
|
|
1310
|
+
|
|
1311
|
+
if plot_config.get("save_plot", False):
|
|
1312
|
+
output_type = plot_config.get("output_type", "pdf")
|
|
1313
|
+
output_folder = Path(config["output_folder"])
|
|
1314
|
+
output_folder.mkdir(parents=True, exist_ok=True)
|
|
1315
|
+
output_path = output_folder / f"mpr_complexes_auc_{filter_key}.{output_type}"
|
|
1316
|
+
plt.savefig(output_path, bbox_inches="tight", format=output_type)
|
|
1317
|
+
|
|
1318
|
+
if plot_config.get("show_plot", True):
|
|
1319
|
+
plt.show()
|
|
1320
|
+
|
|
1321
|
+
plt.close(fig)
|
|
1322
|
+
return s
|
|
1323
|
+
|
|
1223
1324
|
# -----------------------------------------------------------------------------
|
|
1224
1325
|
# mPR plots (Fig. 1E and Fig. 1F)
|
|
1225
1326
|
# -----------------------------------------------------------------------------
|
|
@@ -1620,6 +1721,8 @@ def plot_mpr_complexes_multi(
|
|
|
1620
1721
|
outname=None,
|
|
1621
1722
|
linewidth=1.8,
|
|
1622
1723
|
show_filters=("all", "no_mtRibo_ETCI", "no_small_highAUPRC"),
|
|
1724
|
+
show_markers="auto",
|
|
1725
|
+
marker_size=20,
|
|
1623
1726
|
):
|
|
1624
1727
|
"""
|
|
1625
1728
|
Plot module-level PR (#complexes vs precision) for multiple datasets.
|
|
@@ -1644,6 +1747,11 @@ def plot_mpr_complexes_multi(
|
|
|
1644
1747
|
Line width for all curves
|
|
1645
1748
|
show_filters : tuple of str
|
|
1646
1749
|
Which filters to show. Default is all three.
|
|
1750
|
+
show_markers : bool or "auto"
|
|
1751
|
+
If True, draw markers on curves to make short curves visible.
|
|
1752
|
+
If "auto" (default), markers are drawn only for curves with <= 10 points.
|
|
1753
|
+
marker_size : int
|
|
1754
|
+
Scatter marker size (points^2) when markers are shown.
|
|
1647
1755
|
|
|
1648
1756
|
Returns
|
|
1649
1757
|
-------
|
|
@@ -1730,13 +1838,26 @@ def plot_mpr_complexes_multi(
|
|
|
1730
1838
|
prec_plot = precision_cutoffs[mask]
|
|
1731
1839
|
|
|
1732
1840
|
style = FILTER_STYLES.get(filter_key, {})
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1841
|
+
|
|
1842
|
+
# Decide marker visibility
|
|
1843
|
+
if show_markers == "auto":
|
|
1844
|
+
use_markers = (cov_plot.size <= 10)
|
|
1845
|
+
else:
|
|
1846
|
+
use_markers = bool(show_markers)
|
|
1847
|
+
|
|
1848
|
+
if cov_plot.size == 1:
|
|
1849
|
+
# A single point is effectively invisible as a line; draw a marker.
|
|
1850
|
+
ax.scatter(cov_plot, prec_plot, color=color, s=marker_size, zorder=3)
|
|
1851
|
+
else:
|
|
1852
|
+
ax.plot(
|
|
1853
|
+
cov_plot,
|
|
1854
|
+
prec_plot,
|
|
1855
|
+
color=color,
|
|
1856
|
+
linestyle=style.get("linestyle", "-"),
|
|
1857
|
+
linewidth=linewidth,
|
|
1858
|
+
marker=("o" if use_markers else None),
|
|
1859
|
+
markersize=(3 if use_markers else None),
|
|
1860
|
+
)
|
|
1740
1861
|
|
|
1741
1862
|
# Configure axes
|
|
1742
1863
|
ax.set_xscale("log")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pythonflex-0.3.2 → pythonflex-0.3.3}/src/pythonflex/data/dataset/liver_cell_lines_500_genes.csv
RENAMED
|
File without changes
|
{pythonflex-0.3.2 → pythonflex-0.3.3}/src/pythonflex/data/dataset/melanoma_cell_lines_500_genes.csv
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|