pylocuszoom 1.0.0__py3-none-any.whl → 1.1.1__py3-none-any.whl

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pylocuszoom
3
- Version: 1.0.0
3
+ Version: 1.1.1
4
4
  Summary: Publication-ready regional association plots with LD coloring, gene tracks, and recombination overlays
5
5
  Project-URL: Homepage, https://github.com/michael-denyer/pylocuszoom
6
6
  Project-URL: Documentation, https://github.com/michael-denyer/pylocuszoom#readme
@@ -21,6 +21,7 @@ Classifier: Topic :: Scientific/Engineering :: Visualization
21
21
  Requires-Python: >=3.10
22
22
  Requires-Dist: adjusttext>=0.8
23
23
  Requires-Dist: bokeh>=3.8.2
24
+ Requires-Dist: colorcet>=3.0.0
24
25
  Requires-Dist: kaleido>=0.2.0
25
26
  Requires-Dist: loguru>=0.7.0
26
27
  Requires-Dist: matplotlib>=3.5.0
@@ -52,7 +53,7 @@ Description-Content-Type: text/markdown
52
53
  [![Plotly](https://img.shields.io/badge/Plotly-5.15+-3F4F75.svg)](https://plotly.com/python/)
53
54
  [![Bokeh](https://img.shields.io/badge/Bokeh-3.8+-E6526F.svg)](https://bokeh.org/)
54
55
  [![Pandas](https://img.shields.io/badge/Pandas-1.4+-150458.svg)](https://pandas.pydata.org/)
55
- <img src="logo.svg" alt="pyLocusZoom logo" width="120" align="right">
56
+ <img src="https://raw.githubusercontent.com/michael-denyer/pyLocusZoom/main/logo.svg" alt="pyLocusZoom logo" width="120" align="right">
56
57
  # pyLocusZoom
57
58
 
58
59
  Designed for publication-ready GWAS visualization with regional association plots, gene tracks, eQTL, PheWAS, fine-mapping, and forest plots.
@@ -66,22 +67,24 @@ Inspired by [LocusZoom](http://locuszoom.org/) and [locuszoomr](https://github.c
66
67
  - **Multi-species support**: Built-in reference data for *Canis lupus familiaris* (CanFam3.1/CanFam4) and *Felis catus* (FelCat9), or optionally provide your own for any species
67
68
  - **LD coloring**: SNPs colored by linkage disequilibrium (R²) with lead variant
68
69
  - **Gene tracks**: Annotated gene/exon positions below the association plot
69
- - **Recombination rate**: Optional overlay across region (*Canis lupus familiaris* built-in, not shown in example image)
70
+ - **Recombination rate**: Overlay across region (*Canis lupus familiaris* built-in, or user-provided)
70
71
  - **SNP labels (matplotlib)**: Automatic labeling of top SNPs by p-value (RS IDs)
71
72
  - **Hover tooltips (Plotly and Bokeh)**: Detailed SNP data on hover
72
73
 
73
- ![Example regional association plot with LD coloring and gene track](examples/regional_plot.png)
74
- *Regional association plot with LD coloring, gene/exon track, and top SNP labels (recombination overlay disabled in example).*
74
+ ![Example regional association plot with LD coloring, gene track, and recombination overlay](https://raw.githubusercontent.com/michael-denyer/pyLocusZoom/main/examples/regional_plot_with_recomb.png)
75
+ *Regional association plot with LD coloring, gene/exon track, recombination rate overlay (blue line), and top SNP labels.*
75
76
 
76
77
  2. **Stacked plots**: Compare multiple GWAS/phenotypes vertically
77
- 3. **eQTL plot**: Expression QTL data aligned with association plots and gene tracks
78
- 4. **Fine-mapping plots**: Visualize SuSiE credible sets with posterior inclusion probabilities
79
- 5. **PheWAS plots**: Phenome-wide association study visualization across multiple phenotypes
80
- 6. **Forest plots**: Meta-analysis effect size visualization with confidence intervals
81
- 7. **Multiple backends**: matplotlib (publication-ready), plotly (interactive), bokeh (dashboard integration)
82
- 8. **Pandas and PySpark support**: Works with both Pandas and PySpark DataFrames for large-scale genomics data
83
- 9. **Convenience data file loaders**: Load and validate common GWAS, eQTL and fine-mapping file formats
84
- 10. **Automatic gene annotations**: Fetch gene/exon data from Ensembl REST API with caching (human, mouse, rat, canine, feline, and any Ensembl species)
78
+ 3. **Manhattan plots**: Genome-wide association visualization with chromosome coloring
79
+ 4. **QQ plots**: Quantile-quantile plots with confidence bands and genomic inflation factor
80
+ 5. **eQTL plot**: Expression QTL data aligned with association plots and gene tracks
81
+ 6. **Fine-mapping plots**: Visualize SuSiE credible sets with posterior inclusion probabilities
82
+ 7. **PheWAS plots**: Phenome-wide association study visualization across multiple phenotypes
83
+ 8. **Forest plots**: Meta-analysis effect size visualization with confidence intervals
84
+ 9. **Multiple backends**: matplotlib (publication-ready), plotly (interactive), bokeh (dashboard integration)
85
+ 10. **Pandas and PySpark support**: Works with both Pandas and PySpark DataFrames for large-scale genomics data
86
+ 11. **Convenience data file loaders**: Load and validate common GWAS, eQTL and fine-mapping file formats
87
+ 12. **Automatic gene annotations**: Fetch gene/exon data from Ensembl REST API with caching (human, mouse, rat, canine, feline, and any Ensembl species)
85
88
 
86
89
  ## Installation
87
90
 
@@ -107,15 +110,16 @@ conda install -c bioconda pylocuszoom
107
110
  from pylocuszoom import LocusZoomPlotter
108
111
 
109
112
  # Initialize plotter (loads reference data for canine)
110
- plotter = LocusZoomPlotter(species="canine")
113
+ plotter = LocusZoomPlotter(species="canine", auto_genes=True)
111
114
 
112
115
  # Plot with parameters passed directly
113
116
  fig = plotter.plot(
114
- gwas_df, # DataFrame with ps, p_wald, rs columns
117
+ gwas_df, # DataFrame with pos, p_value, rs columns
115
118
  chrom=1,
116
119
  start=1000000,
117
120
  end=2000000,
118
121
  lead_pos=1500000, # Highlight lead SNP
122
+ show_recombination=True, # Overlay recombination rate
119
123
  )
120
124
  fig.savefig("regional_plot.png", dpi=150)
121
125
  ```
@@ -250,7 +254,7 @@ fig = plotter.plot_stacked(
250
254
  )
251
255
  ```
252
256
 
253
- ![Example stacked plot comparing two phenotypes](examples/stacked_plot.png)
257
+ ![Example stacked plot comparing two phenotypes](https://raw.githubusercontent.com/michael-denyer/pyLocusZoom/main/examples/stacked_plot.png)
254
258
  *Stacked plot comparing two phenotypes with LD coloring and shared gene track.*
255
259
 
256
260
  ## eQTL Overlay
@@ -279,7 +283,7 @@ fig = plotter.plot_stacked(
279
283
  )
280
284
  ```
281
285
 
282
- ![Example eQTL overlay plot](examples/eqtl_overlay.png)
286
+ ![Example eQTL overlay plot](https://raw.githubusercontent.com/michael-denyer/pyLocusZoom/main/examples/eqtl_overlay.png)
283
287
  *eQTL overlay with effect direction (up/down triangles) and magnitude binning.*
284
288
 
285
289
  ## Fine-mapping Visualization
@@ -308,7 +312,7 @@ fig = plotter.plot_stacked(
308
312
  )
309
313
  ```
310
314
 
311
- ![Example fine-mapping plot](examples/finemapping_plot.png)
315
+ ![Example fine-mapping plot](https://raw.githubusercontent.com/michael-denyer/pyLocusZoom/main/examples/finemapping_plot.png)
312
316
  *Fine-mapping visualization with PIP line and credible set coloring (CS1/CS2).*
313
317
 
314
318
  ## PheWAS Plots
@@ -329,7 +333,7 @@ fig = plotter.plot_phewas(
329
333
  )
330
334
  ```
331
335
 
332
- ![Example PheWAS plot](examples/phewas_plot.png)
336
+ ![Example PheWAS plot](https://raw.githubusercontent.com/michael-denyer/pyLocusZoom/main/examples/phewas_plot.png)
333
337
  *PheWAS plot showing associations across phenotype categories with significance threshold.*
334
338
 
335
339
  ## Forest Plots
@@ -352,9 +356,115 @@ fig = plotter.plot_forest(
352
356
  )
353
357
  ```
354
358
 
355
- ![Example forest plot](examples/forest_plot.png)
359
+ ![Example forest plot](https://raw.githubusercontent.com/michael-denyer/pyLocusZoom/main/examples/forest_plot.png)
356
360
  *Forest plot with effect sizes, confidence intervals, and weight-proportional markers.*
357
361
 
362
+ ## Manhattan Plots
363
+
364
+ Create genome-wide Manhattan plots showing associations across all chromosomes:
365
+
366
+ ```python
367
+ from pylocuszoom import LocusZoomPlotter
368
+
369
+ plotter = LocusZoomPlotter(species="human")
370
+
371
+ fig = plotter.plot_manhattan(
372
+ gwas_df,
373
+ chrom_col="chrom",
374
+ pos_col="pos",
375
+ p_col="p",
376
+ significance_threshold=5e-8, # Genome-wide significance line
377
+ figsize=(12, 5),
378
+ )
379
+ fig.savefig("manhattan.png", dpi=150)
380
+ ```
381
+
382
+ ![Example Manhattan plot](https://raw.githubusercontent.com/michael-denyer/pyLocusZoom/main/examples/manhattan_plot.png)
383
+ *Manhattan plot showing genome-wide associations with chromosome coloring and significance threshold.*
384
+
385
+ Categorical Manhattan plots (PheWAS-style) are also supported:
386
+
387
+ ```python
388
+ fig = plotter.plot_manhattan(
389
+ phewas_df,
390
+ category_col="phenotype_category",
391
+ p_col="pvalue",
392
+ )
393
+ ```
394
+
395
+ ## QQ Plots
396
+
397
+ Create quantile-quantile plots to assess p-value distribution:
398
+
399
+ ```python
400
+ from pylocuszoom import LocusZoomPlotter
401
+
402
+ plotter = LocusZoomPlotter()
403
+
404
+ fig = plotter.plot_qq(
405
+ gwas_df,
406
+ p_col="p",
407
+ show_confidence_band=True, # 95% confidence band
408
+ show_lambda=True, # Genomic inflation factor in title
409
+ figsize=(6, 6),
410
+ )
411
+ fig.savefig("qq_plot.png", dpi=150)
412
+ ```
413
+
414
+ ![Example QQ plot](https://raw.githubusercontent.com/michael-denyer/pyLocusZoom/main/examples/qq_plot.png)
415
+ *QQ plot with 95% confidence band and genomic inflation factor (λ).*
416
+
417
+ ## Stacked Manhattan Plots
418
+
419
+ Compare multiple GWAS results in vertically stacked Manhattan plots:
420
+
421
+ ```python
422
+ from pylocuszoom import LocusZoomPlotter
423
+
424
+ plotter = LocusZoomPlotter()
425
+
426
+ fig = plotter.plot_manhattan_stacked(
427
+ [gwas_study1, gwas_study2, gwas_study3],
428
+ chrom_col="chrom",
429
+ pos_col="pos",
430
+ p_col="p",
431
+ panel_labels=["Study 1", "Study 2", "Study 3"],
432
+ significance_threshold=5e-8,
433
+ figsize=(12, 8),
434
+ title="Multi-study GWAS Comparison",
435
+ )
436
+ fig.savefig("manhattan_stacked.png", dpi=150)
437
+ ```
438
+
439
+ ![Example stacked Manhattan plot](https://raw.githubusercontent.com/michael-denyer/pyLocusZoom/main/examples/manhattan_stacked.png)
440
+ *Stacked Manhattan plots comparing three GWAS studies with shared chromosome axis.*
441
+
442
+ ## Manhattan and QQ Side-by-Side
443
+
444
+ Create combined Manhattan and QQ plots in a single figure:
445
+
446
+ ```python
447
+ from pylocuszoom import LocusZoomPlotter
448
+
449
+ plotter = LocusZoomPlotter()
450
+
451
+ fig = plotter.plot_manhattan_qq(
452
+ gwas_df,
453
+ chrom_col="chrom",
454
+ pos_col="pos",
455
+ p_col="p",
456
+ significance_threshold=5e-8,
457
+ show_confidence_band=True,
458
+ show_lambda=True,
459
+ figsize=(14, 5),
460
+ title="GWAS Results",
461
+ )
462
+ fig.savefig("manhattan_qq.png", dpi=150)
463
+ ```
464
+
465
+ ![Example Manhattan and QQ side-by-side](https://raw.githubusercontent.com/michael-denyer/pyLocusZoom/main/examples/manhattan_qq_sidebyside.png)
466
+ *Combined Manhattan and QQ plot showing genome-wide associations and p-value distribution.*
467
+
358
468
  ## PySpark Support
359
469
 
360
470
  For large-scale genomics data, convert PySpark DataFrames with `to_pandas()` before plotting:
@@ -0,0 +1,36 @@
1
+ pylocuszoom/__init__.py,sha256=vhYxzDWG31iCl-VlL-yxsnv4XB8drMH00JtAoQVtpuc,6108
2
+ pylocuszoom/_plotter_utils.py,sha256=ELdSOcKk2KvOo_AxEWHeutmmUS4zZMaDMmQfpQUWaF0,1541
3
+ pylocuszoom/colors.py,sha256=B28rfhWwGZ-e6Q-F43iXxC6NZpjUo0yWk4S_-vp9ZvU,7686
4
+ pylocuszoom/config.py,sha256=qjIEodI-RY71RVyQ5QmE6WXcPXU4Re_xEWiDlkEww3g,13266
5
+ pylocuszoom/ensembl.py,sha256=w2msgBoIrY79iHI3hURSbevvdFHxHyWF9Z78hXtAaBc,14296
6
+ pylocuszoom/eqtl.py,sha256=9hGcFARABQRCMN3rco0pVlFJdmlh4SLBBKSgOvdIH_U,5924
7
+ pylocuszoom/exceptions.py,sha256=nd-rWMUodW62WVV4TfcYVPQcb66xV6v9FA-_4xHb5VY,926
8
+ pylocuszoom/finemapping.py,sha256=VYQs4o4dVREXicueT1anzuENiFZk6YXb6HpbwyF0FD0,5828
9
+ pylocuszoom/forest.py,sha256=K-wBinxBOqIzsNMtZJ587e_oMhUXIXEqmEzVTUbmHSY,1161
10
+ pylocuszoom/gene_track.py,sha256=Sh0JCSdLNAAH0NQEiDVMvyXjm63PiCMq3gLvewcagvo,17277
11
+ pylocuszoom/labels.py,sha256=l4PHAR_err75Z9kTmb3a2h0eunkFj6UjzhKBUgmZTDc,3623
12
+ pylocuszoom/ld.py,sha256=64xIulpDVvbMSryWUPoCQ99Odcjwf1wejpwVr_30MLU,6412
13
+ pylocuszoom/loaders.py,sha256=KpWPBO0BCb2yrGTtgdiOqOuhx2YLmjK_ywmpr3onnx8,25156
14
+ pylocuszoom/logging.py,sha256=nZHEkbnjp8zoyWj_S-Hy9UQvUYLoMoxyiOWRozBT2dg,4987
15
+ pylocuszoom/manhattan.py,sha256=sNhPnsfsIqe1ls74D-kKMFyF_ZmaYB9Ul8qf4UMWnF0,8022
16
+ pylocuszoom/manhattan_plotter.py,sha256=1QQxaXEh5YG4x6ZIxpdhdfQPI2KuO_525qYKI7c32n4,27584
17
+ pylocuszoom/phewas.py,sha256=6g2LmwA5kmxYlHgPxJvuXIMerEqfqgsrth110Y3CgVU,968
18
+ pylocuszoom/plotter.py,sha256=mMOQxyLU3d1XJGpDJUuy71fAFm6IAnQfMZQXHgN6Mzk,54689
19
+ pylocuszoom/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ pylocuszoom/qq.py,sha256=GPIFHXYCLvhP4IUgjcU3QELLREH8r1AEYXMord8gtEo,3650
21
+ pylocuszoom/recombination.py,sha256=e11IlFRXKILEAP-vgMcbFK28zbAQ5jY-fESsisogq0o,14570
22
+ pylocuszoom/schemas.py,sha256=XxeivyRm5LGDwJw4GToxzOSdyx1yXvFYk3xgeFJ6VW0,11858
23
+ pylocuszoom/stats_plotter.py,sha256=67bgU-TXGnmVTxfTRWT3-PFemVVy6lTu4-ZlxUnwHS4,11171
24
+ pylocuszoom/utils.py,sha256=Z2P__Eau3ilF2ftuAZBm11EZ1NqCFQzfr4br9jCiJmg,6887
25
+ pylocuszoom/validation.py,sha256=3D9axjUvNXWW3Mk7dwRG38-di2P0zDpVVGF5WNSfZbk,7403
26
+ pylocuszoom/backends/__init__.py,sha256=xefVj3jVxmYwVLLY5AZtFqTPMehQxZ2qGd-Pk7_V_Bk,4267
27
+ pylocuszoom/backends/base.py,sha256=d_IqH2yGWIfQHeUCcavV4eL6V68hpNtOyGfTyb2ke0I,22628
28
+ pylocuszoom/backends/bokeh_backend.py,sha256=cubjEzNq5vHov-CeBMLgmf3SAtEET-fUUB8d_oYFgiw,29151
29
+ pylocuszoom/backends/hover.py,sha256=Hjm_jcxJL8dDxO_Ye7jeWAUcHKlbH6oO8ZfGJ2MzIFM,6564
30
+ pylocuszoom/backends/matplotlib_backend.py,sha256=9WAFLWcclj2-4WKi6bE6IPJfQ_HNoIekOE45ibBGPa0,22824
31
+ pylocuszoom/backends/plotly_backend.py,sha256=VDEZMdP7nOeFYLli-YOc_2DG00ZA6VVRNUcvT5PU0HM,39084
32
+ pylocuszoom/reference_data/__init__.py,sha256=qqHqAUt1jebGlCN3CjqW3Z-_coHVNo5K3a3bb9o83hA,109
33
+ pylocuszoom-1.1.1.dist-info/METADATA,sha256=jbJjhG60wtSjUWHU2G2t-jYzphdsuhNjC919jo_pSfg,22009
34
+ pylocuszoom-1.1.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
35
+ pylocuszoom-1.1.1.dist-info/licenses/LICENSE.md,sha256=U2y_hv8RcN5lECA3uK88irU3ODUE1TDAPictcmnP0Q4,698
36
+ pylocuszoom-1.1.1.dist-info/RECORD,,
@@ -1,31 +0,0 @@
1
- pylocuszoom/__init__.py,sha256=DNdSi6JbIQeGr6yt4G_z9NcZoY0P9ivLVbaLaOlLbRM,5894
2
- pylocuszoom/colors.py,sha256=B28rfhWwGZ-e6Q-F43iXxC6NZpjUo0yWk4S_-vp9ZvU,7686
3
- pylocuszoom/config.py,sha256=qjIEodI-RY71RVyQ5QmE6WXcPXU4Re_xEWiDlkEww3g,13266
4
- pylocuszoom/ensembl.py,sha256=q767o86FdcKn4V9aK48ESFwNI7ATlaX5tnwjZReYMEw,14436
5
- pylocuszoom/eqtl.py,sha256=9hGcFARABQRCMN3rco0pVlFJdmlh4SLBBKSgOvdIH_U,5924
6
- pylocuszoom/exceptions.py,sha256=nd-rWMUodW62WVV4TfcYVPQcb66xV6v9FA-_4xHb5VY,926
7
- pylocuszoom/finemapping.py,sha256=VYQs4o4dVREXicueT1anzuENiFZk6YXb6HpbwyF0FD0,5828
8
- pylocuszoom/forest.py,sha256=K-wBinxBOqIzsNMtZJ587e_oMhUXIXEqmEzVTUbmHSY,1161
9
- pylocuszoom/gene_track.py,sha256=nbQEC3bbqukhCosPFny5ajv6hjkV-EZe7rKbsSoGs8g,17933
10
- pylocuszoom/labels.py,sha256=Ams5WVZFNVT692BRiQ5wZcdbdNEAm5xtgRwmF5u0s_A,3492
11
- pylocuszoom/ld.py,sha256=64xIulpDVvbMSryWUPoCQ99Odcjwf1wejpwVr_30MLU,6412
12
- pylocuszoom/loaders.py,sha256=KpWPBO0BCb2yrGTtgdiOqOuhx2YLmjK_ywmpr3onnx8,25156
13
- pylocuszoom/logging.py,sha256=nZHEkbnjp8zoyWj_S-Hy9UQvUYLoMoxyiOWRozBT2dg,4987
14
- pylocuszoom/phewas.py,sha256=6g2LmwA5kmxYlHgPxJvuXIMerEqfqgsrth110Y3CgVU,968
15
- pylocuszoom/plotter.py,sha256=7rWsBXbLg-WSjmK474FU5KbzviidXC-cJGFkMMHomAg,54980
16
- pylocuszoom/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
- pylocuszoom/recombination.py,sha256=97GGBLDLTlQSRMp5sLOna3mCeRxeJiiWPHrw4dBRjQs,14546
18
- pylocuszoom/schemas.py,sha256=XxeivyRm5LGDwJw4GToxzOSdyx1yXvFYk3xgeFJ6VW0,11858
19
- pylocuszoom/utils.py,sha256=Z2P__Eau3ilF2ftuAZBm11EZ1NqCFQzfr4br9jCiJmg,6887
20
- pylocuszoom/validation.py,sha256=3D9axjUvNXWW3Mk7dwRG38-di2P0zDpVVGF5WNSfZbk,7403
21
- pylocuszoom/backends/__init__.py,sha256=xefVj3jVxmYwVLLY5AZtFqTPMehQxZ2qGd-Pk7_V_Bk,4267
22
- pylocuszoom/backends/base.py,sha256=PBdm9t4f_qFDMkYR5z3edW4DvpuQSCAXuaxs2qjAeH0,21034
23
- pylocuszoom/backends/bokeh_backend.py,sha256=11zRhXH2guUHiaYXyd7l2IDAv6uawdRAv6dyGPkHmJc,25512
24
- pylocuszoom/backends/hover.py,sha256=Hjm_jcxJL8dDxO_Ye7jeWAUcHKlbH6oO8ZfGJ2MzIFM,6564
25
- pylocuszoom/backends/matplotlib_backend.py,sha256=098ITnvNrBTaEztqez_7D0sZ_rKAYIxS6EDR5Yxt8is,20924
26
- pylocuszoom/backends/plotly_backend.py,sha256=A6ZuHw0wVZaIIA6FgYJ4SH-Sz59tHOtnGUl-e-2VzZM,30574
27
- pylocuszoom/reference_data/__init__.py,sha256=qqHqAUt1jebGlCN3CjqW3Z-_coHVNo5K3a3bb9o83hA,109
28
- pylocuszoom-1.0.0.dist-info/METADATA,sha256=OMU09xbn6MMuvw8rPy19aMUiN40rp9Vl69QvqU7nwc4,18390
29
- pylocuszoom-1.0.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
30
- pylocuszoom-1.0.0.dist-info/licenses/LICENSE.md,sha256=U2y_hv8RcN5lECA3uK88irU3ODUE1TDAPictcmnP0Q4,698
31
- pylocuszoom-1.0.0.dist-info/RECORD,,