Skip to main content

StripeSankey


StripeSankey fits a mixed membership model at several k (a sweep) and draws all of it as one figure. Every ribbon entering or leaving a node sums to exactly that node, and a ribbon's thickness is a number of samples you can read off.

The pipeline supports LDA and NMF, and takes three tables: a count matrix, a per-feature annotation (like taxa in microbiome) and per-sample metadata.

table index columns
counts sample id feature id
feature_annotation feature id annotation levels
metadata sample id sample variables

The pipeline also lets users bring their own sweep, computed elsewhere (see Fit your customized models).

From a count table to the StripeSankey: one model per k, a chance-corrected consensus across k, and the figure coloured by it

pip install stripesankey

Fit models with StripeSankey

1 — prepare

prepare checks that the three tables line up (matching sample and feature ids, usable counts), collapses the counts to one annotation level if you give one, and writes the result to base/intermediate/ for sweep to read.

import stripesankey as ss
base = 'LOCAL FOLDER PATH TO SAVE CACHE'
# fit LDA/NMF models via StripeSankey, example of microbiome count table
ss.prepare(base, counts, feature_annotation, metadata, level="genus")

level is any column of feature_annotation. For instance, in microbiome or ecology, you may want to group your count table at genus level.

2 — sweep

One fit per k, each saved to disk as it finishes.

ss.sweep(base, k_range=range(2, 11), implementation="nmf", random_state=42)

Implementations include:

Algorithm implementation source lib API
LDA Variational Bayes gensim lda_gensim
LDA Markov Chain Monte Carlo MALLET lda_mallet
NMF generalized KL loss, initialised with nndsvdar scikit-learn nmf

lda_mallet takes one more argument, mallet: the path to MALLET's bin/mallet launcher. MALLET is a Java program and is not bundled with StripeSankey, so download it yourself and make sure Java is availble.

ss.sweep(base, k_range=range(2, 11), implementation="lda_mallet",
         mallet="/path/to/Mallet", random_state=42)

Expect lda_mallet to be much slower than lda_gensim and nmf, for two reasons:

  1. MALLET fits LDA by Markov chain Monte Carlo (collapsed Gibbs sampling)
  2. Convergence has to be watched.

After fitting, results are saved in the base folder with the structure below:

base/
├── intermediate/                       # written by prepare
│   ├── features.csv                    
│   ├── feature_annotation.csv
│   ├── manifest.json
│   └── mallet/corpus.txt               # the count table as MALLET's input
└── results/                            # written by sweep
    ├── W/W_{k}.csv                     # one file per k
    ├── H/H_{k}.csv                     # one file per k
    ├── diagnostics/topic_diff_{k}.csv  # LDA (gensim) only
    ├── diagnostics/ll_{k}.csv          # LDA (MALLET) only
    ├── consensus.json                  # consensus cluster of each sample
    ├── run_info.json                   # k list, implementation, convergence per k
    └── metrics.csv
shape on disk
W sample × LC results/W/W_{k}.csv
H LC × feature results/H/H_{k}.csv

Fit your customized models

Bring your own model via python

Define a function that takes k and a seed and returns an unfitted model, then pass it as implementation. sweep fits it at every k and saves W, H and the consensus, as it does for the built-in implementations:

from sklearn.decomposition import NMF

def my_nmf(k, seed):
    return NMF(n_components=k, beta_loss="kullback-leibler", solver="mu",
               init="nndsvdar", max_iter=3000, random_state=seed)

ss.sweep(base, k_range=range(2, 11), implementation=my_nmf, random_state=42)

The model needs scikit-learn's interface: fit_transform(X) returns W (sample × LC) and components_ holds H (LC × feature).

Bring your own sweep via other programming languages

If your model runs in another language, such as R, or in a well-established tool like ADMIXTURE, run the sweep there and save each W as base/results/W/W_{k}.csv: the sample id in the first column, then one column per LC, rows summing to 1, and the same samples in the same order at every k. Then run sweep without k_range:

ss.sweep(base)

example/population does this with pong's precomputed ADMIXTURE results for the 1000 Genomes (K = 2…8).

Plotting

Both figures read the sweep from base, wherever it was fitted.

stripesankey — coloured by consensus cluster

fig = ss.stripesankey(base, metadata_df=metadata, hover_field=["group"])

stripesankey on the 1000 Genomes example, K=2…8

An interactive version is available in example/population/viz/stripesankey_K2-8.html.

Click a band, a ribbon or a cluster chip to trace those samples across every k. Click a K = label to focus that column — it restacks by the first hover_field. Read the selection back from fig.selected_samples.

metasankey — the same figure, cut by metadata

fig = ss.metasankey(base, metadata_df=metadata, hover_field=["group"])

metasankey by region on the 1000 Genomes example, K=2…8

An interactive version is available in example/population/viz/metasankey_K2-8.html.

Identical layout, one thing changed: a node is sliced into a metadata field's categories instead of into clusters.

affinity heatmap — the matrix the clusters came from

Q = ss.consensus_affinity(ss.load_W(base))                                         # the affinity matrix
fig, order, labels = ss.affinity_heatmap(Q, above=metadata, annotations=["group"])  # the plot

Consensus affinity Q for the 1000 Genomes example, ordered by consensus cluster, with cluster and region strips

Q is the signed, chance-corrected co-membership: positive means two samples share components more than chance, negative less. Samples are ordered by consensus cluster by default.

Hard labels

For an ensemble of hard labels instead of soft assignments — k-means at several k, or different algorithms at one k:

fig = ss.hardstripe(labels_df, colorby="consensus", metadata_df=metadata)

Citation

License

MIT

Metadata

Release files for StripeSankey 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for StripeSankey 0.4.0
File Size Uploaded Provenance
stripesankey-0.4.0.tar.gz 2.2 MB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for StripeSankey 0.4.0
File Interpreter ABI Platform
stripesankey-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 2.4 MB

Release files / stripesankey-0.4.0.tar.gz

Download URL stripesankey-0.4.0.tar.gz
Size 2.2 MB
Tags Source
SHA-256 checksum
How to use checksums
7c076d2e0eb226eee0cb116a7edd85d8e1b64a7c0d0a1e6bbcf0bf2fae561c28
BLAKE2b-256 checksum
How to use checksums
d7707c4b7bca850f50f655275df8d11f2a2c15c8efa9ecd7d53369ebdad42fe9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.4

Release files / stripesankey-0.4.0-py3-none-any.whl

Download URL stripesankey-0.4.0-py3-none-any.whl
Size 181.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
45a7ac2706a11b9499119fc1ffdecf929f745469e4cde6fa9baf9c2f529d009e
BLAKE2b-256 checksum
How to use checksums
a7ce95e9fccbd3cf278f4937e85bca56b2cecc3677aaca59b868048dca36411e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.4

Security for StripeSankey 0.4.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page