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.
Files changed (51) hide show
  1. pylocuszoom-0.3.0/CHANGELOG.md +86 -0
  2. pylocuszoom-0.3.0/CONTRIBUTING.md +114 -0
  3. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/PKG-INFO +36 -27
  4. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/README.md +34 -23
  5. pylocuszoom-0.3.0/bioconda/meta.yaml +54 -0
  6. pylocuszoom-0.3.0/examples/eqtl_overlay.png +0 -0
  7. pylocuszoom-0.3.0/examples/finemapping_plot.png +0 -0
  8. pylocuszoom-0.3.0/examples/generate_readme_plots.py +235 -0
  9. pylocuszoom-0.3.0/examples/getting_started.ipynb +1007 -0
  10. pylocuszoom-0.3.0/examples/regional_plot.png +0 -0
  11. pylocuszoom-0.3.0/examples/stacked_plot.png +0 -0
  12. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/pyproject.toml +7 -5
  13. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/__init__.py +39 -20
  14. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/backends/__init__.py +1 -5
  15. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/backends/base.py +3 -1
  16. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/backends/bokeh_backend.py +220 -51
  17. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/backends/matplotlib_backend.py +35 -8
  18. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/backends/plotly_backend.py +273 -32
  19. pylocuszoom-0.3.0/src/pylocuszoom/colors.py +239 -0
  20. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/eqtl.py +3 -2
  21. pylocuszoom-0.3.0/src/pylocuszoom/finemapping.py +223 -0
  22. pylocuszoom-0.3.0/src/pylocuszoom/gene_track.py +532 -0
  23. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/labels.py +32 -33
  24. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/ld.py +8 -7
  25. pylocuszoom-0.3.0/src/pylocuszoom/plotter.py +1186 -0
  26. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/recombination.py +14 -14
  27. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/utils.py +3 -1
  28. pylocuszoom-0.3.0/tests/test_finemapping.py +153 -0
  29. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/tests/test_labels.py +4 -4
  30. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/tests/test_ld.py +26 -6
  31. pylocuszoom-0.3.0/tests/test_notebook_backends.py +457 -0
  32. pylocuszoom-0.3.0/tests/test_plotter.py +529 -0
  33. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/uv.lock +239 -8
  34. pylocuszoom-0.1.0/examples/getting_started.ipynb +0 -351
  35. pylocuszoom-0.1.0/src/pylocuszoom/colors.py +0 -107
  36. pylocuszoom-0.1.0/src/pylocuszoom/gene_track.py +0 -311
  37. pylocuszoom-0.1.0/src/pylocuszoom/plotter.py +0 -733
  38. pylocuszoom-0.1.0/tests/test_plotter.py +0 -257
  39. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/.github/workflows/ci.yml +0 -0
  40. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/.github/workflows/publish.yml +0 -0
  41. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/.gitignore +0 -0
  42. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/LICENSE.md +0 -0
  43. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/docs/ARCHITECTURE.md +0 -0
  44. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/logo.svg +0 -0
  45. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/logging.py +0 -0
  46. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/src/pylocuszoom/reference_data/__init__.py +0 -0
  47. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/tests/conftest.py +0 -0
  48. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/tests/test_colors.py +0 -0
  49. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/tests/test_gene_track.py +0 -0
  50. {pylocuszoom-0.1.0 → pylocuszoom-0.3.0}/tests/test_logging.py +0 -0
  51. {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.1.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
+ ![Example regional association plot](examples/regional_plot.png)
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 pip:
86
+ Or with conda (Bioconda):
81
87
 
82
88
  ```bash
83
- pip install pylocuszoom
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 dog)
92
- plotter = LocusZoomPlotter(species="dog")
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="dog", # or "cat", or None for custom
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 dog is CanFam3.1. For CanFam4 data:
143
+ The default genome build for canine is CanFam3.1. For CanFam4 data:
138
144
 
139
145
  ```python
140
- plotter = LocusZoomPlotter(species="dog", genome_build="canfam4")
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
- # Cat (LD and gene tracks, user provides recombination data)
149
- plotter = LocusZoomPlotter(species="cat")
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
- ## Interactive Backends
172
+ ## Backends
167
173
 
168
- Choose between static (matplotlib) and interactive (plotly, bokeh) outputs:
174
+ pyLocusZoom supports multiple rendering backends:
169
175
 
170
176
  ```python
171
177
  # Static publication-quality plot (default)
172
- plotter = LocusZoomPlotter(species="dog", backend="matplotlib")
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 with plotly (hover tooltips, zoom/pan)
177
- plotter = LocusZoomPlotter(species="dog", backend="plotly")
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 with bokeh (dashboard-friendly)
182
- plotter = LocusZoomPlotter(species="dog", backend="bokeh")
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
- Interactive plots show SNP details (RS ID, p-value, R²) on hover.
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
- Dog recombination maps are downloaded from [Campbell et al. 2016](https://github.com/cflerin/dog_recombination) on first use.
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 download_dog_recombination_maps
341
+ from pylocuszoom import download_canine_recombination_maps
333
342
 
334
- download_dog_recombination_maps()
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
+ ![Example regional association plot](examples/regional_plot.png)
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 pip:
46
+ Or with conda (Bioconda):
39
47
 
40
48
  ```bash
41
- pip install pylocuszoom
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 dog)
50
- plotter = LocusZoomPlotter(species="dog")
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="dog", # or "cat", or None for custom
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 dog is CanFam3.1. For CanFam4 data:
103
+ The default genome build for canine is CanFam3.1. For CanFam4 data:
96
104
 
97
105
  ```python
98
- plotter = LocusZoomPlotter(species="dog", genome_build="canfam4")
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
- # Cat (LD and gene tracks, user provides recombination data)
107
- plotter = LocusZoomPlotter(species="cat")
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
- ## Interactive Backends
132
+ ## Backends
125
133
 
126
- Choose between static (matplotlib) and interactive (plotly, bokeh) outputs:
134
+ pyLocusZoom supports multiple rendering backends:
127
135
 
128
136
  ```python
129
137
  # Static publication-quality plot (default)
130
- plotter = LocusZoomPlotter(species="dog", backend="matplotlib")
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 with plotly (hover tooltips, zoom/pan)
135
- plotter = LocusZoomPlotter(species="dog", backend="plotly")
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 with bokeh (dashboard-friendly)
140
- plotter = LocusZoomPlotter(species="dog", backend="bokeh")
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
- Interactive plots show SNP details (RS ID, p-value, R²) on hover.
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
- Dog recombination maps are downloaded from [Campbell et al. 2016](https://github.com/cflerin/dog_recombination) on first use.
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 download_dog_recombination_maps
301
+ from pylocuszoom import download_canine_recombination_maps
291
302
 
292
- download_dog_recombination_maps()
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