ridgeplot-py 0.2.7__tar.gz → 0.4.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.
- ridgeplot_py-0.4.0/.github/workflows/ci.yaml +113 -0
- ridgeplot_py-0.4.0/.pre-commit-config.yaml +8 -0
- ridgeplot_py-0.4.0/Example.ipynb +206 -0
- {ridgeplot_py-0.2.7 → ridgeplot_py-0.4.0}/PKG-INFO +11 -19
- ridgeplot_py-0.4.0/docs/colors.md +1 -0
- ridgeplot_py-0.4.0/docs/dotted_heatmap.md +1 -0
- ridgeplot_py-0.4.0/docs/index.md +14 -0
- ridgeplot_py-0.4.0/docs/ridge_plot.md +1 -0
- ridgeplot_py-0.4.0/docs/stats.md +1 -0
- ridgeplot_py-0.4.0/img/ridgeplot.png +0 -0
- ridgeplot_py-0.4.0/mkdocs.yml +15 -0
- ridgeplot_py-0.4.0/pyproject.toml +61 -0
- ridgeplot_py-0.4.0/requirements-dev.lock +99 -0
- ridgeplot_py-0.4.0/requirements.lock +52 -0
- {ridgeplot_py-0.2.7 → ridgeplot_py-0.4.0/src}/ridgeplot/colors.py +1 -1
- ridgeplot_py-0.4.0/test/test_colors.py +87 -0
- ridgeplot_py-0.4.0/test/test_dotted_heatmap.py +19 -0
- ridgeplot_py-0.4.0/test/test_ridge_plot.py +37 -0
- ridgeplot_py-0.4.0/test/test_stats.py +22 -0
- ridgeplot_py-0.2.7/pyproject.toml +0 -61
- {ridgeplot_py-0.2.7 → ridgeplot_py-0.4.0}/LICENSE +0 -0
- {ridgeplot_py-0.2.7 → ridgeplot_py-0.4.0}/README.md +0 -0
- {ridgeplot_py-0.2.7 → ridgeplot_py-0.4.0/src}/ridgeplot/__init__.py +0 -0
- {ridgeplot_py-0.2.7 → ridgeplot_py-0.4.0/src}/ridgeplot/dotted_heatmap.py +0 -0
- {ridgeplot_py-0.2.7 → ridgeplot_py-0.4.0/src}/ridgeplot/ridge_plot.py +0 -0
- {ridgeplot_py-0.2.7 → ridgeplot_py-0.4.0/src}/ridgeplot/stats.py +0 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# This workflow will install Python dependencies, run tests and lint with a single version of Python
|
|
2
|
+
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
|
|
3
|
+
|
|
4
|
+
name: CI
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches: [ main ]
|
|
9
|
+
pull_request:
|
|
10
|
+
branches: [ main ]
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build:
|
|
14
|
+
name: poetry-build
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
strategy:
|
|
17
|
+
matrix:
|
|
18
|
+
python-version: ["3.10", "3.9"]
|
|
19
|
+
defaults:
|
|
20
|
+
run:
|
|
21
|
+
shell: bash -l {0}
|
|
22
|
+
permissions:
|
|
23
|
+
# Gives the action the necessary permissions for publishing new
|
|
24
|
+
# comments in pull requests.
|
|
25
|
+
pull-requests: write
|
|
26
|
+
# Gives the action the necessary permissions for pushing data to the
|
|
27
|
+
# python-coverage-comment-action branch, and for editing existing
|
|
28
|
+
# comments (to avoid publishing multiple comments in the same PR)
|
|
29
|
+
contents: write
|
|
30
|
+
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@v2
|
|
33
|
+
|
|
34
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
35
|
+
uses: actions/setup-python@v2
|
|
36
|
+
with:
|
|
37
|
+
python-version: ${{ matrix.python-version }}
|
|
38
|
+
|
|
39
|
+
- name: Install the latest version of rye
|
|
40
|
+
uses: eifinger/setup-rye@v3
|
|
41
|
+
|
|
42
|
+
- name: Install dependencies
|
|
43
|
+
run: |
|
|
44
|
+
rye sync --no-lock
|
|
45
|
+
|
|
46
|
+
- name: type check
|
|
47
|
+
run: |
|
|
48
|
+
rye run mypy src/ridgeplot
|
|
49
|
+
|
|
50
|
+
- name: format check
|
|
51
|
+
run: |
|
|
52
|
+
rye run pre-commit run --all-files --show-diff-on-failure
|
|
53
|
+
|
|
54
|
+
- name: Test with pytest
|
|
55
|
+
run: |
|
|
56
|
+
rye test -- -l -rPap -vvv -p no:warnings --cov
|
|
57
|
+
|
|
58
|
+
- uses: py-cov-action/python-coverage-comment-action@v3
|
|
59
|
+
id: coverage_comment
|
|
60
|
+
if: ${{ matrix.python-version }} == "3.9" && github.ref != 'refs/heads/main'
|
|
61
|
+
with:
|
|
62
|
+
GITHUB_TOKEN: ${{ github.token }}
|
|
63
|
+
ANNOTATE_MISSING_LINES: true
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
publish:
|
|
67
|
+
needs: build
|
|
68
|
+
if: github.ref == 'refs/heads/main'
|
|
69
|
+
runs-on: ubuntu-latest
|
|
70
|
+
permissions:
|
|
71
|
+
contents: write
|
|
72
|
+
|
|
73
|
+
steps:
|
|
74
|
+
- uses: actions/checkout@v2
|
|
75
|
+
with:
|
|
76
|
+
fetch-depth: 0
|
|
77
|
+
|
|
78
|
+
- name: Install the latest version of rye
|
|
79
|
+
uses: eifinger/setup-rye@v3
|
|
80
|
+
|
|
81
|
+
- name: Build dist
|
|
82
|
+
run: |
|
|
83
|
+
rye build --verbose
|
|
84
|
+
|
|
85
|
+
- name: publish to pypi
|
|
86
|
+
run: |
|
|
87
|
+
rye publish --token ${{ secrets.PYPI_TOKEN }} --yes --verbose
|
|
88
|
+
|
|
89
|
+
- name: push tag
|
|
90
|
+
run: |
|
|
91
|
+
gh release create $(rye version)
|
|
92
|
+
env:
|
|
93
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
deploy:
|
|
97
|
+
name: deploy doc
|
|
98
|
+
runs-on: ubuntu-latest
|
|
99
|
+
if: github.ref == 'refs/heads/main'
|
|
100
|
+
needs: [publish, build]
|
|
101
|
+
|
|
102
|
+
steps:
|
|
103
|
+
- uses: actions/checkout@v2
|
|
104
|
+
|
|
105
|
+
- name: setup
|
|
106
|
+
uses: actions/setup-python@v2
|
|
107
|
+
with:
|
|
108
|
+
python-version: 3.x
|
|
109
|
+
|
|
110
|
+
- name: build and deploy doc
|
|
111
|
+
run: |
|
|
112
|
+
pip install mkdocs-material mkdocstrings-python mkdocs
|
|
113
|
+
mkdocs gh-deploy --force
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cells": [
|
|
3
|
+
{
|
|
4
|
+
"cell_type": "code",
|
|
5
|
+
"execution_count": 1,
|
|
6
|
+
"metadata": {},
|
|
7
|
+
"outputs": [],
|
|
8
|
+
"source": [
|
|
9
|
+
"%load_ext autoreload\n",
|
|
10
|
+
"%autoreload 2\n",
|
|
11
|
+
"%matplotlib inline\n",
|
|
12
|
+
"\n",
|
|
13
|
+
"from ridgeplot import ridgeplot\n",
|
|
14
|
+
"from ridgeplot.colors import ColorEncoder, ColorPalette\n",
|
|
15
|
+
"import numpy as np\n",
|
|
16
|
+
"import matplotlib.pyplot as plt"
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"cell_type": "code",
|
|
21
|
+
"execution_count": 2,
|
|
22
|
+
"metadata": {},
|
|
23
|
+
"outputs": [
|
|
24
|
+
{
|
|
25
|
+
"data": {
|
|
26
|
+
"image/png": "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",
|
|
27
|
+
"text/plain": [
|
|
28
|
+
"<Figure size 432x288 with 1 Axes>"
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
"metadata": {
|
|
32
|
+
"needs_background": "light"
|
|
33
|
+
},
|
|
34
|
+
"output_type": "display_data"
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"source": [
|
|
38
|
+
"data = {}\n",
|
|
39
|
+
"for i in range(8):\n",
|
|
40
|
+
" data['data_{}'.format(i)] = np.random.randn(100) * (i+1)\n",
|
|
41
|
+
"\n",
|
|
42
|
+
"fig = plt.figure()\n",
|
|
43
|
+
"ax = fig.add_subplot(111)\n",
|
|
44
|
+
"ridgeplot(ax, \n",
|
|
45
|
+
" data, \n",
|
|
46
|
+
" xlim=(-20,20), \n",
|
|
47
|
+
" label_size=15)"
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"cell_type": "markdown",
|
|
52
|
+
"metadata": {},
|
|
53
|
+
"source": [
|
|
54
|
+
"## Different colors ##"
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"cell_type": "code",
|
|
59
|
+
"execution_count": 3,
|
|
60
|
+
"metadata": {},
|
|
61
|
+
"outputs": [
|
|
62
|
+
{
|
|
63
|
+
"data": {
|
|
64
|
+
"text/plain": [
|
|
65
|
+
"['#A3CF71',\n",
|
|
66
|
+
" '#66BF7E',\n",
|
|
67
|
+
" '#0AACA0',\n",
|
|
68
|
+
" '#0888B2',\n",
|
|
69
|
+
" '#373737',\n",
|
|
70
|
+
" '#EFEDEA',\n",
|
|
71
|
+
" '#686b69',\n",
|
|
72
|
+
" '#417d55']"
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
"execution_count": 3,
|
|
76
|
+
"metadata": {},
|
|
77
|
+
"output_type": "execute_result"
|
|
78
|
+
}
|
|
79
|
+
],
|
|
80
|
+
"source": [
|
|
81
|
+
"ColorPalette[\"invitae\"]"
|
|
82
|
+
]
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"cell_type": "code",
|
|
86
|
+
"execution_count": 4,
|
|
87
|
+
"metadata": {},
|
|
88
|
+
"outputs": [
|
|
89
|
+
{
|
|
90
|
+
"data": {
|
|
91
|
+
"text/plain": [
|
|
92
|
+
"OrderedDict([('data_0', '#A3CF71'),\n",
|
|
93
|
+
" ('data_1', '#66BF7E'),\n",
|
|
94
|
+
" ('data_2', '#0AACA0'),\n",
|
|
95
|
+
" ('data_3', '#0888B2'),\n",
|
|
96
|
+
" ('data_4', '#373737'),\n",
|
|
97
|
+
" ('data_5', '#EFEDEA'),\n",
|
|
98
|
+
" ('data_6', '#686b69'),\n",
|
|
99
|
+
" ('data_7', '#417d55')])"
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
"execution_count": 4,
|
|
103
|
+
"metadata": {},
|
|
104
|
+
"output_type": "execute_result"
|
|
105
|
+
}
|
|
106
|
+
],
|
|
107
|
+
"source": [
|
|
108
|
+
"color_encoder = ColorEncoder()\n",
|
|
109
|
+
"color_encoder.fit(\n",
|
|
110
|
+
" categories = list(data.keys()),\n",
|
|
111
|
+
" colors = ColorPalette[\"invitae\"],\n",
|
|
112
|
+
")\n",
|
|
113
|
+
"color_encoder.encoder"
|
|
114
|
+
]
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"cell_type": "code",
|
|
118
|
+
"execution_count": 5,
|
|
119
|
+
"metadata": {},
|
|
120
|
+
"outputs": [
|
|
121
|
+
{
|
|
122
|
+
"data": {
|
|
123
|
+
"text/plain": [
|
|
124
|
+
"['#A3CF71',\n",
|
|
125
|
+
" '#66BF7E',\n",
|
|
126
|
+
" '#0AACA0',\n",
|
|
127
|
+
" '#0888B2',\n",
|
|
128
|
+
" '#373737',\n",
|
|
129
|
+
" '#EFEDEA',\n",
|
|
130
|
+
" '#686b69',\n",
|
|
131
|
+
" '#417d55']"
|
|
132
|
+
]
|
|
133
|
+
},
|
|
134
|
+
"execution_count": 5,
|
|
135
|
+
"metadata": {},
|
|
136
|
+
"output_type": "execute_result"
|
|
137
|
+
}
|
|
138
|
+
],
|
|
139
|
+
"source": [
|
|
140
|
+
"line_colors = color_encoder.transform(list(data.keys()))\n",
|
|
141
|
+
"line_colors"
|
|
142
|
+
]
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"cell_type": "code",
|
|
146
|
+
"execution_count": 6,
|
|
147
|
+
"metadata": {},
|
|
148
|
+
"outputs": [
|
|
149
|
+
{
|
|
150
|
+
"data": {
|
|
151
|
+
"image/png": "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",
|
|
152
|
+
"text/plain": [
|
|
153
|
+
"<Figure size 432x288 with 1 Axes>"
|
|
154
|
+
]
|
|
155
|
+
},
|
|
156
|
+
"metadata": {
|
|
157
|
+
"needs_background": "light"
|
|
158
|
+
},
|
|
159
|
+
"output_type": "display_data"
|
|
160
|
+
}
|
|
161
|
+
],
|
|
162
|
+
"source": [
|
|
163
|
+
"fig = plt.figure()\n",
|
|
164
|
+
"ax = fig.add_subplot(111)\n",
|
|
165
|
+
"\n",
|
|
166
|
+
"ridgeplot(ax, \n",
|
|
167
|
+
" data, \n",
|
|
168
|
+
" xlim=(-20,20), \n",
|
|
169
|
+
" label_size=10, \n",
|
|
170
|
+
" line_colors=line_colors, \n",
|
|
171
|
+
" fill_colors=line_colors)"
|
|
172
|
+
]
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"cell_type": "code",
|
|
176
|
+
"execution_count": null,
|
|
177
|
+
"metadata": {},
|
|
178
|
+
"outputs": [],
|
|
179
|
+
"source": []
|
|
180
|
+
}
|
|
181
|
+
],
|
|
182
|
+
"metadata": {
|
|
183
|
+
"interpreter": {
|
|
184
|
+
"hash": "b0fa6594d8f4cbf19f97940f81e996739fb7646882a419484c72d19e05852a7e"
|
|
185
|
+
},
|
|
186
|
+
"kernelspec": {
|
|
187
|
+
"display_name": "mambaforge",
|
|
188
|
+
"language": "python",
|
|
189
|
+
"name": "python3"
|
|
190
|
+
},
|
|
191
|
+
"language_info": {
|
|
192
|
+
"codemirror_mode": {
|
|
193
|
+
"name": "ipython",
|
|
194
|
+
"version": 3
|
|
195
|
+
},
|
|
196
|
+
"file_extension": ".py",
|
|
197
|
+
"mimetype": "text/x-python",
|
|
198
|
+
"name": "python",
|
|
199
|
+
"nbconvert_exporter": "python",
|
|
200
|
+
"pygments_lexer": "ipython3",
|
|
201
|
+
"version": "3.9.7"
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
"nbformat": 4,
|
|
205
|
+
"nbformat_minor": 4
|
|
206
|
+
}
|
|
@@ -1,23 +1,16 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: ridgeplot-py
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Plotting ridgeplots with matplotlib
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Requires-Python: >=3.9
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
-
Requires-Dist: matplotlib (>=3.8,<4.0)
|
|
16
|
-
Requires-Dist: more-itertools (>=8.9.0,<9.0.0)
|
|
17
|
-
Requires-Dist: numpy (>=1.21.1,<2.0.0)
|
|
18
|
-
Requires-Dist: pandas (>=2.2.2,<3.0.0)
|
|
19
|
-
Requires-Dist: poetry (>=1.8.3,<2.0.0)
|
|
20
|
-
Requires-Dist: scipy (>=1.8.0,<2.0.0)
|
|
5
|
+
Author-email: Douglas Wu <wckdouglas@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Python: >=3.9
|
|
9
|
+
Requires-Dist: matplotlib>=3.8
|
|
10
|
+
Requires-Dist: more-itertools>=8.9.0
|
|
11
|
+
Requires-Dist: numpy>=1.21.1
|
|
12
|
+
Requires-Dist: pandas>=2.2.2
|
|
13
|
+
Requires-Dist: scipy>=1.8.0
|
|
21
14
|
Description-Content-Type: text/markdown
|
|
22
15
|
|
|
23
16
|
# ridgeplot-py #
|
|
@@ -97,4 +90,3 @@ brew install openblas
|
|
|
97
90
|
export OPENBLAS="$(brew --prefix openblas)"
|
|
98
91
|
poetry install
|
|
99
92
|
```
|
|
100
|
-
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
::: src.ridgeplot.colors
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
::: ridgeplot.dotted_heatmap
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
This is a simple module for plotting [ridgeplot](https://clauswilke.com/blog/2017/09/15/goodbye-joyplots/) with the [scipy ecosystem](https://www.scipy.org/about.html).
|
|
2
|
+
|
|
3
|
+
Ridgeplot is a great data visualization technique to compare distributions from multiple groups at the same time, and was first introduced in 2017 as joy plot:
|
|
4
|
+
|
|
5
|
+
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">I hereby propose that we call these "joy plots" <a href="https://twitter.com/hashtag/rstats?src=hash&ref_src=twsrc%5Etfw">#rstats</a> <a href="https://t.co/uuLGpQLAwY">https://t.co/uuLGpQLAwY</a></p>— Jenny Bryan (@JennyBryan) <a href="https://twitter.com/JennyBryan/status/856674638981550080?ref_src=twsrc%5Etfw">April 25, 2017</a></blockquote>
|
|
6
|
+
|
|
7
|
+
[ridgeplot-py](https://pypi.org/project/ridgeplot-py/) provides a simple API to produce matplotlib-compatible ridgeplots, as well as a handy [ColorEncoder](https://github.com/wckdouglas/ridgeplot-py/blob/0198628ce0622e2e7f4f4e9284165d5d09324ca9/ridgeplot/colors.py#L117) class with scikit-learn syntax for manipulating color annotations in a consistent way [through out manuscripts or presentations].
|
|
8
|
+
|
|
9
|
+
# Modules
|
|
10
|
+
|
|
11
|
+
1. [colors](colors.md)
|
|
12
|
+
2. [ridgeplot](ridge_plot.md)
|
|
13
|
+
3. [stats](stats.md)
|
|
14
|
+
4. [dotted_heatmap](dotted_heatmap.md)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
::: src.ridgeplot.ridge_plot
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
::: src.ridgeplot.stats
|
|
Binary file
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
site_name: ridgeplot-py
|
|
2
|
+
|
|
3
|
+
theme:
|
|
4
|
+
name: "material"
|
|
5
|
+
|
|
6
|
+
plugins:
|
|
7
|
+
- search
|
|
8
|
+
- mkdocstrings
|
|
9
|
+
|
|
10
|
+
nav:
|
|
11
|
+
- ridgeplot-py docs: index.md
|
|
12
|
+
- ridgeplot.colors: colors.md
|
|
13
|
+
- ridgeplot.ridge_plot: ridge_plot.md
|
|
14
|
+
- ridgeplot.stats: stats.md
|
|
15
|
+
- ridgeplot.dotted_heatmap: dotted_heatmap.md
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "ridgeplot-py"
|
|
3
|
+
dynamic = ["version"]
|
|
4
|
+
description = "Plotting ridgeplots with matplotlib"
|
|
5
|
+
authors = [{ name = "Douglas Wu", email = "wckdouglas@gmail.com" }]
|
|
6
|
+
license = "MIT"
|
|
7
|
+
readme = "README.md"
|
|
8
|
+
requires-python = ">= 3.9"
|
|
9
|
+
dependencies = [
|
|
10
|
+
"scipy>=1.8.0",
|
|
11
|
+
"matplotlib>=3.8",
|
|
12
|
+
"more-itertools>=8.9.0",
|
|
13
|
+
"numpy>=1.21.1",
|
|
14
|
+
"pandas>=2.2.2",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[tool.rye]
|
|
18
|
+
dev-dependencies = [
|
|
19
|
+
"pytest>=6.2.5",
|
|
20
|
+
"pytest-cov>=2.12.1",
|
|
21
|
+
"mypy>=1.10.0",
|
|
22
|
+
"ruff>=0.0.290",
|
|
23
|
+
"pre-commit>=3.7.1",
|
|
24
|
+
"versioningit>=3.1.1",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[build-system]
|
|
28
|
+
requires = ["hatchling", "versioningit"]
|
|
29
|
+
build-backend = "hatchling.build"
|
|
30
|
+
|
|
31
|
+
[tool.hatch.version]
|
|
32
|
+
source = "versioningit"
|
|
33
|
+
|
|
34
|
+
[tool.versioningit]
|
|
35
|
+
default-version = "0.0.0+unknown"
|
|
36
|
+
|
|
37
|
+
[tool.versioningit.format]
|
|
38
|
+
distance = "{next_version}"
|
|
39
|
+
dirty = "{version}+dirty"
|
|
40
|
+
distance-dirty = "{next_version}.dev{distance}+{vcs}{rev}.dirty"
|
|
41
|
+
|
|
42
|
+
[tool.mypy]
|
|
43
|
+
plugins = "numpy.typing.mypy_plugin"
|
|
44
|
+
ignore_missing_imports = true
|
|
45
|
+
strict_optional = true
|
|
46
|
+
check_untyped_defs = true
|
|
47
|
+
|
|
48
|
+
[[tool.mypy.overrides]]
|
|
49
|
+
module = ["matplotlib.*", "scipy.*"]
|
|
50
|
+
ignore_errors = true
|
|
51
|
+
|
|
52
|
+
[tool.ruff]
|
|
53
|
+
line-length = 120
|
|
54
|
+
select = ['E', 'F', 'W', 'I']
|
|
55
|
+
|
|
56
|
+
[tool.coverage.run]
|
|
57
|
+
relative_files = true
|
|
58
|
+
source_pkgs = ["ridgeplot"]
|
|
59
|
+
|
|
60
|
+
[tool.hatch.build.targets.wheel]
|
|
61
|
+
packages = ["src/ridgeplot"]
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# generated by rye
|
|
2
|
+
# use `rye lock` or `rye sync` to update this lockfile
|
|
3
|
+
#
|
|
4
|
+
# last locked with the following flags:
|
|
5
|
+
# pre: false
|
|
6
|
+
# features: []
|
|
7
|
+
# all-features: false
|
|
8
|
+
# with-sources: false
|
|
9
|
+
# generate-hashes: false
|
|
10
|
+
|
|
11
|
+
-e file:.
|
|
12
|
+
cfgv==3.4.0
|
|
13
|
+
# via pre-commit
|
|
14
|
+
contourpy==1.2.1
|
|
15
|
+
# via matplotlib
|
|
16
|
+
coverage==7.5.1
|
|
17
|
+
# via pytest-cov
|
|
18
|
+
cycler==0.12.1
|
|
19
|
+
# via matplotlib
|
|
20
|
+
distlib==0.3.8
|
|
21
|
+
# via virtualenv
|
|
22
|
+
exceptiongroup==1.2.1
|
|
23
|
+
# via pytest
|
|
24
|
+
filelock==3.14.0
|
|
25
|
+
# via virtualenv
|
|
26
|
+
fonttools==4.51.0
|
|
27
|
+
# via matplotlib
|
|
28
|
+
identify==2.5.36
|
|
29
|
+
# via pre-commit
|
|
30
|
+
importlib-metadata==7.1.0
|
|
31
|
+
# via versioningit
|
|
32
|
+
importlib-resources==6.4.0
|
|
33
|
+
# via matplotlib
|
|
34
|
+
iniconfig==2.0.0
|
|
35
|
+
# via pytest
|
|
36
|
+
kiwisolver==1.4.5
|
|
37
|
+
# via matplotlib
|
|
38
|
+
matplotlib==3.9.0
|
|
39
|
+
# via ridgeplot-py
|
|
40
|
+
more-itertools==10.2.0
|
|
41
|
+
# via ridgeplot-py
|
|
42
|
+
mypy==1.10.0
|
|
43
|
+
mypy-extensions==1.0.0
|
|
44
|
+
# via mypy
|
|
45
|
+
nodeenv==1.8.0
|
|
46
|
+
# via pre-commit
|
|
47
|
+
numpy==1.26.4
|
|
48
|
+
# via contourpy
|
|
49
|
+
# via matplotlib
|
|
50
|
+
# via pandas
|
|
51
|
+
# via ridgeplot-py
|
|
52
|
+
# via scipy
|
|
53
|
+
packaging==24.0
|
|
54
|
+
# via matplotlib
|
|
55
|
+
# via pytest
|
|
56
|
+
# via versioningit
|
|
57
|
+
pandas==2.2.2
|
|
58
|
+
# via ridgeplot-py
|
|
59
|
+
pillow==10.3.0
|
|
60
|
+
# via matplotlib
|
|
61
|
+
platformdirs==4.2.2
|
|
62
|
+
# via virtualenv
|
|
63
|
+
pluggy==1.5.0
|
|
64
|
+
# via pytest
|
|
65
|
+
pre-commit==3.7.1
|
|
66
|
+
pyparsing==3.1.2
|
|
67
|
+
# via matplotlib
|
|
68
|
+
pytest==8.2.1
|
|
69
|
+
# via pytest-cov
|
|
70
|
+
pytest-cov==5.0.0
|
|
71
|
+
python-dateutil==2.9.0.post0
|
|
72
|
+
# via matplotlib
|
|
73
|
+
# via pandas
|
|
74
|
+
pytz==2024.1
|
|
75
|
+
# via pandas
|
|
76
|
+
pyyaml==6.0.1
|
|
77
|
+
# via pre-commit
|
|
78
|
+
ruff==0.4.4
|
|
79
|
+
scipy==1.13.0
|
|
80
|
+
# via ridgeplot-py
|
|
81
|
+
setuptools==69.5.1
|
|
82
|
+
# via nodeenv
|
|
83
|
+
six==1.16.0
|
|
84
|
+
# via python-dateutil
|
|
85
|
+
tomli==2.0.1
|
|
86
|
+
# via coverage
|
|
87
|
+
# via mypy
|
|
88
|
+
# via pytest
|
|
89
|
+
# via versioningit
|
|
90
|
+
typing-extensions==4.11.0
|
|
91
|
+
# via mypy
|
|
92
|
+
tzdata==2024.1
|
|
93
|
+
# via pandas
|
|
94
|
+
versioningit==3.1.1
|
|
95
|
+
virtualenv==20.26.2
|
|
96
|
+
# via pre-commit
|
|
97
|
+
zipp==3.18.2
|
|
98
|
+
# via importlib-metadata
|
|
99
|
+
# via importlib-resources
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# generated by rye
|
|
2
|
+
# use `rye lock` or `rye sync` to update this lockfile
|
|
3
|
+
#
|
|
4
|
+
# last locked with the following flags:
|
|
5
|
+
# pre: false
|
|
6
|
+
# features: []
|
|
7
|
+
# all-features: false
|
|
8
|
+
# with-sources: false
|
|
9
|
+
# generate-hashes: false
|
|
10
|
+
|
|
11
|
+
-e file:.
|
|
12
|
+
contourpy==1.2.1
|
|
13
|
+
# via matplotlib
|
|
14
|
+
cycler==0.12.1
|
|
15
|
+
# via matplotlib
|
|
16
|
+
fonttools==4.51.0
|
|
17
|
+
# via matplotlib
|
|
18
|
+
importlib-resources==6.4.0
|
|
19
|
+
# via matplotlib
|
|
20
|
+
kiwisolver==1.4.5
|
|
21
|
+
# via matplotlib
|
|
22
|
+
matplotlib==3.9.0
|
|
23
|
+
# via ridgeplot-py
|
|
24
|
+
more-itertools==10.2.0
|
|
25
|
+
# via ridgeplot-py
|
|
26
|
+
numpy==1.26.4
|
|
27
|
+
# via contourpy
|
|
28
|
+
# via matplotlib
|
|
29
|
+
# via pandas
|
|
30
|
+
# via ridgeplot-py
|
|
31
|
+
# via scipy
|
|
32
|
+
packaging==24.0
|
|
33
|
+
# via matplotlib
|
|
34
|
+
pandas==2.2.2
|
|
35
|
+
# via ridgeplot-py
|
|
36
|
+
pillow==10.3.0
|
|
37
|
+
# via matplotlib
|
|
38
|
+
pyparsing==3.1.2
|
|
39
|
+
# via matplotlib
|
|
40
|
+
python-dateutil==2.9.0.post0
|
|
41
|
+
# via matplotlib
|
|
42
|
+
# via pandas
|
|
43
|
+
pytz==2024.1
|
|
44
|
+
# via pandas
|
|
45
|
+
scipy==1.13.0
|
|
46
|
+
# via ridgeplot-py
|
|
47
|
+
six==1.16.0
|
|
48
|
+
# via python-dateutil
|
|
49
|
+
tzdata==2024.1
|
|
50
|
+
# via pandas
|
|
51
|
+
zipp==3.18.2
|
|
52
|
+
# via importlib-resources
|
|
@@ -8,8 +8,8 @@ from typing import Any, Dict, List, Tuple
|
|
|
8
8
|
import matplotlib.axes
|
|
9
9
|
import matplotlib.patches as mpatches
|
|
10
10
|
from matplotlib import legend
|
|
11
|
-
from matplotlib.cm import get_cmap
|
|
12
11
|
from matplotlib.colors import to_hex
|
|
12
|
+
from matplotlib.pyplot import get_cmap
|
|
13
13
|
|
|
14
14
|
ColorPalette: Dict[str, List[str]] = dict(
|
|
15
15
|
# 1. maximum
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
from unittest.mock import patch
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from ridgeplot.colors import (
|
|
5
|
+
ColorEncoder,
|
|
6
|
+
ColorPalette,
|
|
7
|
+
check_color_vector_size,
|
|
8
|
+
get_cmap_color_values,
|
|
9
|
+
ordered_set,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@pytest.fixture(scope="module")
|
|
14
|
+
def color_encoder():
|
|
15
|
+
ce = ColorEncoder()
|
|
16
|
+
ce.fit(["a", "b", "c", "b", "a"], ["red", "green", "blue"])
|
|
17
|
+
return ce
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@pytest.mark.parametrize(
|
|
21
|
+
"input, output",
|
|
22
|
+
[(["a", "b", "c"], ["a", "b", "c"]), (["b", "a", "b", "d"], ["b", "a", "d"])],
|
|
23
|
+
)
|
|
24
|
+
def test_ordered_set(input, output):
|
|
25
|
+
assert ordered_set(input) == output
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@pytest.mark.parametrize(
|
|
29
|
+
"palette, expected_num",
|
|
30
|
+
[("maximum", 22), ("simpsons", 16), ("okabeito", 8), ("invitae", 8)],
|
|
31
|
+
)
|
|
32
|
+
def test_ColorPalette(palette, expected_num):
|
|
33
|
+
assert len(ColorPalette[palette]) == expected_num
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def test_check_color_vector_size():
|
|
37
|
+
cat = check_color_vector_size(["a", "a", "b", "a"], ["red", "blue"])
|
|
38
|
+
assert set(cat).union(set(["a", "b"])) == set(["a", "b"])
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def test_check_color_vector_size_fail():
|
|
42
|
+
with pytest.raises(ValueError) as e:
|
|
43
|
+
check_color_vector_size(["a", "a", "b", "c"], ["red", "blue"])
|
|
44
|
+
assert "Not enough colors!!" in str(e.value), "Cannot catch category > color"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def test_ColorEncoder(color_encoder):
|
|
48
|
+
assert color_encoder.encoder == {"a": "red", "b": "green", "c": "blue"}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_ColorEncoder_transform(color_encoder):
|
|
52
|
+
assert color_encoder.transform(["c", "c", "c"]) == ["blue", "blue", "blue"]
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def test_ColorEncoder_transform_unseen(color_encoder):
|
|
56
|
+
with pytest.raises(ValueError) as e:
|
|
57
|
+
color_encoder.transform(["a", "b", "c", "d", "e"])
|
|
58
|
+
assert "Input [categories] contain unseen data!!: d, e" in str(e.value)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def test_ColorEncoder_transform_fail():
|
|
62
|
+
with pytest.raises(ValueError) as e:
|
|
63
|
+
ce = ColorEncoder()
|
|
64
|
+
ce.transform(["a", "b", "c"])
|
|
65
|
+
assert "Call color_encoder.fit() first" in str(e.value)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def test_ColorEncoder_fit_transform(color_encoder):
|
|
69
|
+
colors = color_encoder.fit_transform(["a", "b", "c", "b", "a"], ["red", "green", "blue"])
|
|
70
|
+
assert color_encoder.encoder == {"a": "red", "b": "green", "c": "blue"}
|
|
71
|
+
assert colors == ["red", "green", "blue", "green", "red"]
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@patch("matplotlib.pyplot.figure")
|
|
75
|
+
def test_ColorEncoder_show_legend(figure, color_encoder):
|
|
76
|
+
ax = figure.add_subplot(111)
|
|
77
|
+
color_encoder.show_legend(ax)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@patch("matplotlib.pyplot.figure")
|
|
81
|
+
def test_ColorEncoder_show_legend_sort(figure, color_encoder):
|
|
82
|
+
ax = figure.add_subplot(111)
|
|
83
|
+
color_encoder.show_legend(ax, sort=True)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def test_get_cmap_color_values():
|
|
87
|
+
assert get_cmap_color_values("viridis") == ("#440154", "#fde725")
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import matplotlib
|
|
2
|
+
import matplotlib.pyplot as plt
|
|
3
|
+
import numpy as np
|
|
4
|
+
import pandas as pd
|
|
5
|
+
from ridgeplot import dotted_heatmap
|
|
6
|
+
|
|
7
|
+
matplotlib.use("agg")
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def test_ridgeplot():
|
|
11
|
+
figure = plt.figure()
|
|
12
|
+
ax = figure.add_subplot(111)
|
|
13
|
+
n = 10
|
|
14
|
+
data = pd.DataFrame(
|
|
15
|
+
np.random.randn(n, n),
|
|
16
|
+
index=[f"feature{i}" for i in range(n)],
|
|
17
|
+
columns=[f"sample{i}" for i in range(n)],
|
|
18
|
+
)
|
|
19
|
+
dotted_heatmap.dotted_heatmap(data=data, ax=ax, cmap="viridis", circle_size=None)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import matplotlib
|
|
2
|
+
import matplotlib.pyplot as plt
|
|
3
|
+
import numpy as np
|
|
4
|
+
import pytest
|
|
5
|
+
from ridgeplot import RidgePlotError, ridgeplot
|
|
6
|
+
|
|
7
|
+
matplotlib.use("agg")
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@pytest.fixture(scope="module")
|
|
11
|
+
def data():
|
|
12
|
+
data_dict = {}
|
|
13
|
+
for i in range(10):
|
|
14
|
+
data_dict["data_{}".format(i)] = np.random.randn(100) * (i + 1)
|
|
15
|
+
return data_dict
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def test_ridgeplot_bad_fill_color(data):
|
|
19
|
+
figure = plt.figure()
|
|
20
|
+
ax = figure.add_subplot(111)
|
|
21
|
+
with pytest.raises(RidgePlotError) as e:
|
|
22
|
+
ridgeplot(ax=ax, data=data, fill_colors=["white", "white"])
|
|
23
|
+
assert "fill_colors must be same length as data" in str(e.value), "Failed to catch fill color length diff"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def test_ridgeplot_bad_line_color(data):
|
|
27
|
+
figure = plt.figure()
|
|
28
|
+
ax = figure.add_subplot(111)
|
|
29
|
+
with pytest.raises(RidgePlotError) as e:
|
|
30
|
+
ridgeplot(ax=ax, data=data, line_colors=["white", "white"])
|
|
31
|
+
assert "line_colors must be same length as data" in str(e.value), "Failed to catch line color length diff"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_ridgeplot(data):
|
|
35
|
+
figure = plt.figure()
|
|
36
|
+
ax = figure.add_subplot(111)
|
|
37
|
+
ridgeplot(ax, data, xlim=(-20, 20))
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import pytest
|
|
3
|
+
from ridgeplot.stats import scaling
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@pytest.mark.parametrize(
|
|
7
|
+
"xs,expected",
|
|
8
|
+
[
|
|
9
|
+
([1, 2, 3, 4], [0, 0.333, 0.666, 1]),
|
|
10
|
+
([8, 6, 4, 2], [1, 0.666, 0.333, 0]),
|
|
11
|
+
([1, 1, 1, 2], [0, 0, 0, 1]),
|
|
12
|
+
([2, 1, 1, 0], [1, 0.5, 0.5, 0]),
|
|
13
|
+
],
|
|
14
|
+
)
|
|
15
|
+
def test_scaling(xs, expected):
|
|
16
|
+
out = scaling(xs)
|
|
17
|
+
assert np.all(np.isclose(out, expected, atol=0.001)), "Failed test"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_scaling_exception():
|
|
21
|
+
with pytest.raises(ValueError, match="The input list should not be homogenous"):
|
|
22
|
+
scaling([1, 1, 1, 1])
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
[tool.poetry]
|
|
2
|
-
name = "ridgeplot-py"
|
|
3
|
-
version = "0.2.7" # managed by poetry-dynamic-versioning
|
|
4
|
-
description = "Plotting ridgeplots with matplotlib"
|
|
5
|
-
authors = ["Douglas Wu <wckdouglas@gmail.com>"]
|
|
6
|
-
license = "MIT"
|
|
7
|
-
packages = [{ "include" = "ridgeplot" }]
|
|
8
|
-
readme = "README.md"
|
|
9
|
-
|
|
10
|
-
[tool.poetry.dependencies]
|
|
11
|
-
python = "^3.9"
|
|
12
|
-
scipy = "^1.8.0"
|
|
13
|
-
matplotlib = "^3.8"
|
|
14
|
-
more-itertools = "^8.9.0"
|
|
15
|
-
numpy = "^1.21.1"
|
|
16
|
-
pandas = "^2.2.2"
|
|
17
|
-
poetry = "^1.8.3"
|
|
18
|
-
|
|
19
|
-
[tool.poetry.group.dev]
|
|
20
|
-
optional = true
|
|
21
|
-
|
|
22
|
-
[tool.poetry.group.dev.dependencies]
|
|
23
|
-
pytest = "^6.2.5"
|
|
24
|
-
pytest-cov = "^2.12.1"
|
|
25
|
-
mypy = "^0.990"
|
|
26
|
-
ruff = "^0.0.290"
|
|
27
|
-
pre-commit = "^3.7.0"
|
|
28
|
-
|
|
29
|
-
[tool.poetry-dynamic-versioning]
|
|
30
|
-
enable = false
|
|
31
|
-
vcs = "git"
|
|
32
|
-
metadata = false
|
|
33
|
-
bump = true
|
|
34
|
-
style = "pep440"
|
|
35
|
-
pattern = "^(?P<base>\\d+\\.\\d+\\.\\d+)(-?((?P<stage>[a-zA-Z]+)\\.?(?P<revision>\\d+)?))?"
|
|
36
|
-
format-jinja = """
|
|
37
|
-
{%- set ns = namespace(version=base) -%}
|
|
38
|
-
{%- for i in range(distance) -%}
|
|
39
|
-
{%- set ns.version = bump_version(ns.version) -%}
|
|
40
|
-
{%- endfor -%}
|
|
41
|
-
{{- ns.version -}}
|
|
42
|
-
"""
|
|
43
|
-
|
|
44
|
-
[build-system]
|
|
45
|
-
requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning>=1.0.0,<2.0.0"]
|
|
46
|
-
build-backend = "poetry_dynamic_versioning.backend"
|
|
47
|
-
|
|
48
|
-
[tool.mypy]
|
|
49
|
-
plugins = "numpy.typing.mypy_plugin"
|
|
50
|
-
ignore_missing_imports = true
|
|
51
|
-
strict_optional = true
|
|
52
|
-
check_untyped_defs = true
|
|
53
|
-
|
|
54
|
-
[[tool.mypy.overrides]]
|
|
55
|
-
module = ["matplotlib.*", "scipy.*"]
|
|
56
|
-
ignore_errors = true
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
[tool.ruff]
|
|
60
|
-
line-length = 120
|
|
61
|
-
select = ['E', 'F', 'W', 'I']
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|