multiscoresplot 1.0.3__tar.gz → 1.0.5__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.
- multiscoresplot-1.0.5/.github/workflows/docs.yml +27 -0
- {multiscoresplot-1.0.3 → multiscoresplot-1.0.5}/.pre-commit-config.yaml +1 -0
- {multiscoresplot-1.0.3 → multiscoresplot-1.0.5}/PKG-INFO +9 -7
- {multiscoresplot-1.0.3 → multiscoresplot-1.0.5}/README.md +4 -3
- multiscoresplot-1.0.5/docs/api/colorspace.md +25 -0
- multiscoresplot-1.0.5/docs/api/index.md +27 -0
- multiscoresplot-1.0.5/docs/api/interactive.md +8 -0
- multiscoresplot-1.0.5/docs/api/legend.md +5 -0
- multiscoresplot-1.0.5/docs/api/plotting.md +5 -0
- multiscoresplot-1.0.5/docs/api/scoring.md +5 -0
- multiscoresplot-1.0.5/docs/changelog.md +19 -0
- multiscoresplot-1.0.5/docs/examples.md +165 -0
- multiscoresplot-1.0.5/docs/getting-started.md +64 -0
- multiscoresplot-1.0.5/docs/index.md +46 -0
- multiscoresplot-1.0.5/docs/pipeline.md +149 -0
- multiscoresplot-1.0.5/mkdocs.yml +92 -0
- {multiscoresplot-1.0.3 → multiscoresplot-1.0.5}/pyproject.toml +7 -5
- {multiscoresplot-1.0.3 → multiscoresplot-1.0.5}/src/multiscoresplot/__init__.py +1 -1
- multiscoresplot-1.0.5/uv.lock +2784 -0
- {multiscoresplot-1.0.3 → multiscoresplot-1.0.5}/.github/workflows/ci.yml +0 -0
- {multiscoresplot-1.0.3 → multiscoresplot-1.0.5}/.github/workflows/publish.yml +0 -0
- {multiscoresplot-1.0.3 → multiscoresplot-1.0.5}/.gitignore +0 -0
- {multiscoresplot-1.0.3 → multiscoresplot-1.0.5}/LICENSE +0 -0
- {multiscoresplot-1.0.3 → multiscoresplot-1.0.5}/src/multiscoresplot/_colorspace.py +0 -0
- {multiscoresplot-1.0.3 → multiscoresplot-1.0.5}/src/multiscoresplot/_interactive.py +0 -0
- {multiscoresplot-1.0.3 → multiscoresplot-1.0.5}/src/multiscoresplot/_legend.py +0 -0
- {multiscoresplot-1.0.3 → multiscoresplot-1.0.5}/src/multiscoresplot/_plotting.py +0 -0
- {multiscoresplot-1.0.3 → multiscoresplot-1.0.5}/src/multiscoresplot/_scoring.py +0 -0
- {multiscoresplot-1.0.3 → multiscoresplot-1.0.5}/src/multiscoresplot/py.typed +0 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: Deploy Docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
deploy:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- uses: astral-sh/setup-uv@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
|
|
21
|
+
- name: Configure git for gh-deploy
|
|
22
|
+
run: |
|
|
23
|
+
git config user.name "github-actions[bot]"
|
|
24
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
25
|
+
|
|
26
|
+
- name: Deploy to GitHub Pages
|
|
27
|
+
run: uv run --group docs mkdocs gh-deploy --force
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: multiscoresplot
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.5
|
|
4
4
|
Summary: Multi-dimensional gene set scoring and visualization for single-cell transcriptomics
|
|
5
|
-
Project-URL: Homepage, https://github.com/
|
|
6
|
-
Project-URL:
|
|
7
|
-
Project-URL:
|
|
5
|
+
Project-URL: Homepage, https://github.com/AndreMacedo88/multiscoresplot
|
|
6
|
+
Project-URL: Documentation, https://AndreMacedo88.github.io/multiscoresplot/
|
|
7
|
+
Project-URL: Repository, https://github.com/AndreMacedo88/multiscoresplot
|
|
8
|
+
Project-URL: Issues, https://github.com/AndreMacedo88/multiscoresplot/issues
|
|
8
9
|
Author: Andre Macedo
|
|
9
10
|
License-Expression: MIT
|
|
10
11
|
License-File: LICENSE
|
|
@@ -33,9 +34,10 @@ Description-Content-Type: text/markdown
|
|
|
33
34
|
# multiscoresplot
|
|
34
35
|
|
|
35
36
|
[](https://github.com/AndreMacedo88/multiscoresplot/actions/workflows/ci.yml)
|
|
36
|
-
[](https://AndreMacedo88.github.io/multiscoresplot/)
|
|
38
|
+
[](https://pypi.org/project/multiscoresplot/)
|
|
39
|
+
[](https://pypi.org/project/multiscoresplot/)
|
|
37
40
|
[](https://opensource.org/licenses/MIT)
|
|
38
|
-
[](https://pypi.org/project/multiscoresplot/)
|
|
39
41
|
|
|
40
42
|
**Multi-dimensional gene set scoring and visualization for single-cell transcriptomics.**
|
|
41
43
|
|
|
@@ -230,7 +232,7 @@ rgb = msp.reduce_to_rgb(scores, method="umap")
|
|
|
230
232
|
## Development
|
|
231
233
|
|
|
232
234
|
```bash
|
|
233
|
-
git clone https://github.com/
|
|
235
|
+
git clone https://github.com/AndreMacedo88/multiscoresplot.git
|
|
234
236
|
cd multiscoresplot
|
|
235
237
|
|
|
236
238
|
# Install in editable mode with dev dependencies
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# multiscoresplot
|
|
2
2
|
|
|
3
3
|
[](https://github.com/AndreMacedo88/multiscoresplot/actions/workflows/ci.yml)
|
|
4
|
-
[](https://AndreMacedo88.github.io/multiscoresplot/)
|
|
5
|
+
[](https://pypi.org/project/multiscoresplot/)
|
|
6
|
+
[](https://pypi.org/project/multiscoresplot/)
|
|
5
7
|
[](https://opensource.org/licenses/MIT)
|
|
6
|
-
[](https://pypi.org/project/multiscoresplot/)
|
|
7
8
|
|
|
8
9
|
**Multi-dimensional gene set scoring and visualization for single-cell transcriptomics.**
|
|
9
10
|
|
|
@@ -198,7 +199,7 @@ rgb = msp.reduce_to_rgb(scores, method="umap")
|
|
|
198
199
|
## Development
|
|
199
200
|
|
|
200
201
|
```bash
|
|
201
|
-
git clone https://github.com/
|
|
202
|
+
git clone https://github.com/AndreMacedo88/multiscoresplot.git
|
|
202
203
|
cd multiscoresplot
|
|
203
204
|
|
|
204
205
|
# Install in editable mode with dev dependencies
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Color Space
|
|
2
|
+
|
|
3
|
+
Color mapping from gene set scores to RGB (pipeline steps 2–3).
|
|
4
|
+
|
|
5
|
+
## Blending (2–3 gene sets)
|
|
6
|
+
|
|
7
|
+
::: multiscoresplot.blend_to_rgb
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Dimensionality Reduction (2+ gene sets)
|
|
12
|
+
|
|
13
|
+
::: multiscoresplot.reduce_to_rgb
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Custom Reducers
|
|
18
|
+
|
|
19
|
+
::: multiscoresplot.register_reducer
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Utility
|
|
24
|
+
|
|
25
|
+
::: multiscoresplot.get_component_labels
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# API Reference
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
| Function | Description | Pipeline Step |
|
|
6
|
+
|----------|-------------|---------------|
|
|
7
|
+
| [`score_gene_sets`](scoring.md) | Score gene sets per cell via pyUCell | Step 1 |
|
|
8
|
+
| [`blend_to_rgb`](colorspace.md#multiscoresplot.blend_to_rgb) | Multiplicative blend to RGB (2–3 sets) | Step 2 |
|
|
9
|
+
| [`reduce_to_rgb`](colorspace.md#multiscoresplot.reduce_to_rgb) | Dimensionality reduction to RGB (2+ sets) | Step 3 |
|
|
10
|
+
| [`plot_embedding`](plotting.md) | Static matplotlib scatter plot | Step 4 |
|
|
11
|
+
| [`plot_embedding_interactive`](interactive.md) | Interactive Plotly scatter plot | Step 4b |
|
|
12
|
+
| [`render_legend`](legend.md) | Draw color-space legend on axes | Step 5 |
|
|
13
|
+
| [`register_reducer`](colorspace.md#multiscoresplot.register_reducer) | Register a custom reduction method | Extensibility |
|
|
14
|
+
| [`get_component_labels`](colorspace.md#multiscoresplot.get_component_labels) | Get axis labels for a reduction method | Utility |
|
|
15
|
+
|
|
16
|
+
## Module Layout
|
|
17
|
+
|
|
18
|
+
All public functions are available directly from the top-level `multiscoresplot` namespace:
|
|
19
|
+
|
|
20
|
+
```python
|
|
21
|
+
import multiscoresplot as msp
|
|
22
|
+
|
|
23
|
+
msp.score_gene_sets(...)
|
|
24
|
+
msp.blend_to_rgb(...)
|
|
25
|
+
msp.reduce_to_rgb(...)
|
|
26
|
+
msp.plot_embedding(...)
|
|
27
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.0.3
|
|
4
|
+
|
|
5
|
+
- Fix badge display in README
|
|
6
|
+
|
|
7
|
+
## 1.0.2
|
|
8
|
+
|
|
9
|
+
- Fix legend not being plotted in interactive "direct" methods
|
|
10
|
+
- Fix CI badge path in README
|
|
11
|
+
|
|
12
|
+
## 1.0.1
|
|
13
|
+
|
|
14
|
+
- Initial stable release
|
|
15
|
+
- 5-step pipeline: score, blend, reduce, plot, legend
|
|
16
|
+
- Built-in reducers: PCA, NMF, ICA
|
|
17
|
+
- Pluggable reducer registry
|
|
18
|
+
- Static matplotlib and interactive Plotly plotting
|
|
19
|
+
- Color-space legends for direct and reduction modes
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# Examples
|
|
2
|
+
|
|
3
|
+
## Custom Reducer — UMAP
|
|
4
|
+
|
|
5
|
+
Register your own dimensionality reduction method and use it like any built-in:
|
|
6
|
+
|
|
7
|
+
```python
|
|
8
|
+
import multiscoresplot as msp
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def umap_reducer(X, n_components, **kwargs):
|
|
12
|
+
"""Reduce score matrix to RGB via UMAP.
|
|
13
|
+
|
|
14
|
+
Parameters
|
|
15
|
+
----------
|
|
16
|
+
X : ndarray of shape (n_cells, n_gene_sets)
|
|
17
|
+
Score matrix.
|
|
18
|
+
n_components : int
|
|
19
|
+
Number of output components (always 3 for RGB).
|
|
20
|
+
|
|
21
|
+
Returns
|
|
22
|
+
-------
|
|
23
|
+
ndarray of shape (n_cells, 3)
|
|
24
|
+
Embedding with values in [0, 1].
|
|
25
|
+
"""
|
|
26
|
+
import umap
|
|
27
|
+
|
|
28
|
+
embedding = umap.UMAP(n_components=n_components, **kwargs).fit_transform(X)
|
|
29
|
+
# min-max normalize each column to [0, 1]
|
|
30
|
+
for j in range(embedding.shape[1]):
|
|
31
|
+
col = embedding[:, j]
|
|
32
|
+
lo, hi = col.min(), col.max()
|
|
33
|
+
if hi > lo:
|
|
34
|
+
embedding[:, j] = (col - lo) / (hi - lo)
|
|
35
|
+
return embedding
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# Register it
|
|
39
|
+
msp.register_reducer("umap", umap_reducer, component_prefix="UMAP")
|
|
40
|
+
|
|
41
|
+
# Use it
|
|
42
|
+
rgb = msp.reduce_to_rgb(scores, method="umap")
|
|
43
|
+
msp.plot_embedding(adata, rgb, basis="umap", method="umap",
|
|
44
|
+
gene_set_names=list(gene_sets.keys()))
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Different Embeddings
|
|
48
|
+
|
|
49
|
+
Plot the same RGB coloring on different embeddings to compare:
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
import matplotlib.pyplot as plt
|
|
53
|
+
|
|
54
|
+
scores = msp.score_gene_sets(adata, gene_sets, inplace=True)
|
|
55
|
+
rgb = msp.reduce_to_rgb(scores, method="pca")
|
|
56
|
+
|
|
57
|
+
fig, axes = plt.subplots(1, 3, figsize=(18, 5))
|
|
58
|
+
|
|
59
|
+
for ax, basis in zip(axes, ["umap", "pca", "X_scanorama"]):
|
|
60
|
+
msp.plot_embedding(
|
|
61
|
+
adata, rgb,
|
|
62
|
+
basis=basis,
|
|
63
|
+
method="pca",
|
|
64
|
+
gene_set_names=list(gene_sets.keys()),
|
|
65
|
+
ax=ax,
|
|
66
|
+
title=basis.upper(),
|
|
67
|
+
show=False,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
plt.tight_layout()
|
|
71
|
+
plt.show()
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Comparing Reduction Methods
|
|
75
|
+
|
|
76
|
+
Visualize how PCA, NMF, and ICA produce different colorings:
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
import matplotlib.pyplot as plt
|
|
80
|
+
|
|
81
|
+
scores = msp.score_gene_sets(adata, gene_sets, inplace=True)
|
|
82
|
+
|
|
83
|
+
fig, axes = plt.subplots(1, 3, figsize=(18, 5))
|
|
84
|
+
|
|
85
|
+
for ax, method in zip(axes, ["pca", "nmf", "ica"]):
|
|
86
|
+
rgb = msp.reduce_to_rgb(scores, method=method)
|
|
87
|
+
msp.plot_embedding(
|
|
88
|
+
adata, rgb,
|
|
89
|
+
basis="umap",
|
|
90
|
+
method=method,
|
|
91
|
+
gene_set_names=list(gene_sets.keys()),
|
|
92
|
+
ax=ax,
|
|
93
|
+
title=method.upper(),
|
|
94
|
+
show=False,
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
plt.tight_layout()
|
|
98
|
+
plt.show()
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Interactive Plot with Hover Metadata
|
|
102
|
+
|
|
103
|
+
Explore individual cells with hover tooltips:
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
scores = msp.score_gene_sets(adata, gene_sets, inplace=True)
|
|
107
|
+
rgb = msp.reduce_to_rgb(scores, method="nmf")
|
|
108
|
+
|
|
109
|
+
msp.plot_embedding_interactive(
|
|
110
|
+
adata, rgb,
|
|
111
|
+
basis="umap",
|
|
112
|
+
scores=scores,
|
|
113
|
+
method="nmf",
|
|
114
|
+
gene_set_names=list(gene_sets.keys()),
|
|
115
|
+
hover_columns=["n_counts", "cell_type"], # any adata.obs columns
|
|
116
|
+
point_size=2,
|
|
117
|
+
width=800,
|
|
118
|
+
height=600,
|
|
119
|
+
)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Customizing Plot Appearance
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
ax = msp.plot_embedding(
|
|
126
|
+
adata, rgb,
|
|
127
|
+
basis="umap",
|
|
128
|
+
method="pca",
|
|
129
|
+
gene_set_names=list(gene_sets.keys()),
|
|
130
|
+
point_size=5,
|
|
131
|
+
alpha=0.6,
|
|
132
|
+
figsize=(8, 8),
|
|
133
|
+
title="SVZ Neural Lineage",
|
|
134
|
+
legend=True,
|
|
135
|
+
legend_style="side", # legend in a separate panel
|
|
136
|
+
legend_loc="upper right",
|
|
137
|
+
show=False,
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
# Further customize the returned axes
|
|
141
|
+
ax.set_xlabel("UMAP 1", fontsize=14)
|
|
142
|
+
ax.set_ylabel("UMAP 2", fontsize=14)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Direct Blend for 2–3 Gene Sets
|
|
146
|
+
|
|
147
|
+
When you have exactly 2 or 3 gene sets, direct blending gives the most intuitive
|
|
148
|
+
color mapping:
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
two_sets = {
|
|
152
|
+
"Stem": ["Sox2", "Pax6", "Nes"],
|
|
153
|
+
"Neuronal": ["Dcx", "Tubb3", "Neurod1"],
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
scores = msp.score_gene_sets(adata, two_sets, inplace=True)
|
|
157
|
+
rgb = msp.blend_to_rgb(scores) # blue/red by default
|
|
158
|
+
|
|
159
|
+
msp.plot_embedding(
|
|
160
|
+
adata, rgb,
|
|
161
|
+
basis="umap",
|
|
162
|
+
method="direct",
|
|
163
|
+
gene_set_names=list(two_sets.keys()),
|
|
164
|
+
)
|
|
165
|
+
```
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Getting Started
|
|
2
|
+
|
|
3
|
+
## Installation
|
|
4
|
+
|
|
5
|
+
Install from PyPI:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install multiscoresplot
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
For interactive Plotly plots:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install 'multiscoresplot[interactive]'
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Prerequisites
|
|
18
|
+
|
|
19
|
+
multiscoresplot expects an [AnnData](https://anndata.readthedocs.io/) object with:
|
|
20
|
+
|
|
21
|
+
- A precomputed dimensionality reduction embedding (e.g., UMAP, PCA, or Scanorama) stored in `adata.obsm`
|
|
22
|
+
- Gene expression data (raw or normalized) accessible for scoring
|
|
23
|
+
|
|
24
|
+
## Minimal Working Example
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
import multiscoresplot as msp
|
|
28
|
+
|
|
29
|
+
# 1. Define your gene sets
|
|
30
|
+
gene_sets = {
|
|
31
|
+
"Stem": ["Sox2", "Pax6", "Nes"],
|
|
32
|
+
"Neuronal": ["Dcx", "Tubb3", "Neurod1"],
|
|
33
|
+
"Astrocytic": ["Gfap", "Aqp4", "Aldh1l1"],
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
# 2. Score gene sets per cell (stores in adata.obs as score-<name>)
|
|
37
|
+
scores = msp.score_gene_sets(adata, gene_sets, inplace=True)
|
|
38
|
+
|
|
39
|
+
# 3. Map scores to RGB — choose one:
|
|
40
|
+
# Direct blend (2–3 gene sets only)
|
|
41
|
+
rgb = msp.blend_to_rgb(scores)
|
|
42
|
+
# Or dimensionality reduction (any number of gene sets)
|
|
43
|
+
rgb = msp.reduce_to_rgb(scores, method="pca")
|
|
44
|
+
|
|
45
|
+
# 4. Plot on a UMAP embedding
|
|
46
|
+
msp.plot_embedding(
|
|
47
|
+
adata, rgb,
|
|
48
|
+
basis="umap",
|
|
49
|
+
method="pca",
|
|
50
|
+
gene_set_names=list(gene_sets.keys()),
|
|
51
|
+
)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
!!! tip "Which color mapping to use?"
|
|
55
|
+
- **`blend_to_rgb`** — Best for 2–3 gene sets. Uses intuitive multiplicative blending from white, where each gene set darkens toward its assigned color.
|
|
56
|
+
- **`reduce_to_rgb`** — Works for any number of gene sets (2+). Uses PCA, NMF, or ICA to project scores into a 3D RGB space.
|
|
57
|
+
|
|
58
|
+
See the [Pipeline Guide](pipeline.md) for a detailed comparison.
|
|
59
|
+
|
|
60
|
+
## Next Steps
|
|
61
|
+
|
|
62
|
+
- [Pipeline Guide](pipeline.md) — Understand each step and when to use each method
|
|
63
|
+
- [API Reference](api/index.md) — Full function signatures and parameters
|
|
64
|
+
- [Examples](examples.md) — Custom reducers, plot customization, and more
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# multiscoresplot
|
|
2
|
+
|
|
3
|
+
**Multi-dimensional gene set scoring and visualization for single-cell transcriptomics.**
|
|
4
|
+
|
|
5
|
+
Color dimensionality reduction plots (UMAP, PCA, etc.) using a multi-dimensional
|
|
6
|
+
color space derived from gene set scores — visualize the activity of multiple gene
|
|
7
|
+
programs simultaneously in a single plot.
|
|
8
|
+
|
|
9
|
+
## Key Features
|
|
10
|
+
|
|
11
|
+
- **Score** gene sets per cell using [UCell](https://github.com/Cem-Gulec/pyUCell)
|
|
12
|
+
- **Blend** 2–3 gene sets to RGB via multiplicative blending
|
|
13
|
+
- **Reduce** any number of gene sets to RGB via PCA / NMF / ICA
|
|
14
|
+
- **Plot** static matplotlib or interactive Plotly scatter plots
|
|
15
|
+
- **Extend** with custom dimensionality reduction methods
|
|
16
|
+
|
|
17
|
+
## Quick Example
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
import multiscoresplot as msp
|
|
21
|
+
|
|
22
|
+
# Define gene sets of interest
|
|
23
|
+
gene_sets = {
|
|
24
|
+
"qNSCs": ["Id3", "Aldoc", "Slc1a3"],
|
|
25
|
+
"aNSCs": ["Egfr", "Ascl1", "Mki67"],
|
|
26
|
+
"TAP": ["Dll1", "Dcx", "Neurod1"],
|
|
27
|
+
"NB": ["Dcx", "Sox11", "Tubb3"],
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
# 1. Score gene sets per cell
|
|
31
|
+
scores = msp.score_gene_sets(adata, gene_sets, inplace=True)
|
|
32
|
+
|
|
33
|
+
# 2. Map scores to RGB colors
|
|
34
|
+
rgb = msp.reduce_to_rgb(scores, method="pca")
|
|
35
|
+
|
|
36
|
+
# 3. Plot
|
|
37
|
+
msp.plot_embedding(
|
|
38
|
+
adata, rgb,
|
|
39
|
+
basis="umap",
|
|
40
|
+
method="pca",
|
|
41
|
+
gene_set_names=list(gene_sets.keys()),
|
|
42
|
+
)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
[Get Started](getting-started.md){ .md-button .md-button--primary }
|
|
46
|
+
[API Reference](api/index.md){ .md-button }
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Pipeline Guide
|
|
2
|
+
|
|
3
|
+
multiscoresplot follows a 5-step pipeline to go from gene sets to a colored embedding plot.
|
|
4
|
+
|
|
5
|
+
## Step 1 — Score Gene Sets
|
|
6
|
+
|
|
7
|
+
Calculate per-cell gene set scores using [pyUCell](https://github.com/Cem-Gulec/pyUCell).
|
|
8
|
+
Scores are stored in `adata.obs` as `score-<name>` columns with values in [0, 1].
|
|
9
|
+
|
|
10
|
+
```python
|
|
11
|
+
scores = msp.score_gene_sets(adata, gene_sets, inplace=True)
|
|
12
|
+
|
|
13
|
+
# With tuning parameters
|
|
14
|
+
scores = msp.score_gene_sets(
|
|
15
|
+
adata, gene_sets,
|
|
16
|
+
max_rank=1500, # rank cap (tune to median genes per cell)
|
|
17
|
+
chunk_size=1000, # cells per batch
|
|
18
|
+
n_jobs=-1, # parallelism (-1 = all cores)
|
|
19
|
+
inplace=False, # don't store in adata.obs
|
|
20
|
+
)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
!!! note
|
|
24
|
+
`score_gene_sets` wraps pyUCell's ranking-based scoring. The `max_rank` parameter
|
|
25
|
+
controls how many top-ranked genes per cell are considered — set it close to the
|
|
26
|
+
median number of detected genes per cell for best results.
|
|
27
|
+
|
|
28
|
+
## Step 2 — Blend to RGB (2–3 Gene Sets)
|
|
29
|
+
|
|
30
|
+
For **2–3 gene sets**, multiplicative blending maps scores directly to colors. Starting from
|
|
31
|
+
white, each gene set darkens the color toward its base hue proportionally to the score.
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
# Default colors (2 sets: blue/red, 3 sets: R/G/B)
|
|
35
|
+
rgb = msp.blend_to_rgb(scores)
|
|
36
|
+
|
|
37
|
+
# Custom colors
|
|
38
|
+
rgb = msp.blend_to_rgb(scores, colors=[(1, 0, 0), (0, 0.5, 1)])
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**How it works:** Each cell starts as white `(1, 1, 1)`. For each gene set, the cell's
|
|
42
|
+
color is multiplied element-wise by a blend between white and the gene set's base color,
|
|
43
|
+
weighted by the score. High scores pull the color toward the base hue; low scores leave
|
|
44
|
+
it near white. Cells with multiple high scores produce mixed colors.
|
|
45
|
+
|
|
46
|
+
## Step 3 — Reduce to RGB (2+ Gene Sets)
|
|
47
|
+
|
|
48
|
+
For **any number of gene sets**, dimensionality reduction projects the score matrix into
|
|
49
|
+
3 components that become RGB channels.
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
rgb = msp.reduce_to_rgb(scores, method="pca") # default
|
|
53
|
+
rgb = msp.reduce_to_rgb(scores, method="nmf")
|
|
54
|
+
rgb = msp.reduce_to_rgb(scores, method="ica")
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Choosing a Reduction Method
|
|
58
|
+
|
|
59
|
+
| Method | Best for | Properties |
|
|
60
|
+
|--------|----------|------------|
|
|
61
|
+
| **PCA** | General use | Linear, orthogonal components, preserves maximum variance. Components can mix positive and negative loadings. |
|
|
62
|
+
| **NMF** | Interpretability | Non-negative components — each RGB channel corresponds to a non-negative combination of gene sets. Often more biologically intuitive. |
|
|
63
|
+
| **ICA** | Independent signals | Maximizes statistical independence between components. Useful when gene programs are expected to be independent. |
|
|
64
|
+
|
|
65
|
+
!!! tip
|
|
66
|
+
Start with **PCA** for exploration. Switch to **NMF** if you want components that are
|
|
67
|
+
easier to interpret biologically (since NMF coefficients are always non-negative).
|
|
68
|
+
Use **ICA** when you suspect the gene programs represent statistically independent signals.
|
|
69
|
+
|
|
70
|
+
## Step 4 — Plot Embedding
|
|
71
|
+
|
|
72
|
+
Scatter plot of embedding coordinates (UMAP, PCA, etc.) colored by the RGB values,
|
|
73
|
+
with an integrated color-space legend.
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
# Basic usage
|
|
77
|
+
msp.plot_embedding(
|
|
78
|
+
adata, rgb,
|
|
79
|
+
basis="umap",
|
|
80
|
+
method="pca",
|
|
81
|
+
gene_set_names=["qNSCs", "aNSCs", "TAP", "NB"],
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# With customization
|
|
85
|
+
ax = msp.plot_embedding(
|
|
86
|
+
adata, rgb,
|
|
87
|
+
basis="umap",
|
|
88
|
+
method="pca",
|
|
89
|
+
gene_set_names=["qNSCs", "aNSCs", "TAP", "NB"],
|
|
90
|
+
legend=True, # show color legend (default)
|
|
91
|
+
legend_style="inset", # "inset" or "side"
|
|
92
|
+
legend_loc="lower right", # legend position
|
|
93
|
+
point_size=3,
|
|
94
|
+
alpha=0.8,
|
|
95
|
+
figsize=(6, 6),
|
|
96
|
+
title="SVZ lineage",
|
|
97
|
+
show=False, # return axes instead of displaying
|
|
98
|
+
)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Step 4b — Interactive Plot (requires Plotly)
|
|
102
|
+
|
|
103
|
+
WebGL-accelerated scatter plot with hover info showing gene set scores, RGB channel
|
|
104
|
+
values, and custom metadata.
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
msp.plot_embedding_interactive(
|
|
108
|
+
adata, rgb,
|
|
109
|
+
basis="umap",
|
|
110
|
+
scores=scores,
|
|
111
|
+
method="nmf",
|
|
112
|
+
gene_set_names=["qNSCs", "aNSCs", "TAP", "NB"],
|
|
113
|
+
hover_columns=["n_counts", "cell_type"],
|
|
114
|
+
legend=True,
|
|
115
|
+
legend_loc="lower right",
|
|
116
|
+
point_size=2,
|
|
117
|
+
width=600,
|
|
118
|
+
height=500,
|
|
119
|
+
)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
!!! note
|
|
123
|
+
Interactive plots require the `plotly` extra: `pip install 'multiscoresplot[interactive]'`
|
|
124
|
+
|
|
125
|
+
## Step 5 — Standalone Legend
|
|
126
|
+
|
|
127
|
+
Render the color-space legend independently on any matplotlib axes.
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
import matplotlib.pyplot as plt
|
|
131
|
+
|
|
132
|
+
fig, ax = plt.subplots()
|
|
133
|
+
|
|
134
|
+
# Direct mode (2-set square or 3-set triangle)
|
|
135
|
+
msp.render_legend(ax, "direct", gene_set_names=["A", "B", "C"])
|
|
136
|
+
|
|
137
|
+
# Reduction mode (RGB triangle with component labels)
|
|
138
|
+
msp.render_legend(ax, "pca")
|
|
139
|
+
msp.render_legend(ax, "nmf", component_labels=["NMF1", "NMF2", "NMF3"])
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Blend vs. Reduce — When to Use Which
|
|
143
|
+
|
|
144
|
+
| | `blend_to_rgb` | `reduce_to_rgb` |
|
|
145
|
+
|---|---|---|
|
|
146
|
+
| **Gene sets** | 2–3 only | 2 or more |
|
|
147
|
+
| **Color mapping** | Direct: each gene set has its own color | Learned: RGB channels are linear combinations of scores |
|
|
148
|
+
| **Interpretability** | Immediate — colors correspond directly to gene sets | Requires the legend to interpret RGB channels |
|
|
149
|
+
| **Best for** | Focused comparisons of 2–3 programs | Exploratory analysis of many programs simultaneously |
|