marsilea 0.4.2__tar.gz → 0.4.3__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.
- marsilea-0.4.3/PKG-INFO +168 -0
- marsilea-0.4.3/README.md +113 -0
- {marsilea-0.4.2 → marsilea-0.4.3}/pyproject.toml +20 -3
- {marsilea-0.4.2 → marsilea-0.4.3}/src/marsilea/__init__.py +1 -1
- {marsilea-0.4.2 → marsilea-0.4.3}/src/marsilea/_deform.py +17 -3
- {marsilea-0.4.2 → marsilea-0.4.3}/src/marsilea/base.py +30 -6
- {marsilea-0.4.2 → marsilea-0.4.3}/src/marsilea/dendrogram.py +37 -5
- {marsilea-0.4.2 → marsilea-0.4.3}/src/marsilea/exceptions.py +5 -4
- {marsilea-0.4.2 → marsilea-0.4.3}/src/marsilea/heatmap.py +2 -0
- {marsilea-0.4.2 → marsilea-0.4.3}/src/marsilea/plotter/__init__.py +1 -1
- marsilea-0.4.3/src/marsilea/plotter/_images.py +293 -0
- {marsilea-0.4.2 → marsilea-0.4.3}/src/marsilea/plotter/_seaborn.py +5 -4
- {marsilea-0.4.2 → marsilea-0.4.3}/src/marsilea/plotter/arc.py +1 -2
- {marsilea-0.4.2 → marsilea-0.4.3}/src/marsilea/plotter/bar.py +8 -7
- {marsilea-0.4.2 → marsilea-0.4.3}/src/marsilea/plotter/base.py +12 -2
- {marsilea-0.4.2 → marsilea-0.4.3}/src/marsilea/plotter/bio.py +3 -2
- {marsilea-0.4.2 → marsilea-0.4.3}/src/marsilea/plotter/mesh.py +25 -13
- {marsilea-0.4.2 → marsilea-0.4.3}/src/marsilea/plotter/text.py +69 -32
- {marsilea-0.4.2 → marsilea-0.4.3}/src/marsilea/utils.py +1 -2
- marsilea-0.4.2/.github/workflows/build.yaml +0 -70
- marsilea-0.4.2/.github/workflows/deploy_streamlit.yaml +0 -39
- marsilea-0.4.2/.github/workflows/lint.yaml +0 -10
- marsilea-0.4.2/.streamlit/config.toml +0 -6
- marsilea-0.4.2/CITATION.cff +0 -37
- marsilea-0.4.2/CODE_OF_CONDUCT.md +0 -128
- marsilea-0.4.2/PKG-INFO +0 -76
- marsilea-0.4.2/README.md +0 -42
- marsilea-0.4.2/src/marsilea/plotter/_images.py +0 -99
- {marsilea-0.4.2 → marsilea-0.4.3}/.gitignore +0 -0
- {marsilea-0.4.2 → marsilea-0.4.3}/LICENSE +0 -0
- {marsilea-0.4.2 → marsilea-0.4.3}/setup.py +0 -0
- {marsilea-0.4.2 → marsilea-0.4.3}/src/marsilea/_api.py +0 -0
- {marsilea-0.4.2 → marsilea-0.4.3}/src/marsilea/dataset.py +0 -0
- {marsilea-0.4.2 → marsilea-0.4.3}/src/marsilea/layers.py +0 -0
- {marsilea-0.4.2 → marsilea-0.4.3}/src/marsilea/layout.py +0 -0
- {marsilea-0.4.2 → marsilea-0.4.3}/src/marsilea/plotter/_utils.py +0 -0
- {marsilea-0.4.2 → marsilea-0.4.3}/src/marsilea/plotter/area.py +0 -0
- {marsilea-0.4.2 → marsilea-0.4.3}/src/marsilea/upset.py +0 -0
- {marsilea-0.4.2 → marsilea-0.4.3}/src/oncoprinter/__init__.py +0 -0
- {marsilea-0.4.2 → marsilea-0.4.3}/src/oncoprinter/core.py +0 -0
- {marsilea-0.4.2 → marsilea-0.4.3}/src/oncoprinter/preset.py +0 -0
marsilea-0.4.3/PKG-INFO
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: marsilea
|
|
3
|
+
Version: 0.4.3
|
|
4
|
+
Dynamic: Summary
|
|
5
|
+
Project-URL: Home, https://github.com/Marsilea-viz/marsilea
|
|
6
|
+
Author: Zhihang Zheng
|
|
7
|
+
Author-email: Mr-Milk <yzheng@cemm.at>
|
|
8
|
+
License: The MIT License (MIT)
|
|
9
|
+
|
|
10
|
+
Copyright (c) 2024 Mr-Milk
|
|
11
|
+
|
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
14
|
+
in the Software without restriction, including without limitation the rights
|
|
15
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
17
|
+
furnished to do so, subject to the following conditions:
|
|
18
|
+
|
|
19
|
+
The above copyright notice and this permission notice shall be included in
|
|
20
|
+
all copies or substantial portions of the Software.
|
|
21
|
+
|
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
28
|
+
THE SOFTWARE.
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Classifier: Framework :: Matplotlib
|
|
31
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
32
|
+
Classifier: Programming Language :: Python :: 3
|
|
33
|
+
Requires-Python: >=3.8
|
|
34
|
+
Requires-Dist: legendkit
|
|
35
|
+
Requires-Dist: matplotlib>=3.6
|
|
36
|
+
Requires-Dist: numpy
|
|
37
|
+
Requires-Dist: pandas
|
|
38
|
+
Requires-Dist: platformdirs
|
|
39
|
+
Requires-Dist: scipy
|
|
40
|
+
Requires-Dist: seaborn
|
|
41
|
+
Provides-Extra: dev
|
|
42
|
+
Requires-Dist: icecream; extra == 'dev'
|
|
43
|
+
Requires-Dist: mpl-fontkit; extra == 'dev'
|
|
44
|
+
Requires-Dist: numpydoc; extra == 'dev'
|
|
45
|
+
Requires-Dist: pydata-sphinx-theme; extra == 'dev'
|
|
46
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
47
|
+
Requires-Dist: python-hmr; extra == 'dev'
|
|
48
|
+
Requires-Dist: ruff; extra == 'dev'
|
|
49
|
+
Requires-Dist: scikit-learn; extra == 'dev'
|
|
50
|
+
Requires-Dist: sphinx; extra == 'dev'
|
|
51
|
+
Requires-Dist: sphinx-copybutton; extra == 'dev'
|
|
52
|
+
Requires-Dist: sphinx-design; extra == 'dev'
|
|
53
|
+
Requires-Dist: sphinx-gallery; extra == 'dev'
|
|
54
|
+
Description-Content-Type: text/markdown
|
|
55
|
+
|
|
56
|
+
<p align="center">
|
|
57
|
+
<picture align="center">
|
|
58
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/Marsilea-viz/marsilea/raw/main/img/banner-dark.jpg">
|
|
59
|
+
<source media="(prefers-color-scheme: light)" srcset="https://github.com/Marsilea-viz/marsilea/raw/main/img/banner-blue.jpg">
|
|
60
|
+
<img alt="Shows a bar chart with benchmark results." src="https://github.com/Marsilea-viz/marsilea/raw/main/img/banner-dark.jpg" width="400">
|
|
61
|
+
</picture>
|
|
62
|
+
</p>
|
|
63
|
+
|
|
64
|
+
[](https://marsilea.readthedocs.io/en/stable)
|
|
65
|
+

|
|
66
|
+

|
|
67
|
+
|
|
68
|
+
# Marsilea: Declarative creation of composable visualization!
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Documentation
|
|
73
|
+
|
|
74
|
+
You can read the documentation on Read the Docs.
|
|
75
|
+
|
|
76
|
+
[Read Documentation](https://marsilea.readthedocs.io/)
|
|
77
|
+
|
|
78
|
+
## Installation
|
|
79
|
+
|
|
80
|
+
```shell
|
|
81
|
+
pip install marsilea
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## What is Composable Visualization?
|
|
85
|
+
|
|
86
|
+
<p align="center">
|
|
87
|
+
<picture align="center">
|
|
88
|
+
<img alt="Shows a bar chart with benchmark results." src="https://github.com/Marsilea-viz/marsilea/raw/main/img/showcase.gif" width="300">
|
|
89
|
+
</picture>
|
|
90
|
+
</p>
|
|
91
|
+
|
|
92
|
+
When we do visualization, we often need to combine multiple plots to show different aspects of the data.
|
|
93
|
+
For example, we may need to create a heatmap to show the expression of genes in different cells,
|
|
94
|
+
and then create a bar chart to show the expression of genes in different cell types.
|
|
95
|
+
A visualization contains multiple plots is called a composable visualization.
|
|
96
|
+
In Marsilea, we employ a declarative approach for user to create composable visualization incrementally.
|
|
97
|
+
|
|
98
|
+
## Examples
|
|
99
|
+
|
|
100
|
+
<table>
|
|
101
|
+
<thead>
|
|
102
|
+
<tr>
|
|
103
|
+
<th>
|
|
104
|
+
<a href="https://marsilea.readthedocs.io/en/latest/examples/Gallery/plot_tiobe_index.html">
|
|
105
|
+
Bar Chart With Image
|
|
106
|
+
</a>
|
|
107
|
+
</th>
|
|
108
|
+
<th>
|
|
109
|
+
<a href="https://marsilea.readthedocs.io/en/latest/examples/Gallery/plot_oil_well.html">
|
|
110
|
+
Stacked Bar
|
|
111
|
+
</a>
|
|
112
|
+
</th>
|
|
113
|
+
<th>
|
|
114
|
+
<a href="https://marsilea.readthedocs.io/en/latest/examples/Gallery/plot_arc_diagram.html">
|
|
115
|
+
Arc Diagram
|
|
116
|
+
</a>
|
|
117
|
+
</th>
|
|
118
|
+
</tr>
|
|
119
|
+
</thead>
|
|
120
|
+
<tbody>
|
|
121
|
+
<tr>
|
|
122
|
+
<td>
|
|
123
|
+
<img src="https://marsilea.readthedocs.io/en/latest/_images/sphx_glr_plot_tiobe_index_001_2_00x.png" height="300px">
|
|
124
|
+
</td>
|
|
125
|
+
<td>
|
|
126
|
+
<img src="https://marsilea.readthedocs.io/en/latest/_images/sphx_glr_plot_oil_well_001_2_00x.png" height="300px">
|
|
127
|
+
</td>
|
|
128
|
+
<td>
|
|
129
|
+
<img src="https://marsilea.readthedocs.io/en/latest/_images/sphx_glr_plot_arc_diagram_001_2_00x.png" width="300px">
|
|
130
|
+
</td>
|
|
131
|
+
</tr>
|
|
132
|
+
</tbody>
|
|
133
|
+
</table>
|
|
134
|
+
|
|
135
|
+
<table>
|
|
136
|
+
<thead>
|
|
137
|
+
<tr>
|
|
138
|
+
<th>
|
|
139
|
+
<a href="https://marsilea.readthedocs.io/en/latest/examples/Gallery/plot_pbmc3k.html">
|
|
140
|
+
Heatmap
|
|
141
|
+
</a>
|
|
142
|
+
</th>
|
|
143
|
+
<th>
|
|
144
|
+
<a href="https://marsilea.readthedocs.io/en/latest/examples/Gallery/plot_oncoprint.html">
|
|
145
|
+
Oncoprint
|
|
146
|
+
</a>
|
|
147
|
+
</th>
|
|
148
|
+
<th>
|
|
149
|
+
<a href="https://marsilea.readthedocs.io/en/latest/examples/Gallery/plot_upset.html">
|
|
150
|
+
Upsetplot
|
|
151
|
+
</a>
|
|
152
|
+
</th>
|
|
153
|
+
</tr>
|
|
154
|
+
</thead>
|
|
155
|
+
<tbody>
|
|
156
|
+
<tr>
|
|
157
|
+
<td>
|
|
158
|
+
<img src="https://marsilea.readthedocs.io/en/latest/_images/sphx_glr_plot_pbmc3k_001_2_00x.png" width="300px">
|
|
159
|
+
</td>
|
|
160
|
+
<td>
|
|
161
|
+
<img src="https://marsilea.readthedocs.io/en/latest/_images/sphx_glr_plot_oncoprint_005_2_00x.png" width="300px">
|
|
162
|
+
</td>
|
|
163
|
+
<td>
|
|
164
|
+
<img src="https://marsilea.readthedocs.io/en/latest/_images/sphx_glr_plot_upset_001_2_00x.png" width="300px">
|
|
165
|
+
</td>
|
|
166
|
+
</tr>
|
|
167
|
+
</tbody>
|
|
168
|
+
</table>
|
marsilea-0.4.3/README.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<picture align="center">
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/Marsilea-viz/marsilea/raw/main/img/banner-dark.jpg">
|
|
4
|
+
<source media="(prefers-color-scheme: light)" srcset="https://github.com/Marsilea-viz/marsilea/raw/main/img/banner-blue.jpg">
|
|
5
|
+
<img alt="Shows a bar chart with benchmark results." src="https://github.com/Marsilea-viz/marsilea/raw/main/img/banner-dark.jpg" width="400">
|
|
6
|
+
</picture>
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
[](https://marsilea.readthedocs.io/en/stable)
|
|
10
|
+

|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
# Marsilea: Declarative creation of composable visualization!
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Documentation
|
|
18
|
+
|
|
19
|
+
You can read the documentation on Read the Docs.
|
|
20
|
+
|
|
21
|
+
[Read Documentation](https://marsilea.readthedocs.io/)
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```shell
|
|
26
|
+
pip install marsilea
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## What is Composable Visualization?
|
|
30
|
+
|
|
31
|
+
<p align="center">
|
|
32
|
+
<picture align="center">
|
|
33
|
+
<img alt="Shows a bar chart with benchmark results." src="https://github.com/Marsilea-viz/marsilea/raw/main/img/showcase.gif" width="300">
|
|
34
|
+
</picture>
|
|
35
|
+
</p>
|
|
36
|
+
|
|
37
|
+
When we do visualization, we often need to combine multiple plots to show different aspects of the data.
|
|
38
|
+
For example, we may need to create a heatmap to show the expression of genes in different cells,
|
|
39
|
+
and then create a bar chart to show the expression of genes in different cell types.
|
|
40
|
+
A visualization contains multiple plots is called a composable visualization.
|
|
41
|
+
In Marsilea, we employ a declarative approach for user to create composable visualization incrementally.
|
|
42
|
+
|
|
43
|
+
## Examples
|
|
44
|
+
|
|
45
|
+
<table>
|
|
46
|
+
<thead>
|
|
47
|
+
<tr>
|
|
48
|
+
<th>
|
|
49
|
+
<a href="https://marsilea.readthedocs.io/en/latest/examples/Gallery/plot_tiobe_index.html">
|
|
50
|
+
Bar Chart With Image
|
|
51
|
+
</a>
|
|
52
|
+
</th>
|
|
53
|
+
<th>
|
|
54
|
+
<a href="https://marsilea.readthedocs.io/en/latest/examples/Gallery/plot_oil_well.html">
|
|
55
|
+
Stacked Bar
|
|
56
|
+
</a>
|
|
57
|
+
</th>
|
|
58
|
+
<th>
|
|
59
|
+
<a href="https://marsilea.readthedocs.io/en/latest/examples/Gallery/plot_arc_diagram.html">
|
|
60
|
+
Arc Diagram
|
|
61
|
+
</a>
|
|
62
|
+
</th>
|
|
63
|
+
</tr>
|
|
64
|
+
</thead>
|
|
65
|
+
<tbody>
|
|
66
|
+
<tr>
|
|
67
|
+
<td>
|
|
68
|
+
<img src="https://marsilea.readthedocs.io/en/latest/_images/sphx_glr_plot_tiobe_index_001_2_00x.png" height="300px">
|
|
69
|
+
</td>
|
|
70
|
+
<td>
|
|
71
|
+
<img src="https://marsilea.readthedocs.io/en/latest/_images/sphx_glr_plot_oil_well_001_2_00x.png" height="300px">
|
|
72
|
+
</td>
|
|
73
|
+
<td>
|
|
74
|
+
<img src="https://marsilea.readthedocs.io/en/latest/_images/sphx_glr_plot_arc_diagram_001_2_00x.png" width="300px">
|
|
75
|
+
</td>
|
|
76
|
+
</tr>
|
|
77
|
+
</tbody>
|
|
78
|
+
</table>
|
|
79
|
+
|
|
80
|
+
<table>
|
|
81
|
+
<thead>
|
|
82
|
+
<tr>
|
|
83
|
+
<th>
|
|
84
|
+
<a href="https://marsilea.readthedocs.io/en/latest/examples/Gallery/plot_pbmc3k.html">
|
|
85
|
+
Heatmap
|
|
86
|
+
</a>
|
|
87
|
+
</th>
|
|
88
|
+
<th>
|
|
89
|
+
<a href="https://marsilea.readthedocs.io/en/latest/examples/Gallery/plot_oncoprint.html">
|
|
90
|
+
Oncoprint
|
|
91
|
+
</a>
|
|
92
|
+
</th>
|
|
93
|
+
<th>
|
|
94
|
+
<a href="https://marsilea.readthedocs.io/en/latest/examples/Gallery/plot_upset.html">
|
|
95
|
+
Upsetplot
|
|
96
|
+
</a>
|
|
97
|
+
</th>
|
|
98
|
+
</tr>
|
|
99
|
+
</thead>
|
|
100
|
+
<tbody>
|
|
101
|
+
<tr>
|
|
102
|
+
<td>
|
|
103
|
+
<img src="https://marsilea.readthedocs.io/en/latest/_images/sphx_glr_plot_pbmc3k_001_2_00x.png" width="300px">
|
|
104
|
+
</td>
|
|
105
|
+
<td>
|
|
106
|
+
<img src="https://marsilea.readthedocs.io/en/latest/_images/sphx_glr_plot_oncoprint_005_2_00x.png" width="300px">
|
|
107
|
+
</td>
|
|
108
|
+
<td>
|
|
109
|
+
<img src="https://marsilea.readthedocs.io/en/latest/_images/sphx_glr_plot_upset_001_2_00x.png" width="300px">
|
|
110
|
+
</td>
|
|
111
|
+
</tr>
|
|
112
|
+
</tbody>
|
|
113
|
+
</table>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["
|
|
3
|
-
build-backend = "
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "marsilea"
|
|
@@ -44,7 +44,13 @@ dev = [
|
|
|
44
44
|
"mpl_fontkit"
|
|
45
45
|
]
|
|
46
46
|
|
|
47
|
-
[tool.
|
|
47
|
+
[tool.hatch.version]
|
|
48
|
+
path = "src/marsilea/__init__.py"
|
|
49
|
+
|
|
50
|
+
[tool.hatch.build.targets.wheel]
|
|
51
|
+
packages = ["src/marsilea", "src/oncoprinter"]
|
|
52
|
+
|
|
53
|
+
[tool.hatch.build.targets.sdist]
|
|
48
54
|
exclude = [
|
|
49
55
|
"docs",
|
|
50
56
|
"app",
|
|
@@ -54,6 +60,17 @@ exclude = [
|
|
|
54
60
|
"scripts",
|
|
55
61
|
"readthedocs.yaml",
|
|
56
62
|
]
|
|
63
|
+
include = [
|
|
64
|
+
"README.md",
|
|
65
|
+
"LICENSE",
|
|
66
|
+
"pyproject.toml",
|
|
67
|
+
"setup.py",
|
|
68
|
+
"src/marsilea",
|
|
69
|
+
"src/oncoprinter",
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
[tool.ruff.format]
|
|
73
|
+
docstring-code-format = true
|
|
57
74
|
|
|
58
75
|
[tool.ruff.lint.per-file-ignores]
|
|
59
76
|
"__init__.py" = ["F401"]
|
|
@@ -84,19 +84,29 @@ class Deformation:
|
|
|
84
84
|
self.data_col_reindex = reindex
|
|
85
85
|
self._col_clustered = False
|
|
86
86
|
|
|
87
|
-
def set_cluster(
|
|
87
|
+
def set_cluster(
|
|
88
|
+
self,
|
|
89
|
+
col=None,
|
|
90
|
+
row=None,
|
|
91
|
+
use_meta=True,
|
|
92
|
+
linkage=None,
|
|
93
|
+
meta_linkage=None,
|
|
94
|
+
**kwargs,
|
|
95
|
+
):
|
|
88
96
|
if col is not None:
|
|
89
97
|
self.is_col_cluster = col
|
|
90
98
|
self.col_cluster_kws = kwargs
|
|
91
99
|
self._col_clustered = False
|
|
92
100
|
self._use_col_meta = use_meta
|
|
93
101
|
self.col_linkage = linkage
|
|
102
|
+
self.col_meta_linkage = meta_linkage
|
|
94
103
|
if row is not None:
|
|
95
104
|
self.is_row_cluster = row
|
|
96
105
|
self.row_cluster_kws = kwargs
|
|
97
106
|
self._row_clustered = False
|
|
98
107
|
self._use_row_meta = use_meta
|
|
99
108
|
self.row_linkage = linkage
|
|
109
|
+
self.row_meta_linkage = meta_linkage
|
|
100
110
|
|
|
101
111
|
def get_data(self):
|
|
102
112
|
data = self.data
|
|
@@ -204,7 +214,9 @@ class Deformation:
|
|
|
204
214
|
Dendrogram(chunk, linkage=linkage, key=k, **self.row_cluster_kws)
|
|
205
215
|
)
|
|
206
216
|
|
|
207
|
-
dg = GroupDendrogram(
|
|
217
|
+
dg = GroupDendrogram(
|
|
218
|
+
dens, linkage=self.row_meta_linkage, **self.row_cluster_kws
|
|
219
|
+
)
|
|
208
220
|
if self._use_row_meta:
|
|
209
221
|
self.row_chunk_index = dg.reorder_index
|
|
210
222
|
else:
|
|
@@ -232,7 +244,9 @@ class Deformation:
|
|
|
232
244
|
dens.append(
|
|
233
245
|
Dendrogram(chunk.T, linkage=linkage, key=k, **self.col_cluster_kws)
|
|
234
246
|
)
|
|
235
|
-
dg = GroupDendrogram(
|
|
247
|
+
dg = GroupDendrogram(
|
|
248
|
+
dens, linkage=self.col_meta_linkage, **self.col_cluster_kws
|
|
249
|
+
)
|
|
236
250
|
if self._use_col_meta:
|
|
237
251
|
self.col_chunk_index = dg.reorder_index
|
|
238
252
|
else:
|
|
@@ -606,9 +606,15 @@ class WhiteBoard(LegendMaker):
|
|
|
606
606
|
return compose_board
|
|
607
607
|
|
|
608
608
|
def _freeze_flex_plots(self, figure):
|
|
609
|
+
main_cell = self.layout.main_cell
|
|
610
|
+
main_width = main_cell.width
|
|
611
|
+
main_height = main_cell.height
|
|
612
|
+
|
|
609
613
|
for plan in self._col_plan + self._row_plan:
|
|
610
614
|
if plan.size is None:
|
|
611
|
-
render_size = plan.get_canvas_size(
|
|
615
|
+
render_size = plan.get_canvas_size(
|
|
616
|
+
figure, main_width=main_width, main_height=main_height
|
|
617
|
+
)
|
|
612
618
|
if render_size is not None:
|
|
613
619
|
self.layout.set_render_size(plan.name, render_size)
|
|
614
620
|
|
|
@@ -835,6 +841,7 @@ class ClusterBoard(WhiteBoard):
|
|
|
835
841
|
method=None,
|
|
836
842
|
metric=None,
|
|
837
843
|
linkage=None,
|
|
844
|
+
meta_linkage=None,
|
|
838
845
|
add_meta=True,
|
|
839
846
|
add_base=True,
|
|
840
847
|
add_divider=True,
|
|
@@ -848,6 +855,7 @@ class ClusterBoard(WhiteBoard):
|
|
|
848
855
|
size=0.5,
|
|
849
856
|
pad=0.0,
|
|
850
857
|
get_meta_center=None,
|
|
858
|
+
rasterized=False,
|
|
851
859
|
):
|
|
852
860
|
"""Run cluster and add dendrogram
|
|
853
861
|
|
|
@@ -869,6 +877,10 @@ class ClusterBoard(WhiteBoard):
|
|
|
869
877
|
Precomputed linkage matrix.
|
|
870
878
|
See scipy's :meth:`linkage <scipy.cluster.hierarchy.linkage>` for
|
|
871
879
|
specific format.
|
|
880
|
+
meta_linkage : ndarray
|
|
881
|
+
Precomputed chunk-level linkage matrix.
|
|
882
|
+
See scipy's :meth:`linkage <scipy.cluster.hierarchy.linkage>` for
|
|
883
|
+
specific format.
|
|
872
884
|
add_meta : None | bool
|
|
873
885
|
By default, add_meta is set to False if the linkage is provided, otherwise True.
|
|
874
886
|
If the data is split, a meta dendrogram can be drawn for data
|
|
@@ -905,6 +917,8 @@ class ClusterBoard(WhiteBoard):
|
|
|
905
917
|
array as input and return a 1D numpy array of the same length as the number
|
|
906
918
|
of columns in the input, representing the centroid. The default will use the
|
|
907
919
|
mean values.
|
|
920
|
+
rasterized : bool
|
|
921
|
+
If True, the dendrogram will be rasterized
|
|
908
922
|
|
|
909
923
|
Examples
|
|
910
924
|
--------
|
|
@@ -926,7 +940,7 @@ class ClusterBoard(WhiteBoard):
|
|
|
926
940
|
:context: close-figs
|
|
927
941
|
|
|
928
942
|
>>> h = ma.Heatmap(data)
|
|
929
|
-
>>> h.
|
|
943
|
+
>>> h.cut_rows(cut=[4, 8])
|
|
930
944
|
>>> h.add_dendrogram("left", add_base=False)
|
|
931
945
|
>>> h.render()
|
|
932
946
|
|
|
@@ -936,7 +950,7 @@ class ClusterBoard(WhiteBoard):
|
|
|
936
950
|
:context: close-figs
|
|
937
951
|
|
|
938
952
|
>>> h = ma.Heatmap(data)
|
|
939
|
-
>>> h.
|
|
953
|
+
>>> h.cut_rows(cut=[4, 8])
|
|
940
954
|
>>> h.add_dendrogram("left", colors=["#5470c6", "#91cc75", "#fac858"])
|
|
941
955
|
>>> h.render()
|
|
942
956
|
|
|
@@ -974,6 +988,7 @@ class ClusterBoard(WhiteBoard):
|
|
|
974
988
|
colors=colors,
|
|
975
989
|
divider_style=divider_style,
|
|
976
990
|
meta_ratio=meta_ratio,
|
|
991
|
+
rasterized=rasterized,
|
|
977
992
|
)
|
|
978
993
|
|
|
979
994
|
deform = self.get_deform()
|
|
@@ -985,8 +1000,10 @@ class ClusterBoard(WhiteBoard):
|
|
|
985
1000
|
method=method,
|
|
986
1001
|
metric=metric,
|
|
987
1002
|
linkage=linkage,
|
|
1003
|
+
meta_linkage=meta_linkage,
|
|
988
1004
|
use_meta=add_meta,
|
|
989
1005
|
get_meta_center=get_meta_center,
|
|
1006
|
+
rasterized=rasterized,
|
|
990
1007
|
)
|
|
991
1008
|
else:
|
|
992
1009
|
den_options["pos"] = "col"
|
|
@@ -996,8 +1013,10 @@ class ClusterBoard(WhiteBoard):
|
|
|
996
1013
|
method=method,
|
|
997
1014
|
metric=metric,
|
|
998
1015
|
linkage=linkage,
|
|
1016
|
+
meta_linkage=meta_linkage,
|
|
999
1017
|
use_meta=add_meta,
|
|
1000
1018
|
get_meta_center=get_meta_center,
|
|
1019
|
+
rasterized=rasterized,
|
|
1001
1020
|
)
|
|
1002
1021
|
|
|
1003
1022
|
def hsplit(self, cut=None, labels=None, order=None, spacing=0.01):
|
|
@@ -1160,7 +1179,7 @@ class ClusterBoard(WhiteBoard):
|
|
|
1160
1179
|
>>> h = ma.Heatmap(data)
|
|
1161
1180
|
>>> labels = ["A", "B", "C", "A", "B", "C", "A", "B", "C", "A"]
|
|
1162
1181
|
>>> h.group_rows(labels, order=["A", "B", "C"])
|
|
1163
|
-
>>> h.add_left(ma.plotter.Labels(labels), pad
|
|
1182
|
+
>>> h.add_left(ma.plotter.Labels(labels), pad=0.1)
|
|
1164
1183
|
>>> h.render()
|
|
1165
1184
|
|
|
1166
1185
|
"""
|
|
@@ -1202,7 +1221,7 @@ class ClusterBoard(WhiteBoard):
|
|
|
1202
1221
|
>>> h = ma.Heatmap(data)
|
|
1203
1222
|
>>> labels = ["A", "B", "C", "A", "B", "C", "A", "B", "C", "A"]
|
|
1204
1223
|
>>> h.group_cols(labels, order=["A", "B", "C"])
|
|
1205
|
-
>>> h.add_top(ma.plotter.Labels(labels), pad
|
|
1224
|
+
>>> h.add_top(ma.plotter.Labels(labels), pad=0.1)
|
|
1206
1225
|
>>> h.render()
|
|
1207
1226
|
|
|
1208
1227
|
"""
|
|
@@ -1334,7 +1353,11 @@ class ClusterBoard(WhiteBoard):
|
|
|
1334
1353
|
if (color is not None) & (not is_color_like(color)):
|
|
1335
1354
|
color = color[0]
|
|
1336
1355
|
den_obj.draw(
|
|
1337
|
-
ax,
|
|
1356
|
+
ax,
|
|
1357
|
+
orient=den["side"],
|
|
1358
|
+
color=color,
|
|
1359
|
+
linewidth=den["linewidth"],
|
|
1360
|
+
rasterized=den["rasterized"],
|
|
1338
1361
|
)
|
|
1339
1362
|
else:
|
|
1340
1363
|
den_obj.draw(
|
|
@@ -1349,6 +1372,7 @@ class ClusterBoard(WhiteBoard):
|
|
|
1349
1372
|
divide=den["add_divider"],
|
|
1350
1373
|
divide_style=den["divider_style"],
|
|
1351
1374
|
meta_ratio=den["meta_ratio"],
|
|
1375
|
+
rasterized=den["rasterized"],
|
|
1352
1376
|
)
|
|
1353
1377
|
|
|
1354
1378
|
def _render_plan(self):
|
|
@@ -18,6 +18,7 @@ class _DendrogramBase:
|
|
|
18
18
|
linkage=None,
|
|
19
19
|
get_meta_center=None,
|
|
20
20
|
key=None,
|
|
21
|
+
**kwargs,
|
|
21
22
|
):
|
|
22
23
|
self.key = key
|
|
23
24
|
self.data = data
|
|
@@ -137,7 +138,9 @@ class _DendrogramBase:
|
|
|
137
138
|
y1 = yc[1]
|
|
138
139
|
return x1, y1
|
|
139
140
|
|
|
140
|
-
def _draw_dendrogram(
|
|
141
|
+
def _draw_dendrogram(
|
|
142
|
+
self, ax, orient="top", color=".1", linewidth=0.7, rasterized=False
|
|
143
|
+
):
|
|
141
144
|
x_coords = self._render_x_coords
|
|
142
145
|
y_coords = self._render_y_coords
|
|
143
146
|
if orient in ["right", "left"]:
|
|
@@ -147,6 +150,7 @@ class _DendrogramBase:
|
|
|
147
150
|
[list(zip(x, y)) for x, y in zip(x_coords, y_coords)],
|
|
148
151
|
color=color,
|
|
149
152
|
linewidth=linewidth,
|
|
153
|
+
rasterized=rasterized,
|
|
150
154
|
)
|
|
151
155
|
ax.add_collection(lines)
|
|
152
156
|
|
|
@@ -173,6 +177,7 @@ class Dendrogram(_DendrogramBase):
|
|
|
173
177
|
linkage=None,
|
|
174
178
|
get_meta_center=None,
|
|
175
179
|
key=None,
|
|
180
|
+
**kwargs,
|
|
176
181
|
):
|
|
177
182
|
super().__init__(
|
|
178
183
|
data,
|
|
@@ -181,6 +186,7 @@ class Dendrogram(_DendrogramBase):
|
|
|
181
186
|
key=key,
|
|
182
187
|
linkage=linkage,
|
|
183
188
|
get_meta_center=get_meta_center,
|
|
189
|
+
**kwargs,
|
|
184
190
|
)
|
|
185
191
|
|
|
186
192
|
# here we left an empty **kwargs to align api with GroupDendrogram
|
|
@@ -193,6 +199,7 @@ class Dendrogram(_DendrogramBase):
|
|
|
193
199
|
add_root=False,
|
|
194
200
|
root_color=None,
|
|
195
201
|
control_ax=True,
|
|
202
|
+
rasterized=False,
|
|
196
203
|
**kwargs,
|
|
197
204
|
):
|
|
198
205
|
"""
|
|
@@ -210,6 +217,8 @@ class Dendrogram(_DendrogramBase):
|
|
|
210
217
|
The color of the root line
|
|
211
218
|
control_ax : bool
|
|
212
219
|
Adjust the axes to ensure the dendrogram will display correctly
|
|
220
|
+
rasterized : bool
|
|
221
|
+
Rasterize the dendrogram to speed up rendering
|
|
213
222
|
|
|
214
223
|
Returns
|
|
215
224
|
-------
|
|
@@ -219,7 +228,9 @@ class Dendrogram(_DendrogramBase):
|
|
|
219
228
|
root_color = color if root_color is None else root_color
|
|
220
229
|
linewidth = 0.7 if linewidth is None else linewidth
|
|
221
230
|
|
|
222
|
-
self._draw_dendrogram(
|
|
231
|
+
self._draw_dendrogram(
|
|
232
|
+
ax, orient=orient, color=color, linewidth=linewidth, rasterized=rasterized
|
|
233
|
+
)
|
|
223
234
|
|
|
224
235
|
xlim = self._render_xlim
|
|
225
236
|
ylim = self._render_ylim
|
|
@@ -244,7 +255,11 @@ class Dendrogram(_DendrogramBase):
|
|
|
244
255
|
x2 = x1
|
|
245
256
|
y2 = ylim[1]
|
|
246
257
|
root_line = Line2D(
|
|
247
|
-
[x1, x2],
|
|
258
|
+
[x1, x2],
|
|
259
|
+
[y1, y2],
|
|
260
|
+
color=root_color,
|
|
261
|
+
linewidth=linewidth,
|
|
262
|
+
rasterized=rasterized,
|
|
248
263
|
)
|
|
249
264
|
ax.add_artist(root_line)
|
|
250
265
|
|
|
@@ -267,13 +282,20 @@ class GroupDendrogram(_DendrogramBase):
|
|
|
267
282
|
dens: List[Dendrogram],
|
|
268
283
|
method=None,
|
|
269
284
|
metric=None,
|
|
285
|
+
linkage=None,
|
|
270
286
|
get_meta_center=None,
|
|
271
287
|
key=None,
|
|
272
288
|
**kwargs,
|
|
273
289
|
):
|
|
274
290
|
data = np.vstack([d.center for d in dens])
|
|
275
291
|
super().__init__(
|
|
276
|
-
data,
|
|
292
|
+
data,
|
|
293
|
+
method=method,
|
|
294
|
+
metric=metric,
|
|
295
|
+
linkage=linkage,
|
|
296
|
+
get_meta_center=get_meta_center,
|
|
297
|
+
key=key,
|
|
298
|
+
**kwargs,
|
|
277
299
|
)
|
|
278
300
|
self.orig_dens = np.asarray(dens)
|
|
279
301
|
self.dens = np.asarray(dens)[self.reorder_index]
|
|
@@ -305,6 +327,7 @@ class GroupDendrogram(_DendrogramBase):
|
|
|
305
327
|
divide=True,
|
|
306
328
|
divide_style="--",
|
|
307
329
|
meta_ratio=0.2,
|
|
330
|
+
rasterized=False,
|
|
308
331
|
):
|
|
309
332
|
"""
|
|
310
333
|
|
|
@@ -330,6 +353,8 @@ class GroupDendrogram(_DendrogramBase):
|
|
|
330
353
|
The linestyle of the divide line
|
|
331
354
|
meta_ratio : float
|
|
332
355
|
The size of meta dendrogram relative to the base dendrogram
|
|
356
|
+
rasterized : bool
|
|
357
|
+
Rasterize the dendrogram to speed up rendering
|
|
333
358
|
|
|
334
359
|
"""
|
|
335
360
|
|
|
@@ -418,7 +443,11 @@ class GroupDendrogram(_DendrogramBase):
|
|
|
418
443
|
if add_meta:
|
|
419
444
|
# Add meta dendrogram
|
|
420
445
|
self._draw_dendrogram(
|
|
421
|
-
ax,
|
|
446
|
+
ax,
|
|
447
|
+
orient=orient,
|
|
448
|
+
color=meta_color,
|
|
449
|
+
linewidth=linewidth,
|
|
450
|
+
rasterized=rasterized,
|
|
422
451
|
)
|
|
423
452
|
|
|
424
453
|
if divide & add_base & add_meta:
|
|
@@ -432,6 +461,7 @@ class GroupDendrogram(_DendrogramBase):
|
|
|
432
461
|
linestyles=divide_style,
|
|
433
462
|
color=meta_color,
|
|
434
463
|
linewidth=linewidth,
|
|
464
|
+
rasterized=rasterized,
|
|
435
465
|
)
|
|
436
466
|
else:
|
|
437
467
|
ax.vlines(
|
|
@@ -441,6 +471,7 @@ class GroupDendrogram(_DendrogramBase):
|
|
|
441
471
|
linestyles=divide_style,
|
|
442
472
|
color=meta_color,
|
|
443
473
|
linewidth=linewidth,
|
|
474
|
+
rasterized=rasterized,
|
|
444
475
|
)
|
|
445
476
|
|
|
446
477
|
if add_base:
|
|
@@ -455,6 +486,7 @@ class GroupDendrogram(_DendrogramBase):
|
|
|
455
486
|
linewidth=linewidth,
|
|
456
487
|
root_color=meta_color,
|
|
457
488
|
control_ax=False,
|
|
489
|
+
rasterized=rasterized,
|
|
458
490
|
)
|
|
459
491
|
|
|
460
492
|
xlim = render_xlim
|