exprmat 0.1.42__tar.gz → 0.1.43__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.
- {exprmat-0.1.42 → exprmat-0.1.43}/PKG-INFO +3 -1
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/__init__.py +12 -7
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/ansi.py +10 -2
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/cnv/infercnv.py +3 -3
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/descriptive/tcr.py +0 -2
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/cnmf.py +4 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/cnv.py +2 -2
- exprmat-0.1.43/exprmat/plotting/milestone.py +118 -0
- exprmat-0.1.43/exprmat/plotting/trajectory.py +345 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/preprocessing/linear.py +8 -2
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/preprocessing/plot.py +4 -3
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/reader/experiment.py +122 -46
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/reader/static.py +161 -11
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/reduction/__init__.py +23 -1
- exprmat-0.1.43/exprmat/reduction/forceatlas.py +273 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/reduction/plot.py +10 -4
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/reduction/scvi.py +30 -3
- exprmat-0.1.43/exprmat/reduction/umap.py +194 -0
- exprmat-0.1.43/exprmat/trajectory/elpi.py +703 -0
- exprmat-0.1.43/exprmat/trajectory/pseudotime.py +332 -0
- exprmat-0.1.43/exprmat/trajectory/root.py +175 -0
- exprmat-0.1.43/exprmat/transfer/__init__.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/transfer/atlas.py +78 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/utils.py +55 -1
- exprmat-0.1.43/license +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/pyproject.toml +3 -1
- exprmat-0.1.42/exprmat/reader/__init__.py +0 -2
- exprmat-0.1.42/exprmat/reduction/forceatlas.py +0 -41
- exprmat-0.1.42/exprmat/reduction/umap.py +0 -55
- {exprmat-0.1.42 → exprmat-0.1.43}/Cargo.lock +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/Cargo.toml +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/clustering/__init__.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/clustering/cnmf.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/clustering/dbscan.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/clustering/kmeans.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/clustering/leiden.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/clustering/nmf.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/clustering/rogue.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/clustering/seriation.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/clustering/spectral.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/clustering/utils.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/cnv/__init__.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/cnv/cnvscore.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/configuration.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/data/__init__.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/data/cistarget.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/data/cre.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/data/finders.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/data/geneset.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/data/io.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/data/lr.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/data/presets.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/data/signature.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/data/tf.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/descriptive/__init__.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/descriptive/aggregate.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/descriptive/atac.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/descriptive/aucell.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/descriptive/de.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/descriptive/gse.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/descriptive/kde.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/descriptive/recovery.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/descriptive/summary.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/deseq/dataset.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/deseq/gridsearch.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/deseq/inference.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/deseq/preprocessing.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/deseq/stats.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/deseq/utils.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/dynamics/__init__.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/dynamics/generank.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/dynamics/linreg.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/dynamics/moments.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/dynamics/optimization.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/dynamics/parallel.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/dynamics/preprocess.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/dynamics/pseudotime.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/dynamics/transition.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/dynamics/utils.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/dynamics/velocity.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/grn/__init__.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/grn/infergrn.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/grn/modules.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/grn/prune.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/grn/regressors.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/grn/utils.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/image/__init__.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/image/align.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/lr/__init__.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/lr/aggregate.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/lr/method.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/lr/methods/__init__.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/lr/methods/cellchat.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/lr/methods/cellphonedb.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/lr/methods/connectome.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/lr/methods/geomean.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/lr/methods/logfc.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/lr/methods/natmi.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/lr/methods/rank_aggregate.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/lr/methods/scseqcomm.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/lr/methods/singlecellsignalr.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/lr/pipeline.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/lr/preprocess.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/lr/resources.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/lr/utils.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/peaks/__init__.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/peaks/callpeak.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/peaks/common.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/peaks/coverage.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/peaks/footprint.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/peaks/idr/__init__.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/peaks/idr/constants.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/peaks/idr/idr.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/peaks/idr/invcdf.pyx +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/peaks/idr/optimization.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/peaks/idr/utils.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/peaks/linkage.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/peaks/motif.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/peaks/sequence.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/__init__.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/atac.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/A.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/B.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/C.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/D.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/E.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/F.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/G.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/H.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/I.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/J.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/K.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/L.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/M.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/N.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/O.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/P.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/Q.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/R.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/S.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/T.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/U.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/V.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/W.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/X.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/Y.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/data/Z.pk +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/de.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/expression.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/gse.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/lr.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/palettes.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/sankey.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/sequence.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/summary.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/track.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/utils.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/plotting/velocity.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/preprocessing/__init__.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/preprocessing/doublets/__init__.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/preprocessing/doublets/composite.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/preprocessing/doublets/scrublet.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/preprocessing/emptydrops.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/preprocessing/filter.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/preprocessing/impute/__init__.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/preprocessing/impute/magic.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/preprocessing/integrate.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/preprocessing/normal.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/preprocessing/qc.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/preprocessing/sctransform/__init__.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/preprocessing/sctransform/estimate.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/preprocessing/sctransform/ksmooth.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/preprocessing/sctransform/residual.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/preprocessing/sctransform/transform.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/preprocessing/sparse.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/preprocessing/uniform.py +0 -0
- {exprmat-0.1.42/exprmat/transfer → exprmat-0.1.43/exprmat/reader}/__init__.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/reader/conversions.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/reader/matcher.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/reader/metadata.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/reader/spatial.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/reader/updater.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/reduction/diffmap.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/reduction/mde.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/reduction/nn.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/reduction/outliers.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/reduction/pca.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/reduction/spectral.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/reduction/tsne.py +0 -0
- /exprmat-0.1.42/license → /exprmat-0.1.43/exprmat/trajectory/__init__.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/exprmat/trajectory/pcurve.py +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/readme.md +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2/Cargo.toml +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2/license +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2/readme +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2/src/call_peaks.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2/src/embedding.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2/src/export.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2/src/knn.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2/src/lib.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2/src/motif.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2/src/network.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2/src/preprocessing.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2/src/utils/anndata.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2/src/utils.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2-core/Cargo.toml +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2-core/src/embedding.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2-core/src/export.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2-core/src/feature_count/counter.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2-core/src/feature_count/data_iter.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2-core/src/feature_count/matrix.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2-core/src/feature_count/mod.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2-core/src/genome.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2-core/src/lib.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2-core/src/motif.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2-core/src/network.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2-core/src/preprocessing/bam/flagstat.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2-core/src/preprocessing/bam/header.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2-core/src/preprocessing/bam/mark_duplicates.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2-core/src/preprocessing/bam.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2-core/src/preprocessing/import.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2-core/src/preprocessing/mod.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2-core/src/preprocessing/qc.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2-core/src/utils/knn.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2-core/src/utils/mod.rs +0 -0
- {exprmat-0.1.42 → exprmat-0.1.43}/snapatac2-core/src/utils/similarity.rs +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: exprmat
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.43
|
|
4
4
|
Classifier: Programming Language :: Rust
|
|
5
5
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
6
6
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
@@ -75,6 +75,8 @@ Requires-Dist: pyfastx
|
|
|
75
75
|
Requires-Dist: genomicranges
|
|
76
76
|
Requires-Dist: rustworkx
|
|
77
77
|
Requires-Dist: xgboost
|
|
78
|
+
Requires-Dist: simpleppt
|
|
79
|
+
Requires-Dist: elpigraph-python
|
|
78
80
|
Requires-Dist: dask-expr>=2.0
|
|
79
81
|
Requires-Dist: sphinx ; extra == 'dev'
|
|
80
82
|
Requires-Dist: twine ; extra == 'dev'
|
|
@@ -108,10 +108,11 @@ for finder in default_finders:
|
|
|
108
108
|
basepath = config['data']
|
|
109
109
|
|
|
110
110
|
# core method exports
|
|
111
|
-
from exprmat.utils import setup_styles
|
|
111
|
+
from exprmat.utils import setup_styles, savefig
|
|
112
112
|
from exprmat.ansi import error, warning, info, pprog, pproga
|
|
113
113
|
from exprmat.reader.experiment import experiment, load_experiment
|
|
114
114
|
from exprmat.reader.metadata import metadata, load_metadata
|
|
115
|
+
import exprmat.reader.static as st
|
|
115
116
|
|
|
116
117
|
|
|
117
118
|
setup_styles()
|
|
@@ -127,7 +128,8 @@ def version_db():
|
|
|
127
128
|
with open(version_file, 'r') as vf:
|
|
128
129
|
db_ver = vf.read().strip()
|
|
129
130
|
|
|
130
|
-
return
|
|
131
|
+
if db_ver is None: return None
|
|
132
|
+
return tuple([int(x) for x in db_ver.split('.')])
|
|
131
133
|
|
|
132
134
|
|
|
133
135
|
# perform database integrity check.
|
|
@@ -136,9 +138,9 @@ if PERFORM_DATABASE_CHECK:
|
|
|
136
138
|
if db_ver is None:
|
|
137
139
|
warning('the database is not installed.')
|
|
138
140
|
print(DATABASE_SETUP_MESSAGE)
|
|
139
|
-
elif db_ver != importlib.metadata.version("exprmat"):
|
|
141
|
+
elif ".".join([str(x) for x in db_ver]) != importlib.metadata.version("exprmat"):
|
|
140
142
|
warning('the database version do not match the package version')
|
|
141
|
-
warning(f'db version: {db_ver} package version: {importlib.metadata.version("exprmat")}')
|
|
143
|
+
warning(f'db version: {".".join([str(x) for x in db_ver])} package version: {importlib.metadata.version("exprmat")}')
|
|
142
144
|
|
|
143
145
|
|
|
144
146
|
def cuda():
|
|
@@ -168,11 +170,11 @@ def version():
|
|
|
168
170
|
from exprmat.ansi import info, error, format_file_size
|
|
169
171
|
|
|
170
172
|
db_ver = version_db()
|
|
171
|
-
info(f'exprmat {MAJOR}.{MINOR}.{REVISION} / exprmat-db {db_ver if db_ver is not None else "(Not installed)"}')
|
|
173
|
+
info(f'exprmat {MAJOR}.{MINOR}.{REVISION} / exprmat-db {".".join([str(x) for x in db_ver]) if db_ver is not None else "(Not installed)"}')
|
|
172
174
|
info(f'os: {os.name} ({sys.platform}) platform version: {platform.release()}')
|
|
173
175
|
info(f'loaded configuration from {finder}')
|
|
174
176
|
info(f'current working directory: {os.getcwd()}')
|
|
175
|
-
info(f'current database directory: {config["data"]} ({db_ver if db_ver is not None else "(Not found)"})')
|
|
177
|
+
info(f'current database directory: {config["data"]} ({".".join([str(x) for x in db_ver]) if db_ver is not None else "(Not found)"})')
|
|
176
178
|
memory()
|
|
177
179
|
return (MAJOR, MINOR, REVISION)
|
|
178
180
|
|
|
@@ -206,5 +208,8 @@ __all__ = [
|
|
|
206
208
|
'warning',
|
|
207
209
|
'info',
|
|
208
210
|
'pprog',
|
|
209
|
-
'pproga'
|
|
211
|
+
'pproga',
|
|
212
|
+
'savefig',
|
|
213
|
+
|
|
214
|
+
'st',
|
|
210
215
|
]
|
|
@@ -157,6 +157,7 @@ def yellow(x): return '\033[33m' + x + '\033[0m'
|
|
|
157
157
|
def blue(x): return '\033[34m' + x + '\033[0m'
|
|
158
158
|
def purple(x): return '\033[35m' + x + '\033[0m'
|
|
159
159
|
def cyan(x): return '\033[36m' + x + '\033[0m'
|
|
160
|
+
def annot(x): return '\033[90;3m' + x + '\033[0m'
|
|
160
161
|
|
|
161
162
|
|
|
162
163
|
progress_styles = {
|
|
@@ -166,5 +167,12 @@ progress_styles = {
|
|
|
166
167
|
'file': sys.stderr
|
|
167
168
|
}
|
|
168
169
|
|
|
169
|
-
|
|
170
|
-
|
|
170
|
+
|
|
171
|
+
class pprog(tqdm):
|
|
172
|
+
def __init__(self, iterable = None, **kwargs):
|
|
173
|
+
super().__init__(iterable, **progress_styles, **kwargs)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class pproga(tqdma):
|
|
177
|
+
def __init__(self, iterable = None, **kwargs):
|
|
178
|
+
super().__init__(iterable, **progress_styles, **kwargs)
|
|
@@ -12,7 +12,7 @@ from anndata import AnnData
|
|
|
12
12
|
from scanpy import logging
|
|
13
13
|
from tqdm.contrib.concurrent import process_map
|
|
14
14
|
|
|
15
|
-
from exprmat.ansi import error, warning, info, pproga
|
|
15
|
+
from exprmat.ansi import error, warning, info, pproga, tqdma
|
|
16
16
|
from exprmat.utils import ensure_array
|
|
17
17
|
|
|
18
18
|
|
|
@@ -143,9 +143,9 @@ def infercnv(
|
|
|
143
143
|
itertools.repeat(dynamic_threshold),
|
|
144
144
|
itertools.repeat(calculate_gene_values),
|
|
145
145
|
tqdm_class = pproga,
|
|
146
|
-
max_workers=cpu_count() if n_jobs is None else n_jobs,
|
|
146
|
+
max_workers = cpu_count() if n_jobs is None else n_jobs,
|
|
147
147
|
),
|
|
148
|
-
strict=False,
|
|
148
|
+
strict = False,
|
|
149
149
|
)
|
|
150
150
|
|
|
151
151
|
res = scipy.sparse.vstack(chunks)
|
|
@@ -101,8 +101,6 @@ def transition(adata, clonotype = 'clone.id', cluster = 'leiden', key = 'tcr.clo
|
|
|
101
101
|
adata.obs.loc[adata.obs[clonotype] == cl, key] = shannon_e
|
|
102
102
|
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
|
|
106
104
|
def migration(adata, clonotype = 'clone.id', cluster = 'tissue', key = 'tcr.clone.migr'):
|
|
107
105
|
# completely the same.
|
|
108
106
|
transition(adata, clonotype = clonotype, cluster = cluster, key = key)
|
|
@@ -129,6 +129,10 @@ def matrix_plot(
|
|
|
129
129
|
if annotations is not None and isinstance(annotations, list):
|
|
130
130
|
ax_annot = ax.inset_axes([1.02, 0, 0.05, 1], sharey = ax)
|
|
131
131
|
annot_u = list(set(annotations))
|
|
132
|
+
# sort it
|
|
133
|
+
if all([str(x).isdigit() for x in annot_u]):
|
|
134
|
+
annot_u = sorted(annot_u, key = int)
|
|
135
|
+
else: annot_u = sorted(annot_u, key = str)
|
|
132
136
|
annot_n = [annot_u.index(x) for x in annotations]
|
|
133
137
|
|
|
134
138
|
from exprmat.plotting import palettes
|
|
@@ -60,7 +60,7 @@ def chromosome_heatmap(
|
|
|
60
60
|
|
|
61
61
|
labels = list(chr_pos_dict.keys())
|
|
62
62
|
if draw_autosome_only:
|
|
63
|
-
labels = [x if len(x) <=
|
|
63
|
+
labels = [x if len(x) <= 5 else '' for x in labels]
|
|
64
64
|
|
|
65
65
|
return_ax_dic = sc.pl.heatmap(
|
|
66
66
|
tmp_adata,
|
|
@@ -70,7 +70,7 @@ def chromosome_heatmap(
|
|
|
70
70
|
cmap = mpl(cmap),
|
|
71
71
|
show_gene_labels = False,
|
|
72
72
|
var_group_positions = var_group_positions,
|
|
73
|
-
var_group_labels =
|
|
73
|
+
var_group_labels = labels,
|
|
74
74
|
show = False,
|
|
75
75
|
** kwargs,
|
|
76
76
|
)
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
|
|
2
|
+
from typing_extensions import Literal
|
|
3
|
+
import igraph
|
|
4
|
+
import numpy as np
|
|
5
|
+
import pandas as pd
|
|
6
|
+
from typing import Union, Optional, Iterable
|
|
7
|
+
import matplotlib
|
|
8
|
+
import matplotlib.cm as cm
|
|
9
|
+
import matplotlib.colors as mcolors
|
|
10
|
+
import matplotlib.pyplot as plt
|
|
11
|
+
import scanpy as sc
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def milestones(
|
|
15
|
+
adata,
|
|
16
|
+
basis: Union[None, str] = 'umap',
|
|
17
|
+
trajectory_key = 'ppt',
|
|
18
|
+
annotate: bool = False,
|
|
19
|
+
title = None,
|
|
20
|
+
subset: Optional[Iterable] = None,
|
|
21
|
+
ax = None,
|
|
22
|
+
sort = False,
|
|
23
|
+
cmap = 'turbo',
|
|
24
|
+
**kwargs,
|
|
25
|
+
):
|
|
26
|
+
|
|
27
|
+
emb = adata.obsm[basis]
|
|
28
|
+
kwargs['sort_order'] = sort
|
|
29
|
+
|
|
30
|
+
if not sort: order = adata.obs[f'{trajectory_key}.pseudotime'].sort_values().index
|
|
31
|
+
else: order = adata.obs[f'{trajectory_key}.pseudotime'].sort_values().index
|
|
32
|
+
order = order[order.isin(subset)] if subset is not None else order
|
|
33
|
+
|
|
34
|
+
if "color" in kwargs:
|
|
35
|
+
kwargs.pop("color")
|
|
36
|
+
|
|
37
|
+
if ax is None:
|
|
38
|
+
fig = plt.figure()
|
|
39
|
+
ax = fig.add_subplot(111)
|
|
40
|
+
|
|
41
|
+
if "edgecolor" not in kwargs: kwargs["edgecolor"] = "none"
|
|
42
|
+
if "s" not in kwargs: kwargs["s"] = 120000 / adata.shape[0]
|
|
43
|
+
|
|
44
|
+
ax.scatter(
|
|
45
|
+
adata[order].obsm[basis][:, 0],
|
|
46
|
+
adata[order].obsm[basis][:, 1],
|
|
47
|
+
c = gen_milestones_gradients(adata, key = trajectory_key, palette = cmap)[order].values,
|
|
48
|
+
marker = ".",
|
|
49
|
+
rasterized = True,
|
|
50
|
+
plotnonfinite = True,
|
|
51
|
+
** kwargs,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
ax.set_yticks([])
|
|
55
|
+
ax.set_xticks([])
|
|
56
|
+
ax.autoscale_view()
|
|
57
|
+
|
|
58
|
+
if annotate:
|
|
59
|
+
|
|
60
|
+
R = adata.obsm[trajectory_key]
|
|
61
|
+
proj = (np.dot(emb.T, R) / R.sum(axis=0)).T
|
|
62
|
+
|
|
63
|
+
X = proj[list(adata.uns[f"{trajectory_key}.graph"]["milestones"].values()), :]
|
|
64
|
+
adata_m = sc.AnnData(
|
|
65
|
+
X, dtype = X.dtype,
|
|
66
|
+
obs = dict(mil = list(adata.uns[f"{trajectory_key}.graph"]["milestones"].keys())),
|
|
67
|
+
obsm = {basis: X},
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
adata_m.obs["mil"] = adata_m.obs["mil"].astype("category")
|
|
71
|
+
|
|
72
|
+
sc.pl.embedding(
|
|
73
|
+
adata_m,
|
|
74
|
+
basis,
|
|
75
|
+
color = "mil",
|
|
76
|
+
title = title,
|
|
77
|
+
legend_loc = "on data",
|
|
78
|
+
ax = ax,
|
|
79
|
+
alpha = 0,
|
|
80
|
+
legend_fontoutline = True,
|
|
81
|
+
show = False,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def gen_milestones_gradients(adata, palette = 'turbo', key = 'ppt', seg_order = None):
|
|
86
|
+
|
|
87
|
+
seg_order = adata.obs[f'{key}.segs'].unique() \
|
|
88
|
+
if seg_order is None else seg_order
|
|
89
|
+
|
|
90
|
+
if "milestones.colors" not in adata.uns or len(adata.uns["milestones.colors"]) == 1:
|
|
91
|
+
from exprmat.plotting.palettes import get_palette
|
|
92
|
+
adata.uns['milestones.colors'] = get_palette(palette, len(seg_order))
|
|
93
|
+
|
|
94
|
+
def milestones_prog(s):
|
|
95
|
+
|
|
96
|
+
cfrom = adata.obs.t[adata.obs.seg == s].idxmin()
|
|
97
|
+
cto = adata.obs.t[adata.obs.seg == s].idxmax()
|
|
98
|
+
mfrom = adata.obs.milestones[cfrom]
|
|
99
|
+
mto = adata.obs.milestones[cto]
|
|
100
|
+
mfrom_c = adata.uns["milestones_colors"][
|
|
101
|
+
np.argwhere(adata.obs.milestones.cat.categories == mfrom)[0][0]
|
|
102
|
+
]
|
|
103
|
+
mto_c = adata.uns["milestones_colors"][
|
|
104
|
+
np.argwhere(adata.obs.milestones.cat.categories == mto)[0][0]
|
|
105
|
+
]
|
|
106
|
+
|
|
107
|
+
from matplotlib.colors import LinearSegmentedColormap, to_hex
|
|
108
|
+
cm = LinearSegmentedColormap.from_list("test", [mfrom_c, mto_c], N=1000)
|
|
109
|
+
pst = (
|
|
110
|
+
adata.obs.t[adata.obs.seg == s] - adata.obs.t[adata.obs.seg == s].min()
|
|
111
|
+
) / (
|
|
112
|
+
adata.obs.t[adata.obs.seg == s].max()
|
|
113
|
+
- adata.obs.t[adata.obs.seg == s].min()
|
|
114
|
+
)
|
|
115
|
+
return pd.Series(list(map(to_hex, cm(pst))), index = pst.index)
|
|
116
|
+
|
|
117
|
+
return pd.concat(list(map(milestones_prog, seg_order)))
|
|
118
|
+
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
|
|
2
|
+
import numpy as np
|
|
3
|
+
import pandas as pd
|
|
4
|
+
import igraph
|
|
5
|
+
from anndata import AnnData
|
|
6
|
+
import matplotlib.collections
|
|
7
|
+
from typing import Union, Optional, Sequence, Tuple, List
|
|
8
|
+
import scanpy as sc
|
|
9
|
+
from cycler import Cycler
|
|
10
|
+
|
|
11
|
+
from pandas.api.types import is_categorical_dtype
|
|
12
|
+
from scanpy.plotting._utils import savefig_or_show
|
|
13
|
+
|
|
14
|
+
import matplotlib.patheffects as path_effects
|
|
15
|
+
import matplotlib.text as mtext
|
|
16
|
+
from matplotlib.cm import ScalarMappable
|
|
17
|
+
from matplotlib.colors import Normalize, hex2color, rgb2hex
|
|
18
|
+
from numba import njit
|
|
19
|
+
import math
|
|
20
|
+
|
|
21
|
+
from exprmat.plotting.milestone import milestones as milestones_plot
|
|
22
|
+
from exprmat import error, warning, info
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def graph(
|
|
26
|
+
adata: AnnData,
|
|
27
|
+
background_color = None,
|
|
28
|
+
basis: Union[None, str] = None,
|
|
29
|
+
size_nodes: float = None,
|
|
30
|
+
alpha_nodes: float = 1,
|
|
31
|
+
linewidth: float = 2,
|
|
32
|
+
alpha_seg: float = 1,
|
|
33
|
+
color_cells: Union[str, None] = None,
|
|
34
|
+
tips: bool = True,
|
|
35
|
+
forks: bool = True,
|
|
36
|
+
nodes: Optional[List] = [],
|
|
37
|
+
rasterized: bool = True,
|
|
38
|
+
ax = None,
|
|
39
|
+
trajectory_key = 'ppt',
|
|
40
|
+
embedding_dims = [0, 1],
|
|
41
|
+
contour_plot = False,
|
|
42
|
+
figsize = (3, 3),
|
|
43
|
+
** kwargs,
|
|
44
|
+
):
|
|
45
|
+
|
|
46
|
+
if f"{trajectory_key}.graph" not in adata.uns:
|
|
47
|
+
error(f'do not find trajectory key `{trajectory_key}`')
|
|
48
|
+
|
|
49
|
+
graph = adata.uns[f"{trajectory_key}.graph"]
|
|
50
|
+
emb = adata.obsm[basis]
|
|
51
|
+
emb = emb[:, embedding_dims]
|
|
52
|
+
R = adata.obsm[trajectory_key]
|
|
53
|
+
proj = (np.dot(emb.T, R) / R.sum(axis = 0)).T
|
|
54
|
+
B = graph["adjacencies"]
|
|
55
|
+
|
|
56
|
+
from exprmat.reduction.plot import embedding
|
|
57
|
+
|
|
58
|
+
if ax: embedding(
|
|
59
|
+
adata, basis = basis, ax = ax, embedding_dims = embedding_dims,
|
|
60
|
+
contour_plot = contour_plot, color = background_color, **kwargs
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
else: ax = embedding(
|
|
64
|
+
adata, basis = basis, embedding_dims = embedding_dims, figsize = figsize,
|
|
65
|
+
contour_plot = contour_plot, color = background_color, **kwargs
|
|
66
|
+
).axes[0]
|
|
67
|
+
|
|
68
|
+
al = np.array(igraph.Graph.Adjacency((B > 0).tolist(), mode = "undirected").get_edgelist())
|
|
69
|
+
segs = al.tolist()
|
|
70
|
+
vertices = proj.tolist()
|
|
71
|
+
lines = [[tuple(vertices[j]) for j in i] for i in segs]
|
|
72
|
+
lc = matplotlib.collections.LineCollection(
|
|
73
|
+
lines, colors = "k", linewidths = linewidth,
|
|
74
|
+
alpha = alpha_seg, rasterized = rasterized
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
ax.add_collection(lc)
|
|
78
|
+
ax.scatter(
|
|
79
|
+
proj[:, 0], proj[:, 1],
|
|
80
|
+
s = size_nodes, c = "k", alpha = alpha_nodes,
|
|
81
|
+
rasterized = rasterized
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
bbox = dict(facecolor = "white", alpha = 0.6, edgecolor = "white", pad = 0.1)
|
|
85
|
+
|
|
86
|
+
if tips:
|
|
87
|
+
for tip in graph["tips"]:
|
|
88
|
+
ax.annotate(
|
|
89
|
+
tip,
|
|
90
|
+
(proj[tip, 0], proj[tip, 1]),
|
|
91
|
+
ha = "center",
|
|
92
|
+
va = "center",
|
|
93
|
+
xytext = (0, 0),
|
|
94
|
+
textcoords = "offset points",
|
|
95
|
+
bbox = bbox,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
if forks:
|
|
99
|
+
for fork in graph["forks"]:
|
|
100
|
+
ax.annotate(
|
|
101
|
+
fork,
|
|
102
|
+
(proj[fork, 0], proj[fork, 1]),
|
|
103
|
+
ha = "center",
|
|
104
|
+
va = "center",
|
|
105
|
+
xytext = (0, 0),
|
|
106
|
+
textcoords = "offset points",
|
|
107
|
+
bbox = bbox,
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
if nodes:
|
|
111
|
+
for node in nodes:
|
|
112
|
+
ax.annotate(
|
|
113
|
+
node,
|
|
114
|
+
(proj[node, 0], proj[node, 1]),
|
|
115
|
+
ha = "center",
|
|
116
|
+
va = "center",
|
|
117
|
+
xytext = (0, 0),
|
|
118
|
+
textcoords = "offset points",
|
|
119
|
+
bbox = bbox,
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
return ax.figure
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def trajectory(
|
|
126
|
+
adata: AnnData,
|
|
127
|
+
basis: Union[None, str] = None,
|
|
128
|
+
color_seg = "segments",
|
|
129
|
+
background_color = None,
|
|
130
|
+
cmap_seg: str = "viridis",
|
|
131
|
+
layer_seg: Union[str, None] = "fitted",
|
|
132
|
+
perc_seg: Union[List, None] = None,
|
|
133
|
+
color_cells: Union[str, None] = None,
|
|
134
|
+
scale_path: float = 1,
|
|
135
|
+
rasterized: bool = True,
|
|
136
|
+
ax = None,
|
|
137
|
+
trajectory_key = 'ppt',
|
|
138
|
+
embedding_dims = [0, 1],
|
|
139
|
+
contour_plot = False,
|
|
140
|
+
figsize = (3, 3),
|
|
141
|
+
annotate = False,
|
|
142
|
+
annotate_fontsize = 9,
|
|
143
|
+
**kwargs,
|
|
144
|
+
):
|
|
145
|
+
|
|
146
|
+
from exprmat.reduction.plot import embedding
|
|
147
|
+
if ax: embedding(
|
|
148
|
+
adata, basis = basis, ax = ax, embedding_dims = embedding_dims, annotate = False,
|
|
149
|
+
contour_plot = contour_plot, color = background_color, **kwargs
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
else: ax = embedding(
|
|
153
|
+
adata, basis = basis, embedding_dims = embedding_dims, figsize = figsize, annotate = False,
|
|
154
|
+
contour_plot = contour_plot, color = background_color, **kwargs
|
|
155
|
+
).axes[0]
|
|
156
|
+
|
|
157
|
+
if f"{trajectory_key}.graph" not in adata.uns:
|
|
158
|
+
raise ValueError("You need to run `principle_tree_pseudotime` first before plotting.")
|
|
159
|
+
|
|
160
|
+
graph = adata.uns[f"{trajectory_key}.graph"]
|
|
161
|
+
emb = adata.obsm[f"{basis}"]
|
|
162
|
+
emb = emb[:, embedding_dims]
|
|
163
|
+
R = adata.obsm[trajectory_key]
|
|
164
|
+
|
|
165
|
+
nodes = graph["pp_info"].index
|
|
166
|
+
proj = pd.DataFrame((np.dot(emb.T, R) / R.sum(axis=0)).T, index = nodes)
|
|
167
|
+
|
|
168
|
+
B = graph["adjacencies"]
|
|
169
|
+
g = igraph.Graph.Adjacency((B > 0).tolist(), mode = "undirected")
|
|
170
|
+
g.vs[:]["name"] = [v.index for v in g.vs]
|
|
171
|
+
|
|
172
|
+
miles_ids = np.concatenate([graph["tips"], graph["forks"]])
|
|
173
|
+
|
|
174
|
+
al = np.array(g.get_edgelist())
|
|
175
|
+
edges = [g.vs[e.tolist()]["name"] for e in al]
|
|
176
|
+
lines = [[tuple(proj.loc[j]) for j in i] for i in edges]
|
|
177
|
+
miles_ids = miles_ids[np.isin(miles_ids, proj.index)]
|
|
178
|
+
|
|
179
|
+
if color_seg == "milestones":
|
|
180
|
+
from matplotlib.colors import LinearSegmentedColormap
|
|
181
|
+
|
|
182
|
+
rev_dict = dict(zip(graph["milestones"].values(), graph["milestones"].keys()))
|
|
183
|
+
miles_cat = adata.obs[f"{trajectory_key}.milestones"].cat.categories
|
|
184
|
+
mil_col = np.array(adata.uns[f"{trajectory_key}.milestones.colors"])
|
|
185
|
+
|
|
186
|
+
def get_milestones_gradients(i):
|
|
187
|
+
start = graph["pp_seg"].iloc[i, 1]
|
|
188
|
+
end = graph["pp_seg"].iloc[i, 2]
|
|
189
|
+
mil_path = graph["pp_info"].time[g.get_all_shortest_paths(start, end)[0]]
|
|
190
|
+
mil_path = (mil_path - mil_path.min()) / (mil_path.max() - mil_path.min())
|
|
191
|
+
start_col = mil_col[miles_cat == rev_dict[start]][0] if start in rev_dict.keys() else '#e0e0e0'
|
|
192
|
+
end_col = mil_col[miles_cat == rev_dict[end]][0] if end in rev_dict.keys() else '#e0e0e0'
|
|
193
|
+
|
|
194
|
+
edges_mil = pd.Series([
|
|
195
|
+
mil_path[[first, second]].mean()
|
|
196
|
+
for first, second in zip(mil_path.index, mil_path.index[1:])],
|
|
197
|
+
index = [(first, second) for first, second in zip(mil_path.index, mil_path.index[1:])]
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
cmap = LinearSegmentedColormap.from_list("mil", [start_col, end_col])
|
|
201
|
+
return pd.Series(
|
|
202
|
+
[rgb2hex(c) for c in cmap(edges_mil)], index = edges_mil.index
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
edge_colors = pd.concat(
|
|
206
|
+
[get_milestones_gradients(i) for i in range(graph["pp_seg"].shape[0])]
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
edges_tuples = [tuple(e) for e in edges]
|
|
210
|
+
edge_colors.index = [
|
|
211
|
+
e if any((np.array(edges_tuples) == e).sum(axis=1) == 2) else e[::-1]
|
|
212
|
+
for e in edge_colors.index
|
|
213
|
+
]
|
|
214
|
+
edge_colors = edge_colors[edges_tuples]
|
|
215
|
+
|
|
216
|
+
color_segs = [hex2color(c) for c in edge_colors]
|
|
217
|
+
color_mils = []
|
|
218
|
+
for m in miles_ids:
|
|
219
|
+
if m in rev_dict.keys(): color_mils.append(mil_col[miles_cat.tolist().index(rev_dict[m])])
|
|
220
|
+
else: color_mils.append('#e0e0e0')
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
elif color_seg == "segments":
|
|
224
|
+
|
|
225
|
+
seg_edges = (
|
|
226
|
+
graph["pp_info"]
|
|
227
|
+
.loc[np.array(edges).ravel(), "seg"]
|
|
228
|
+
.values.reshape(-1, 2)[:, 0]
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
seg_col = pd.Series(
|
|
232
|
+
adata.uns[f"{trajectory_key}.seg.colors"],
|
|
233
|
+
index = graph["pp_seg"].n
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
color_segs = [hex2color(seg_col.loc[s]) for s in seg_edges]
|
|
237
|
+
|
|
238
|
+
color_mils = []
|
|
239
|
+
for m in miles_ids:
|
|
240
|
+
if m in graph["milestones"].values():
|
|
241
|
+
color_mils.append(hex2color(seg_col.loc[graph["pp_info"].loc[m].seg]))
|
|
242
|
+
else: color_mils.append('#e0e0e0')
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
lc = matplotlib.collections.LineCollection(
|
|
246
|
+
lines,
|
|
247
|
+
colors = "k",
|
|
248
|
+
linewidths = 7.5 * scale_path,
|
|
249
|
+
zorder = 100,
|
|
250
|
+
path_effects = [path_effects.Stroke(capstyle = "round")],
|
|
251
|
+
rasterized = rasterized,
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
ax.add_collection(lc)
|
|
255
|
+
g = igraph.Graph.Adjacency((B > 0).tolist(), mode = "undirected")
|
|
256
|
+
seg = graph["pp_seg"].loc[:, ["from", "to"]].values.tolist()
|
|
257
|
+
bbox = dict(facecolor = "white", alpha = 0.6, edgecolor = "white", pad = 0.1)
|
|
258
|
+
|
|
259
|
+
lc = matplotlib.collections.LineCollection(
|
|
260
|
+
lines,
|
|
261
|
+
colors = color_segs,
|
|
262
|
+
linewidths = 5 * scale_path,
|
|
263
|
+
zorder = 104,
|
|
264
|
+
path_effects = [path_effects.Stroke(capstyle = "round")],
|
|
265
|
+
rasterized = rasterized,
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
# milestones
|
|
269
|
+
|
|
270
|
+
ax.scatter(
|
|
271
|
+
proj.loc[miles_ids, 0],
|
|
272
|
+
proj.loc[miles_ids, 1],
|
|
273
|
+
zorder = 103,
|
|
274
|
+
c = "k",
|
|
275
|
+
s = 200 * scale_path,
|
|
276
|
+
rasterized = False,
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
ax.add_collection(lc)
|
|
281
|
+
ax.scatter(
|
|
282
|
+
proj.loc[miles_ids, 0],
|
|
283
|
+
proj.loc[miles_ids, 1],
|
|
284
|
+
zorder = 105,
|
|
285
|
+
c = color_mils,
|
|
286
|
+
s = 140 * scale_path,
|
|
287
|
+
rasterized = rasterized,
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
if annotate:
|
|
291
|
+
|
|
292
|
+
if color_seg == 'milestones':
|
|
293
|
+
|
|
294
|
+
for x in miles_ids.tolist():
|
|
295
|
+
|
|
296
|
+
text = mtext.Text(
|
|
297
|
+
x = proj.loc[x, 0], y = proj.loc[x, 1], # fontproperties = 'bold',
|
|
298
|
+
text = str(x),
|
|
299
|
+
color = 'black', zorder = 106,
|
|
300
|
+
ha = 'center', va = 'center', size = annotate_fontsize
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
text.set_path_effects([
|
|
304
|
+
matplotlib.patheffects.Stroke(linewidth = 3, foreground = 'white'),
|
|
305
|
+
matplotlib.patheffects.Normal()
|
|
306
|
+
])
|
|
307
|
+
|
|
308
|
+
ax.add_artist(text)
|
|
309
|
+
pass
|
|
310
|
+
|
|
311
|
+
elif color_seg == 'segments':
|
|
312
|
+
|
|
313
|
+
unique_edges = list(set(seg_edges))
|
|
314
|
+
for uniseg in unique_edges:
|
|
315
|
+
line_segs = []
|
|
316
|
+
for l, seg in zip(lines, seg_edges):
|
|
317
|
+
if seg == uniseg: line_segs.append(l)
|
|
318
|
+
|
|
319
|
+
points = len(line_segs)
|
|
320
|
+
(fromx, fromy), (tox, toy) = line_segs[points // 2]
|
|
321
|
+
text = mtext.Text(
|
|
322
|
+
x = (fromx + tox) / 2, y = (fromy + toy) / 2, # fontproperties = 'bold',
|
|
323
|
+
text = str(uniseg),
|
|
324
|
+
color = 'black', zorder = 106,
|
|
325
|
+
ha = 'center', va = 'center', size = annotate_fontsize
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
text.set_path_effects([
|
|
329
|
+
matplotlib.patheffects.Stroke(linewidth = 3, foreground = 'white'),
|
|
330
|
+
matplotlib.patheffects.Normal()
|
|
331
|
+
])
|
|
332
|
+
|
|
333
|
+
ax.add_artist(text)
|
|
334
|
+
pass
|
|
335
|
+
|
|
336
|
+
return ax.figure
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
@njit()
|
|
340
|
+
def cdist_numba(coords, out):
|
|
341
|
+
for i in range(0, coords.shape[0] - 1):
|
|
342
|
+
out[i] = math.sqrt(
|
|
343
|
+
(coords[i, 0] - coords[i + 1, 0]) ** 2
|
|
344
|
+
+ (coords[i, 1] - coords[i + 1, 1]) ** 2
|
|
345
|
+
)
|
|
@@ -69,8 +69,14 @@ def normalize_total(
|
|
|
69
69
|
target_total = np.mean(tots_use)
|
|
70
70
|
|
|
71
71
|
b = np.array(float(target_total) / tots_use.T)
|
|
72
|
+
e_norm = mul_row(E, b)
|
|
73
|
+
|
|
74
|
+
return e_norm
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def mul_row(E, b):
|
|
78
|
+
|
|
72
79
|
if len(b.shape) == 2: b = b[0]
|
|
73
|
-
|
|
74
80
|
if not sp.issparse(E):
|
|
75
81
|
# this will densify the matrix, causing incredibly large memory comsumption
|
|
76
82
|
# when treating with an sparse matrix.
|
|
@@ -85,7 +91,7 @@ def normalize_total(
|
|
|
85
91
|
elif sp.isspmatrix_csc(E):
|
|
86
92
|
e_norm = E.copy()
|
|
87
93
|
e_norm.data *= b[E.indices]
|
|
88
|
-
|
|
94
|
+
|
|
89
95
|
return e_norm
|
|
90
96
|
|
|
91
97
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
|
|
2
|
+
import numpy as np
|
|
2
3
|
import matplotlib as mpl
|
|
3
4
|
import matplotlib.pyplot as plt
|
|
4
5
|
|
|
@@ -65,13 +66,13 @@ def rna_plot_gene_histogram(adata, sample_name, ax):
|
|
|
65
66
|
ax.set_title(sample_name if len(sample_name) < 20 else sample_name[:17] + ' ..')
|
|
66
67
|
|
|
67
68
|
ax.vlines(
|
|
68
|
-
x = [0, 150], ymin = 0, ymax =
|
|
69
|
+
x = [0, 150], ymin = 0, ymax = np.max(h[0]),
|
|
69
70
|
colors = 'red', linestyles = 'dotted'
|
|
70
71
|
)
|
|
71
72
|
|
|
72
73
|
ax.vlines(
|
|
73
|
-
x = [300, 600], ymin = 0, ymax =
|
|
74
|
+
x = [300, 600], ymin = 0, ymax = np.max(h[0]),
|
|
74
75
|
colors = 'black', linestyles = 'dotted'
|
|
75
76
|
)
|
|
76
77
|
|
|
77
|
-
ax.set_yscale('log')
|
|
78
|
+
# ax.set_yscale('log')
|