Skip to content

Commit 537e946

Browse files
authored
Merge pull request #3 from michael-denyer/master
Modernised to support python 3.10+
2 parents 0bdfb1b + 4941aaa commit 537e946

10 files changed

Lines changed: 1288 additions & 357 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,5 @@ qqman/*.jpg
134134
qqman/*.jpeg
135135
qqman/*.gif
136136
qqman/*.tif
137-
qqman/*.tiff
137+
qqman/*.tiff
138+
.DS_Store

README.md

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,27 @@
11
<h1 style="text-align:center">qqman for Python</h1>
22

3-
![Install with pypi or anaconda](https://img.shields.io/badge/version-v1.0.6-green)
3+
![Install with pypi or anaconda](https://img.shields.io/badge/version-v1.0.8-green)
4+
![Python Version](https://img.shields.io/badge/python-3.10%2B-blue)
5+
![License](https://img.shields.io/badge/license-MIT-green)
46

5-
If you want to check out the source code or have any issues please leave a comment at my [github](https://github.com/satchellhong/qqman) repository. <br>
6-
This library is inspired by r-qqman (see [here](https://github.com/stephenturner/qqman)). <br>
7-
It also contains/will contain other methods for python users.<br>
7+
## About This Fork
8+
9+
This is a modernized fork of [satchellhong/qqman](https://github.com/satchellhong/qqman) with the following enhancements:
10+
11+
- **Added Parameters**: Additional `point_size` parameter for Manhattan plots to control marker size
12+
- **Modernized Dependencies**: Updated to support Python 3.9+ and newer python package versions
13+
- **Modern Packaging**: Added `pyproject.toml` and updated dependency specifications
14+
15+
### Original Project
16+
17+
The original qqman library was created by [satchellhong](https://github.com/satchellhong) and is inspired by the R package [r-qqman](https://github.com/stephenturner/qqman).
18+
19+
### License
20+
21+
This fork maintains the original MIT License. See the [LICENSE](LICENSE) file for details.
22+
23+
**Original Copyright**: Copyright (c) 2020 satchellhong
24+
**Fork Enhancements**: Additional parameters and modernization updates
825

926
---
1027
## Contents
@@ -29,24 +46,24 @@ $ pip install qqman
2946
```
3047

3148
### <a name="h12">1.2. Requirements</a>
32-
- matplotlib
33-
- pandas
34-
- numpy
49+
- Python 3.10+
50+
- matplotlib >= 3.7.0
51+
- pandas >= 1.5.3
52+
- numpy >= 1.23.5
3553

36-
#### pip
54+
#### Using uv (recommended - 10-100x faster)
3755
```console
38-
$ pip install numpy
39-
$ pip install pandas
40-
$ pip install matplotlib
56+
$ pip install uv
57+
$ uv pip install qqman
4158
```
4259

43-
#### ananconda
60+
#### Using pip
4461
```console
45-
$ conda install -c anaconda numpy
46-
$ conda install -y -c anaconda pandas
47-
$ conda install -y -c conda-forge matplotlib
62+
$ pip install qqman
4863
```
4964

65+
All dependencies will be installed automatically.
66+
5067
### <a name="h13">1.3. Features</a>
5168
1. [Manhattan Plot](#h2)<br>
5269
2. [QQ Plot](#h3)<br>
@@ -134,7 +151,11 @@ Draws Manhattan plot from PLINK --assoc output or any assoc formatted data that
134151
</tr>
135152
<tr>
136153
<th><code>col_snp</code> : string<br>( optional : default="SNP" )</th>
137-
<th>A string denoting the column name for the SNP name (rs number). Defaults to PLINK’s "SNP" Said column should be a character</th>
154+
<th>A string denoting the column name for the SNP name (rs number). Defaults to PLINK's "SNP" Said column should be a character</th>
155+
</tr>
156+
<tr>
157+
<th><code>point_size</code> : int<br>( optional : default=8 )</th>
158+
<th>The size of the scatter plot markers in the Manhattan plot</th>
138159
</tr>
139160
<tr>
140161
<th><code>suggestiveline</code> : string<br>( optional : default=-log_10(1e-5) )</th>
@@ -202,6 +223,10 @@ types: [string, pandas.DataFrame, numpy.array, list]
202223
<th>Output path and file name of the plot. (ie. out="./Manhattan.png")</th>
203224
</tr>
204225
<tr>
226+
<th><code>point_size</code> : int<br>( optional )</th>
227+
<th>The size of the scatter graph points (default s=5).</th>
228+
</tr>
229+
<tr>
205230
<th><code>show</code> : bool<br>( optional )</th>
206231
<th>If true, the plot will be shown on your screen. (This option doesn't work in CUI environment.)</th>
207232
</tr>
@@ -264,7 +289,7 @@ import matplotlib.pyplot as plt
264289
if __name__ == "__main__":
265290
df_assoc = pd.read_csv("../../temp.assoc", header=0, delim_whitespace=True)
266291
p_vals = list(df_assoc['P'])
267-
292+
268293
figure, axes = plt.subplots(nrows=2, ncols=2, figsize = (20,20))
269294

270295
qqman.qqplot("../../temp.assoc", ax=axes[0,0],title="From file")
@@ -278,4 +303,4 @@ if __name__ == "__main__":
278303
plt.close()
279304
```
280305

281-
<img src="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/satchellhong/qqman/blob/master/static/images/SubQQplot.png?raw=true" alt="Simple Manhattan Plot" width="600" height="600">
306+
<img src="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/satchellhong/qqman/blob/master/static/images/SubQQplot.png?raw=true" alt="Simple Manhattan Plot" width="600" height="600">

build.sh

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
1+
#!/bin/bash
2+
# Modern Python package build script using uv and pyproject.toml
3+
4+
set -e # Exit on error
5+
6+
echo "🧹 Cleaning previous builds..."
17
rm -rf build dist *.egg-info
2-
conda install setuptools wheel twine -y
3-
conda update setuptools wheel twine -y
48

5-
python setup.py sdist bdist_wheel
6-
twine upload dist/* --verbose
9+
echo "📦 Building package with uv..."
10+
uv build
11+
12+
echo "🚀 Uploading to PyPI..."
13+
uv publish
14+
15+
echo "✅ Build and publish complete!"

pyproject.toml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
[build-system]
2+
requires = ["hatchling"]
3+
build-backend = "hatchling.build"
4+
5+
[project]
6+
name = "qqman"
7+
version = "1.0.8"
8+
description = "Draws Manhattan plot and QQ plot using plink assoc output"
9+
readme = "README.md"
10+
license = {text = "MIT"}
11+
authors = [
12+
{name = "chol hong", email = "shulkhorn@gmail.com"}
13+
]
14+
maintainers = [
15+
{name = "chol hong", email = "shulkhorn@gmail.com"}
16+
]
17+
requires-python = ">=3.10"
18+
classifiers = [
19+
"Development Status :: 5 - Production/Stable",
20+
"Intended Audience :: Science/Research",
21+
"License :: OSI Approved :: MIT License",
22+
"Operating System :: OS Independent",
23+
"Programming Language :: Python :: 3",
24+
"Programming Language :: Python :: 3.10",
25+
"Programming Language :: Python :: 3.11",
26+
"Programming Language :: Python :: 3.12",
27+
"Topic :: Scientific/Engineering :: Bio-Informatics",
28+
"Topic :: Scientific/Engineering :: Visualization",
29+
]
30+
keywords = ["bioinformatics", "gwas", "manhattan plot", "qq plot", "visualization", "genomics"]
31+
32+
dependencies = [
33+
"numpy>=1.23.5,<3.0.0",
34+
"pandas>=1.5.3,<3.0.0",
35+
"matplotlib>=3.7.0,<4.0.0",
36+
]
37+
38+
[project.urls]
39+
Homepage = "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/satchellhong/qqman"
40+
"Bug Tracker" = "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/satchellhong/qqman/issues"
41+
"Source Code" = "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/satchellhong/qqman"
42+
43+
# Optional development dependencies
44+
[project.optional-dependencies]
45+
dev = [
46+
"pytest>=7.0.0",
47+
"pytest-cov>=4.0.0",
48+
"ruff>=0.4.8",
49+
]
50+
51+
[tool.hatch.build.targets.wheel]
52+
packages = ["qqman"]
53+
54+
# uv-specific configuration
55+
[tool.uv]
56+
dev-dependencies = [
57+
"pytest>=7.0.0",
58+
"pytest-cov>=4.0.0",
59+
"ruff>=0.4.8",
60+
]
61+
62+
# Ruff configuration for numpy 2.0 compatibility checking
63+
[tool.ruff]
64+
line-length = 88
65+
target-version = "py310"
66+
67+
[tool.ruff.lint]
68+
select = ["E", "F", "W", "I", "NPY201"] # NPY201 checks numpy 2.0 compatibility

qqman/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
name = "qqman"
2-
from . import qqman
2+
from . import qqman

qqman/biostats.py

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
import numpy as np
21
import numbers
32

3+
import numpy as np
4+
5+
46
def ppoints(n, a=None):
5-
""" numpy analogue or `R`'s `ppoints` function
6-
see details at https://www.rdocumentation.org/packages/stats/versions/3.6.2/topics/ppoints
7-
https://docs.tibco.com/pub/enterprise-runtime-for-R/5.0.0/doc/html/Language_Reference/stats/ppoints.html
8-
:param n: array type or number"""
9-
10-
if isinstance(n, numbers.Number):
11-
n = float(n)
12-
else:
13-
n = float(len(n))
14-
if a == None:
15-
a = .375 if n<=10 else .5
16-
17-
return (np.arange(n) + 1 - a)/(n + 1 - 2*a)
7+
"""numpy analogue or `R`'s `ppoints` function
8+
see details at https://www.rdocumentation.org/packages/stats/versions/3.6.2/topics/ppoints
9+
https://docs.tibco.com/pub/enterprise-runtime-for-R/5.0.0/doc/html/Language_Reference/stats/ppoints.html
10+
:param n: array type or number"""
11+
12+
n = np.float64(n) if isinstance(n, numbers.Number) else np.float64(len(n))
13+
if a is None:
14+
a = 0.375 if n <= 10 else 0.5
15+
16+
return (np.arange(n) + 1 - a) / (n + 1 - 2 * a)

0 commit comments

Comments
 (0)