pylocuszoom 0.1.0__tar.gz → 0.3.0__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.
- pylocuszoom-0.3.0/CHANGELOG.md +86 -0
- pylocuszoom-0.3.0/CONTRIBUTING.md +114 -0
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/PKG-INFO +36 -27
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/README.md +34 -23
- pylocuszoom-0.3.0/bioconda/meta.yaml +54 -0
- pylocuszoom-0.3.0/examples/eqtl_overlay.png +0 -0
- pylocuszoom-0.3.0/examples/finemapping_plot.png +0 -0
- pylocuszoom-0.3.0/examples/generate_readme_plots.py +235 -0
- pylocuszoom-0.3.0/examples/getting_started.ipynb +1007 -0
- pylocuszoom-0.3.0/examples/regional_plot.png +0 -0
- pylocuszoom-0.3.0/examples/stacked_plot.png +0 -0
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/pyproject.toml +7 -5
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/__init__.py +39 -20
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/backends/__init__.py +1 -5
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/backends/base.py +3 -1
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/backends/bokeh_backend.py +220 -51
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/backends/matplotlib_backend.py +35 -8
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/backends/plotly_backend.py +273 -32
- pylocuszoom-0.3.0/src/pylocuszoom/colors.py +239 -0
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/eqtl.py +3 -2
- pylocuszoom-0.3.0/src/pylocuszoom/finemapping.py +223 -0
- pylocuszoom-0.3.0/src/pylocuszoom/gene_track.py +532 -0
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/labels.py +32 -33
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/ld.py +8 -7
- pylocuszoom-0.3.0/src/pylocuszoom/plotter.py +1186 -0
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/recombination.py +14 -14
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/utils.py +3 -1
- pylocuszoom-0.3.0/tests/test_finemapping.py +153 -0
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/tests/test_labels.py +4 -4
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/tests/test_ld.py +26 -6
- pylocuszoom-0.3.0/tests/test_notebook_backends.py +457 -0
- pylocuszoom-0.3.0/tests/test_plotter.py +529 -0
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/uv.lock +239 -8
- pylocuszoom-0.1.0/examples/getting_started.ipynb +0 -351
- pylocuszoom-0.1.0/src/pylocuszoom/colors.py +0 -107
- pylocuszoom-0.1.0/src/pylocuszoom/gene_track.py +0 -311
- pylocuszoom-0.1.0/src/pylocuszoom/plotter.py +0 -733
- pylocuszoom-0.1.0/tests/test_plotter.py +0 -257
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/.github/workflows/ci.yml +0 -0
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/.github/workflows/publish.yml +0 -0
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/.gitignore +0 -0
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/LICENSE.md +0 -0
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/docs/ARCHITECTURE.md +0 -0
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/logo.svg +0 -0
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/logging.py +0 -0
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/reference_data/__init__.py +0 -0
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/tests/conftest.py +0 -0
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/tests/test_colors.py +0 -0
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/tests/test_gene_track.py +0 -0
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/tests/test_logging.py +0 -0
- {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/tests/test_recombination.py +0 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.3.0] - 2026-01-26
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Bioconda recipe for conda installation
|
|
12
|
+
- `adjustText` moved to default dependencies (was optional)
|
|
13
|
+
- **Interactive plotly backend** - use `backend="plotly"` for hover tooltips and pan/zoom
|
|
14
|
+
- **Interactive bokeh backend** - use `backend="bokeh"` for dashboard-ready plots
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- `plot()` and `plot_stacked()` now use backend protocol for all rendering (scatter, line, axes, layout)
|
|
18
|
+
- **Gene track now works with all backends** (plotly, bokeh, matplotlib)
|
|
19
|
+
- **Recombination overlay now works with all backends** - secondary y-axis with rate line and fill
|
|
20
|
+
- **LD legend now works with all backends** - r² color scale (lead SNP highlighted in plot, not legend)
|
|
21
|
+
- SNP labels remain matplotlib-only (interactive backends use hover tooltips instead)
|
|
22
|
+
- Default `genomewide_threshold` changed from 5e-7 to 5e-8 (standard GWAS significance)
|
|
23
|
+
- Gene track strand colors: forward strand now goldenrod (#DAA520), reverse strand light blue (#6BB3FF)
|
|
24
|
+
- Gene track directional arrows: black for forward, dark grey for reverse
|
|
25
|
+
- Added panel spacing (hspace=0.1) between stacked/fine-mapping panels for visual separation
|
|
26
|
+
- Tightened gene track internal spacing for more compact layout
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
- Bokeh backend `x_range=None` error when creating figures with shared x-axis
|
|
30
|
+
- Bokeh backend `legend_label=None` error in scatter plots
|
|
31
|
+
- Bokeh backend LD legend not rendering (empty scatter plots don't create legend glyphs)
|
|
32
|
+
- Bokeh backend deprecated `FuncTickFormatter` replaced with `CustomJSTickFormatter`
|
|
33
|
+
- Bokeh backend deprecated `circle()` method replaced with `scatter(marker=...)`
|
|
34
|
+
- Bokeh backend `FIXED_SIZING_MODE` validation warning in column layouts
|
|
35
|
+
|
|
36
|
+
## [0.2.0] - 2026-01-26
|
|
37
|
+
|
|
38
|
+
### Added
|
|
39
|
+
- Fine-mapping/SuSiE visualization with credible set coloring
|
|
40
|
+
- Example plots in `examples/` directory
|
|
41
|
+
- Plot generation script for documentation
|
|
42
|
+
|
|
43
|
+
### Fixed
|
|
44
|
+
- Ruff linting and formatting errors
|
|
45
|
+
- Bokeh security vulnerability (bumped to >= 3.8.2)
|
|
46
|
+
- `plot()` KeyError when `rs_col` column missing with `ld_reference_file` provided
|
|
47
|
+
- `plot_stacked()` now validates eQTL DataFrame columns before use
|
|
48
|
+
- `plot_stacked()` now validates list lengths for `lead_positions`, `panel_labels`, and `ld_reference_files`
|
|
49
|
+
- `calculate_ld()` docstring now documents `ValidationError` for missing PLINK files
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
- Minimum Python version bumped to 3.10 (required by bokeh 3.8.2)
|
|
53
|
+
- Renamed species terminology: "dog" → "canine", "cat" → "feline"
|
|
54
|
+
- Clarified interactive backend status in README (coming soon)
|
|
55
|
+
|
|
56
|
+
## [0.1.0] - 2026-01-26
|
|
57
|
+
|
|
58
|
+
### Added
|
|
59
|
+
- Initial release of pyLocusZoom
|
|
60
|
+
- Regional association plots with LD coloring
|
|
61
|
+
- Gene and exon track visualization
|
|
62
|
+
- Recombination rate overlay (canine only)
|
|
63
|
+
- Automatic SNP labeling with adjustText
|
|
64
|
+
- Species support: Canine (CanFam3.1/CanFam4), Feline (FelCat9), custom
|
|
65
|
+
- CanFam4 coordinate liftover via pyliftover
|
|
66
|
+
- Stacked plots for multi-GWAS comparison
|
|
67
|
+
- eQTL overlay panel support
|
|
68
|
+
- PySpark DataFrame support
|
|
69
|
+
- Backend infrastructure for matplotlib, plotly, bokeh (matplotlib only active)
|
|
70
|
+
- Logging via loguru
|
|
71
|
+
- Comprehensive test suite
|
|
72
|
+
|
|
73
|
+
### Dependencies
|
|
74
|
+
- matplotlib >= 3.5.0
|
|
75
|
+
- pandas >= 1.4.0
|
|
76
|
+
- numpy >= 1.21.0
|
|
77
|
+
- loguru >= 0.7.0
|
|
78
|
+
- pyliftover >= 0.4
|
|
79
|
+
- plotly >= 5.0.0
|
|
80
|
+
- bokeh >= 3.8.2
|
|
81
|
+
- kaleido >= 0.2.0
|
|
82
|
+
|
|
83
|
+
[Unreleased]: https://github.com/michael-denyer/pyLocusZoom/compare/v0.3.0...HEAD
|
|
84
|
+
[0.3.0]: https://github.com/michael-denyer/pyLocusZoom/compare/v0.2.0...v0.3.0
|
|
85
|
+
[0.2.0]: https://github.com/michael-denyer/pyLocusZoom/compare/v0.1.0...v0.2.0
|
|
86
|
+
[0.1.0]: https://github.com/michael-denyer/pyLocusZoom/releases/tag/v0.1.0
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Contributing to pyLocusZoom
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to pyLocusZoom!
|
|
4
|
+
|
|
5
|
+
## Development Setup
|
|
6
|
+
|
|
7
|
+
1. Clone the repository:
|
|
8
|
+
```bash
|
|
9
|
+
git clone https://github.com/michael-denyer/pyLocusZoom.git
|
|
10
|
+
cd pyLocusZoom
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
2. Install dependencies with uv:
|
|
14
|
+
```bash
|
|
15
|
+
uv sync --all-extras
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
3. Run tests:
|
|
19
|
+
```bash
|
|
20
|
+
uv run python -m pytest tests/ -v
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
4. Run linting:
|
|
24
|
+
```bash
|
|
25
|
+
uv run ruff check src/
|
|
26
|
+
uv run ruff format --check src/ tests/
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Code Style
|
|
30
|
+
|
|
31
|
+
- Follow [PEP 8](https://peps.python.org/pep-0008/) guidelines
|
|
32
|
+
- Use [ruff](https://github.com/astral-sh/ruff) for linting and formatting
|
|
33
|
+
- Maximum line length: 88 characters
|
|
34
|
+
- Use Google-style docstrings
|
|
35
|
+
|
|
36
|
+
### Docstring Example
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
def function_name(param1: str, param2: int = 10) -> bool:
|
|
40
|
+
"""Short one-line description.
|
|
41
|
+
|
|
42
|
+
Longer description if needed.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
param1: Description of first parameter.
|
|
46
|
+
param2: Description of second parameter.
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
Description of return value.
|
|
50
|
+
|
|
51
|
+
Raises:
|
|
52
|
+
ValueError: When param1 is empty.
|
|
53
|
+
"""
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Pull Request Process
|
|
57
|
+
|
|
58
|
+
1. Fork the repository
|
|
59
|
+
2. Create a feature branch: `git checkout -b feature/your-feature`
|
|
60
|
+
3. Make your changes
|
|
61
|
+
4. Run tests and linting:
|
|
62
|
+
```bash
|
|
63
|
+
uv run python -m pytest tests/ -v
|
|
64
|
+
uv run ruff check src/
|
|
65
|
+
uv run ruff format src/ tests/
|
|
66
|
+
```
|
|
67
|
+
5. Commit with a descriptive message
|
|
68
|
+
6. Push and create a pull request
|
|
69
|
+
|
|
70
|
+
## Testing
|
|
71
|
+
|
|
72
|
+
- Write tests for new functionality
|
|
73
|
+
- Use pytest fixtures from `tests/conftest.py`
|
|
74
|
+
- Mock external dependencies (PLINK, network calls)
|
|
75
|
+
- Aim for test coverage of new code
|
|
76
|
+
|
|
77
|
+
### Running Tests
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# All tests
|
|
81
|
+
uv run python -m pytest tests/ -v
|
|
82
|
+
|
|
83
|
+
# Specific test file
|
|
84
|
+
uv run python -m pytest tests/test_plotter.py -v
|
|
85
|
+
|
|
86
|
+
# With coverage
|
|
87
|
+
uv run python -m pytest tests/ --cov=pylocuszoom --cov-report=html
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Architecture
|
|
91
|
+
|
|
92
|
+
See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for project structure.
|
|
93
|
+
|
|
94
|
+
### Key Modules
|
|
95
|
+
|
|
96
|
+
| Module | Purpose |
|
|
97
|
+
|--------|---------|
|
|
98
|
+
| `plotter.py` | Main LocusZoomPlotter class |
|
|
99
|
+
| `backends/` | Rendering backends (matplotlib, plotly, bokeh) |
|
|
100
|
+
| `ld.py` | PLINK LD calculation |
|
|
101
|
+
| `gene_track.py` | Gene/exon visualization |
|
|
102
|
+
| `recombination.py` | Recombination map handling |
|
|
103
|
+
| `eqtl.py` | eQTL data support |
|
|
104
|
+
|
|
105
|
+
## Reporting Issues
|
|
106
|
+
|
|
107
|
+
- Use GitHub Issues
|
|
108
|
+
- Include Python version, OS, and package versions
|
|
109
|
+
- Provide a minimal reproducible example
|
|
110
|
+
- Include full error traceback
|
|
111
|
+
|
|
112
|
+
## License
|
|
113
|
+
|
|
114
|
+
By contributing, you agree that your contributions will be licensed under the GPL-3.0-or-later license.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pylocuszoom
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Regional association plots for GWAS results with LD coloring, gene tracks, and recombination rate overlays
|
|
5
5
|
Project-URL: Homepage, https://github.com/michael-denyer/pylocuszoom
|
|
6
6
|
Project-URL: Documentation, https://github.com/michael-denyer/pylocuszoom#readme
|
|
@@ -19,6 +19,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
19
19
|
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
20
20
|
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
21
21
|
Requires-Python: >=3.10
|
|
22
|
+
Requires-Dist: adjusttext>=0.8
|
|
22
23
|
Requires-Dist: bokeh>=3.8.2
|
|
23
24
|
Requires-Dist: kaleido>=0.2.0
|
|
24
25
|
Requires-Dist: loguru>=0.7.0
|
|
@@ -28,14 +29,11 @@ Requires-Dist: pandas>=1.4.0
|
|
|
28
29
|
Requires-Dist: plotly>=5.0.0
|
|
29
30
|
Requires-Dist: pyliftover>=0.4
|
|
30
31
|
Provides-Extra: all
|
|
31
|
-
Requires-Dist: adjusttext>=0.8; extra == 'all'
|
|
32
32
|
Requires-Dist: pyspark>=3.0.0; extra == 'all'
|
|
33
33
|
Provides-Extra: dev
|
|
34
34
|
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
|
|
35
35
|
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
36
36
|
Requires-Dist: ruff>=0.1.0; extra == 'dev'
|
|
37
|
-
Provides-Extra: labels
|
|
38
|
-
Requires-Dist: adjusttext>=0.8; extra == 'labels'
|
|
39
37
|
Provides-Extra: spark
|
|
40
38
|
Requires-Dist: pyspark>=3.0.0; extra == 'spark'
|
|
41
39
|
Description-Content-Type: text/markdown
|
|
@@ -71,16 +69,24 @@ Inspired by [LocusZoom](http://locuszoom.org/) and [locuszoomr](https://github.c
|
|
|
71
69
|
- **eQTL overlay**: Expression QTL data as separate panel
|
|
72
70
|
- **PySpark support**: Handles large-scale genomics DataFrames
|
|
73
71
|
|
|
72
|
+

|
|
73
|
+
|
|
74
74
|
## Installation
|
|
75
75
|
|
|
76
|
+
```bash
|
|
77
|
+
pip install pylocuszoom
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Or with uv:
|
|
81
|
+
|
|
76
82
|
```bash
|
|
77
83
|
uv add pylocuszoom
|
|
78
84
|
```
|
|
79
85
|
|
|
80
|
-
Or with
|
|
86
|
+
Or with conda (Bioconda):
|
|
81
87
|
|
|
82
88
|
```bash
|
|
83
|
-
|
|
89
|
+
conda install -c bioconda pylocuszoom
|
|
84
90
|
```
|
|
85
91
|
|
|
86
92
|
## Quick Start
|
|
@@ -88,8 +94,8 @@ pip install pylocuszoom
|
|
|
88
94
|
```python
|
|
89
95
|
from pylocuszoom import LocusZoomPlotter
|
|
90
96
|
|
|
91
|
-
# Initialize plotter (loads reference data for
|
|
92
|
-
plotter = LocusZoomPlotter(species="
|
|
97
|
+
# Initialize plotter (loads reference data for canine)
|
|
98
|
+
plotter = LocusZoomPlotter(species="canine")
|
|
93
99
|
|
|
94
100
|
# Create regional plot
|
|
95
101
|
fig = plotter.plot(
|
|
@@ -109,7 +115,7 @@ fig.savefig("regional_plot.png", dpi=150)
|
|
|
109
115
|
from pylocuszoom import LocusZoomPlotter
|
|
110
116
|
|
|
111
117
|
plotter = LocusZoomPlotter(
|
|
112
|
-
species="
|
|
118
|
+
species="canine", # or "feline", or None for custom
|
|
113
119
|
plink_path="/path/to/plink", # Optional, auto-detects if on PATH
|
|
114
120
|
)
|
|
115
121
|
|
|
@@ -134,10 +140,10 @@ fig = plotter.plot(
|
|
|
134
140
|
|
|
135
141
|
## Genome Builds
|
|
136
142
|
|
|
137
|
-
The default genome build for
|
|
143
|
+
The default genome build for canine is CanFam3.1. For CanFam4 data:
|
|
138
144
|
|
|
139
145
|
```python
|
|
140
|
-
plotter = LocusZoomPlotter(species="
|
|
146
|
+
plotter = LocusZoomPlotter(species="canine", genome_build="canfam4")
|
|
141
147
|
```
|
|
142
148
|
|
|
143
149
|
Recombination maps are automatically lifted over from CanFam3.1 to CanFam4 coordinates using the UCSC liftOver chain file.
|
|
@@ -145,8 +151,8 @@ Recombination maps are automatically lifted over from CanFam3.1 to CanFam4 coord
|
|
|
145
151
|
## Using with Other Species
|
|
146
152
|
|
|
147
153
|
```python
|
|
148
|
-
#
|
|
149
|
-
plotter = LocusZoomPlotter(species="
|
|
154
|
+
# Feline (LD and gene tracks, user provides recombination data)
|
|
155
|
+
plotter = LocusZoomPlotter(species="feline")
|
|
150
156
|
|
|
151
157
|
# Custom species (provide all reference data)
|
|
152
158
|
plotter = LocusZoomPlotter(
|
|
@@ -163,27 +169,30 @@ fig = plotter.plot(
|
|
|
163
169
|
)
|
|
164
170
|
```
|
|
165
171
|
|
|
166
|
-
##
|
|
172
|
+
## Backends
|
|
167
173
|
|
|
168
|
-
|
|
174
|
+
pyLocusZoom supports multiple rendering backends:
|
|
169
175
|
|
|
170
176
|
```python
|
|
171
177
|
# Static publication-quality plot (default)
|
|
172
|
-
|
|
173
|
-
fig = plotter.plot(gwas_df, chrom=1, start=1000000, end=2000000)
|
|
178
|
+
fig = plotter.plot(gwas_df, chrom=1, start=1000000, end=2000000, backend="matplotlib")
|
|
174
179
|
fig.savefig("plot.png", dpi=150)
|
|
175
180
|
|
|
176
|
-
# Interactive
|
|
177
|
-
|
|
178
|
-
fig = plotter.plot(gwas_df, chrom=1, start=1000000, end=2000000)
|
|
181
|
+
# Interactive Plotly (hover tooltips, pan/zoom)
|
|
182
|
+
fig = plotter.plot(gwas_df, chrom=1, start=1000000, end=2000000, backend="plotly")
|
|
179
183
|
fig.write_html("plot.html")
|
|
180
184
|
|
|
181
|
-
# Interactive
|
|
182
|
-
|
|
183
|
-
fig = plotter.plot(gwas_df, chrom=1, start=1000000, end=2000000)
|
|
185
|
+
# Interactive Bokeh (dashboard-ready)
|
|
186
|
+
fig = plotter.plot(gwas_df, chrom=1, start=1000000, end=2000000, backend="bokeh")
|
|
184
187
|
```
|
|
185
188
|
|
|
186
|
-
|
|
189
|
+
| Backend | Output | Best For |
|
|
190
|
+
|---------|--------|----------|
|
|
191
|
+
| `matplotlib` | Static PNG/PDF/SVG | Publications, presentations |
|
|
192
|
+
| `plotly` | Interactive HTML | Web reports, data exploration |
|
|
193
|
+
| `bokeh` | Interactive HTML | Dashboards, web apps |
|
|
194
|
+
|
|
195
|
+
> **Note:** All backends support gene track, recombination overlay, and LD legend. SNP labels (auto-positioned with adjustText) are matplotlib-only.
|
|
187
196
|
|
|
188
197
|
## Stacked Plots
|
|
189
198
|
|
|
@@ -324,14 +333,14 @@ chr pos rate cM
|
|
|
324
333
|
|
|
325
334
|
## Reference Data
|
|
326
335
|
|
|
327
|
-
|
|
336
|
+
Canine recombination maps are downloaded from [Campbell et al. 2016](https://github.com/cflerin/dog_recombination) on first use.
|
|
328
337
|
|
|
329
338
|
To manually download:
|
|
330
339
|
|
|
331
340
|
```python
|
|
332
|
-
from pylocuszoom import
|
|
341
|
+
from pylocuszoom import download_canine_recombination_maps
|
|
333
342
|
|
|
334
|
-
|
|
343
|
+
download_canine_recombination_maps()
|
|
335
344
|
```
|
|
336
345
|
|
|
337
346
|
## Logging
|
|
@@ -29,16 +29,24 @@ Inspired by [LocusZoom](http://locuszoom.org/) and [locuszoomr](https://github.c
|
|
|
29
29
|
- **eQTL overlay**: Expression QTL data as separate panel
|
|
30
30
|
- **PySpark support**: Handles large-scale genomics DataFrames
|
|
31
31
|
|
|
32
|
+

|
|
33
|
+
|
|
32
34
|
## Installation
|
|
33
35
|
|
|
36
|
+
```bash
|
|
37
|
+
pip install pylocuszoom
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Or with uv:
|
|
41
|
+
|
|
34
42
|
```bash
|
|
35
43
|
uv add pylocuszoom
|
|
36
44
|
```
|
|
37
45
|
|
|
38
|
-
Or with
|
|
46
|
+
Or with conda (Bioconda):
|
|
39
47
|
|
|
40
48
|
```bash
|
|
41
|
-
|
|
49
|
+
conda install -c bioconda pylocuszoom
|
|
42
50
|
```
|
|
43
51
|
|
|
44
52
|
## Quick Start
|
|
@@ -46,8 +54,8 @@ pip install pylocuszoom
|
|
|
46
54
|
```python
|
|
47
55
|
from pylocuszoom import LocusZoomPlotter
|
|
48
56
|
|
|
49
|
-
# Initialize plotter (loads reference data for
|
|
50
|
-
plotter = LocusZoomPlotter(species="
|
|
57
|
+
# Initialize plotter (loads reference data for canine)
|
|
58
|
+
plotter = LocusZoomPlotter(species="canine")
|
|
51
59
|
|
|
52
60
|
# Create regional plot
|
|
53
61
|
fig = plotter.plot(
|
|
@@ -67,7 +75,7 @@ fig.savefig("regional_plot.png", dpi=150)
|
|
|
67
75
|
from pylocuszoom import LocusZoomPlotter
|
|
68
76
|
|
|
69
77
|
plotter = LocusZoomPlotter(
|
|
70
|
-
species="
|
|
78
|
+
species="canine", # or "feline", or None for custom
|
|
71
79
|
plink_path="/path/to/plink", # Optional, auto-detects if on PATH
|
|
72
80
|
)
|
|
73
81
|
|
|
@@ -92,10 +100,10 @@ fig = plotter.plot(
|
|
|
92
100
|
|
|
93
101
|
## Genome Builds
|
|
94
102
|
|
|
95
|
-
The default genome build for
|
|
103
|
+
The default genome build for canine is CanFam3.1. For CanFam4 data:
|
|
96
104
|
|
|
97
105
|
```python
|
|
98
|
-
plotter = LocusZoomPlotter(species="
|
|
106
|
+
plotter = LocusZoomPlotter(species="canine", genome_build="canfam4")
|
|
99
107
|
```
|
|
100
108
|
|
|
101
109
|
Recombination maps are automatically lifted over from CanFam3.1 to CanFam4 coordinates using the UCSC liftOver chain file.
|
|
@@ -103,8 +111,8 @@ Recombination maps are automatically lifted over from CanFam3.1 to CanFam4 coord
|
|
|
103
111
|
## Using with Other Species
|
|
104
112
|
|
|
105
113
|
```python
|
|
106
|
-
#
|
|
107
|
-
plotter = LocusZoomPlotter(species="
|
|
114
|
+
# Feline (LD and gene tracks, user provides recombination data)
|
|
115
|
+
plotter = LocusZoomPlotter(species="feline")
|
|
108
116
|
|
|
109
117
|
# Custom species (provide all reference data)
|
|
110
118
|
plotter = LocusZoomPlotter(
|
|
@@ -121,27 +129,30 @@ fig = plotter.plot(
|
|
|
121
129
|
)
|
|
122
130
|
```
|
|
123
131
|
|
|
124
|
-
##
|
|
132
|
+
## Backends
|
|
125
133
|
|
|
126
|
-
|
|
134
|
+
pyLocusZoom supports multiple rendering backends:
|
|
127
135
|
|
|
128
136
|
```python
|
|
129
137
|
# Static publication-quality plot (default)
|
|
130
|
-
|
|
131
|
-
fig = plotter.plot(gwas_df, chrom=1, start=1000000, end=2000000)
|
|
138
|
+
fig = plotter.plot(gwas_df, chrom=1, start=1000000, end=2000000, backend="matplotlib")
|
|
132
139
|
fig.savefig("plot.png", dpi=150)
|
|
133
140
|
|
|
134
|
-
# Interactive
|
|
135
|
-
|
|
136
|
-
fig = plotter.plot(gwas_df, chrom=1, start=1000000, end=2000000)
|
|
141
|
+
# Interactive Plotly (hover tooltips, pan/zoom)
|
|
142
|
+
fig = plotter.plot(gwas_df, chrom=1, start=1000000, end=2000000, backend="plotly")
|
|
137
143
|
fig.write_html("plot.html")
|
|
138
144
|
|
|
139
|
-
# Interactive
|
|
140
|
-
|
|
141
|
-
fig = plotter.plot(gwas_df, chrom=1, start=1000000, end=2000000)
|
|
145
|
+
# Interactive Bokeh (dashboard-ready)
|
|
146
|
+
fig = plotter.plot(gwas_df, chrom=1, start=1000000, end=2000000, backend="bokeh")
|
|
142
147
|
```
|
|
143
148
|
|
|
144
|
-
|
|
149
|
+
| Backend | Output | Best For |
|
|
150
|
+
|---------|--------|----------|
|
|
151
|
+
| `matplotlib` | Static PNG/PDF/SVG | Publications, presentations |
|
|
152
|
+
| `plotly` | Interactive HTML | Web reports, data exploration |
|
|
153
|
+
| `bokeh` | Interactive HTML | Dashboards, web apps |
|
|
154
|
+
|
|
155
|
+
> **Note:** All backends support gene track, recombination overlay, and LD legend. SNP labels (auto-positioned with adjustText) are matplotlib-only.
|
|
145
156
|
|
|
146
157
|
## Stacked Plots
|
|
147
158
|
|
|
@@ -282,14 +293,14 @@ chr pos rate cM
|
|
|
282
293
|
|
|
283
294
|
## Reference Data
|
|
284
295
|
|
|
285
|
-
|
|
296
|
+
Canine recombination maps are downloaded from [Campbell et al. 2016](https://github.com/cflerin/dog_recombination) on first use.
|
|
286
297
|
|
|
287
298
|
To manually download:
|
|
288
299
|
|
|
289
300
|
```python
|
|
290
|
-
from pylocuszoom import
|
|
301
|
+
from pylocuszoom import download_canine_recombination_maps
|
|
291
302
|
|
|
292
|
-
|
|
303
|
+
download_canine_recombination_maps()
|
|
293
304
|
```
|
|
294
305
|
|
|
295
306
|
## Logging
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{% set name = "pylocuszoom" %}
|
|
2
|
+
{% set version = "0.3.0" %}
|
|
3
|
+
|
|
4
|
+
package:
|
|
5
|
+
name: {{ name|lower }}
|
|
6
|
+
version: {{ version }}
|
|
7
|
+
|
|
8
|
+
source:
|
|
9
|
+
url: https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/{{ name }}-{{ version }}.tar.gz
|
|
10
|
+
sha256: REPLACE_WITH_SHA256_AFTER_PYPI_PUBLISH
|
|
11
|
+
|
|
12
|
+
build:
|
|
13
|
+
noarch: python
|
|
14
|
+
number: 0
|
|
15
|
+
script: {{ PYTHON }} -m pip install . -vv --no-deps --no-build-isolation
|
|
16
|
+
|
|
17
|
+
requirements:
|
|
18
|
+
host:
|
|
19
|
+
- python >=3.10
|
|
20
|
+
- pip
|
|
21
|
+
- hatchling
|
|
22
|
+
run:
|
|
23
|
+
- python >=3.10
|
|
24
|
+
- matplotlib-base >=3.5.0
|
|
25
|
+
- pandas >=1.4.0
|
|
26
|
+
- numpy >=1.21.0
|
|
27
|
+
- loguru >=0.7.0
|
|
28
|
+
- pyliftover >=0.4
|
|
29
|
+
- plotly >=5.0.0
|
|
30
|
+
- bokeh >=3.8.2
|
|
31
|
+
- python-kaleido >=0.2.0
|
|
32
|
+
- adjusttext >=0.8
|
|
33
|
+
|
|
34
|
+
test:
|
|
35
|
+
imports:
|
|
36
|
+
- pylocuszoom
|
|
37
|
+
commands:
|
|
38
|
+
- python -c "from pylocuszoom import LocusZoomPlotter"
|
|
39
|
+
|
|
40
|
+
about:
|
|
41
|
+
home: https://github.com/michael-denyer/pylocuszoom
|
|
42
|
+
license: GPL-3.0-or-later
|
|
43
|
+
license_family: GPL3
|
|
44
|
+
license_file: LICENSE
|
|
45
|
+
summary: Regional association plots for GWAS results with LD coloring
|
|
46
|
+
description: |
|
|
47
|
+
pyLocusZoom creates publication-quality regional association plots
|
|
48
|
+
for GWAS results with LD coloring, gene tracks, and recombination
|
|
49
|
+
rate overlays. Supports canine, feline, and custom species.
|
|
50
|
+
dev_url: https://github.com/michael-denyer/pylocuszoom
|
|
51
|
+
|
|
52
|
+
extra:
|
|
53
|
+
recipe-maintainers:
|
|
54
|
+
- michael-denyer
|
|
Binary file
|
|
Binary file
|