exprmat 0.1.11__tar.gz → 0.1.13__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.11 → exprmat-0.1.13}/PKG-INFO +1 -1
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/__init__.py +1 -1
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/finders.py +4 -1
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/mapping-name.pkl +0 -0
- exprmat-0.1.13/exprmat/descriptive/tcr.py +108 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/plotting/expression.py +20 -1
- exprmat-0.1.13/exprmat/plotting/sankey.py +184 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/reader/experiment.py +283 -46
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/reader/matcher.py +28 -62
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/reduction/plot.py +29 -21
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat.egg-info/PKG-INFO +1 -1
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat.egg-info/SOURCES.txt +3 -1
- {exprmat-0.1.11 → exprmat-0.1.13}/setup.py +1 -1
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/ansi.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/clustering/__init__.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/clustering/leiden.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/clustering/rogue.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/clustering/spectral.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/clustering/utils.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/cnv/__init__.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/cnv/cnvscore.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/cnv/infercnv.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/configuration.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/__init__.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/delim.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/geneset.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/gff.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/entrez.tsv.gz +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/genesets/all.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/genesets/bp.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/genesets/cancer-modules.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/genesets/cancer-neighborhoods.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/genesets/cancer.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/genesets/cc.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/genesets/chemical-perturb.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/genesets/hallmark.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/genesets/human-phenotype-ontology.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/genesets/immune-perturb.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/genesets/kegg.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/genesets/mf.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/genesets/microrna.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/genesets/oncogenic.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/genesets/pathways.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/genesets/positional.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/genesets/single-cell.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/genesets/transcript-factors.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/genesets/vaccine.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/genome.tsv.gz +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/lr/baccin2019 +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/lr/cellcall +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/lr/cellchatdb +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/lr/cellinker +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/lr/cellphonedb +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/lr/celltalkdb +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/lr/connectomedb2020 +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/lr/consensus +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/lr/embrace +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/lr/guide2pharma +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/lr/hpmr +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/lr/icellnet +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/lr/italk +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/lr/kirouac2010 +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/lr/lrdb +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/lr/ramilowski2015 +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/mapping-ensembl.pkl +0 -0
- /exprmat-0.1.11/exprmat/data/hsa/orthologs/aca.gz → /exprmat-0.1.13/exprmat/data/hsa/orthologs/aca.tsv.gz +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/orthologs/bta.tsv.gz +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/orthologs/cel.tsv.gz +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/orthologs/clu.tsv.gz +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/orthologs/dme.tsv.gz +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/orthologs/dre.tsv.gz +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/orthologs/eca.tsv.gz +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/orthologs/fca.tsv.gz +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/orthologs/gga.tsv.gz +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/orthologs/mdo.tsv.gz +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/orthologs/mmu.tsv.gz +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/orthologs/mmul.gz +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/orthologs/oan.tsv.gz +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/orthologs/ptr.tsv.gz +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/orthologs/rno.tsv.gz +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/orthologs/sce.tsv.gz +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/orthologs/spo.tsv.gz +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/orthologs/ssc.tsv.gz +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/orthologs/xla.tsv.gz +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/hsa/taxa +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/lr.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/mmu/entrez.tsv.gz +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/mmu/genesets/all.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/mmu/genesets/azimuth.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/mmu/genesets/biocarta.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/mmu/genesets/bp.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/mmu/genesets/cc.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/mmu/genesets/chemical-perturb.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/mmu/genesets/hallmark.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/mmu/genesets/kegg.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/mmu/genesets/m2.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/mmu/genesets/markers.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/mmu/genesets/mf.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/mmu/genesets/microrna.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/mmu/genesets/mpt.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/mmu/genesets/positional.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/mmu/genesets/reactome.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/mmu/genesets/transcript-factors.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/mmu/genesets/wikipathway.gmt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/mmu/genome.tsv.gz +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/mmu/lr/consensus +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/mmu/mapping-ensembl.pkl +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/mmu/mapping-name.pkl +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/mmu/taxa +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/private.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/data/ranges.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/descriptive/__init__.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/descriptive/aggregate.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/descriptive/de.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/descriptive/gse.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/descriptive/kde.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/descriptive/summary.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/lr/__init__.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/lr/aggregate.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/lr/method.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/lr/methods/__init__.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/lr/methods/cellchat.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/lr/methods/cellphonedb.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/lr/methods/connectome.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/lr/methods/geomean.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/lr/methods/logfc.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/lr/methods/natmi.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/lr/methods/rank_aggregate.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/lr/methods/scseqcomm.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/lr/methods/singlecellsignalr.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/lr/pipeline.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/lr/preprocess.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/lr/resources.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/lr/utils.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/plotting/__init__.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/plotting/cnv.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/plotting/de.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/plotting/gse.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/plotting/lr.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/plotting/palettes.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/plotting/summary.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/preprocessing/__init__.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/preprocessing/doublets/__init__.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/preprocessing/doublets/composite.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/preprocessing/doublets/scrublet.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/preprocessing/filter.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/preprocessing/integrate.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/preprocessing/linear.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/preprocessing/normal.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/preprocessing/plot.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/preprocessing/qc.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/preprocessing/sctransform/__init__.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/preprocessing/sctransform/estimate.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/preprocessing/sctransform/ksmooth.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/preprocessing/sctransform/residual.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/preprocessing/sctransform/transform.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/preprocessing/sparse.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/preprocessing/uniform.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/reader/__init__.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/reader/metadata.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/reduction/__init__.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/reduction/forceatlas.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/reduction/mde.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/reduction/nn.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/reduction/pca.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/reduction/pumap.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/reduction/tsne.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/reduction/umap.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat/utils.py +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat.egg-info/dependency_links.txt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat.egg-info/not-zip-safe +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat.egg-info/requires.txt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/exprmat.egg-info/top_level.txt +0 -0
- {exprmat-0.1.11 → exprmat-0.1.13}/setup.cfg +0 -0
|
@@ -142,7 +142,10 @@ def update_mapper(taxa, name, ens):
|
|
|
142
142
|
if (name not in genome[taxa]['mapper.name'].keys()):
|
|
143
143
|
if (ens in genome[taxa]['mapper.ensembl'].keys()):
|
|
144
144
|
genome[taxa]['mapper.name'][name] = genome[taxa]['mapper.ensembl'][ens]
|
|
145
|
-
else:
|
|
145
|
+
else:
|
|
146
|
+
# info(f'{ens} -> {name} pair could not be established.')
|
|
147
|
+
# this info log is too noisy.
|
|
148
|
+
pass
|
|
146
149
|
|
|
147
150
|
else:
|
|
148
151
|
if (ens not in genome[taxa]['mapper.ensembl'].keys()):
|
|
Binary file
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
|
|
2
|
+
import numpy as np
|
|
3
|
+
from exprmat.ansi import error, warning
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# expansion index for cluster.
|
|
7
|
+
# maximal value if the cluster is `dominant` for a single clonotype e.g. mait cells.
|
|
8
|
+
|
|
9
|
+
def clone_cluster_matrix(adata, clonotype = 'clone.id', cluster = 'leiden'):
|
|
10
|
+
|
|
11
|
+
clono_ids = adata.obs[clonotype].value_counts().index.tolist()
|
|
12
|
+
clust_ids = adata.obs[cluster].value_counts().index.tolist()
|
|
13
|
+
clono_col = adata.obs[clonotype]
|
|
14
|
+
clust_col = adata.obs[cluster]
|
|
15
|
+
mat = np.ndarray(shape = (len(clono_ids), len(clust_ids)), dtype = np.float32)
|
|
16
|
+
|
|
17
|
+
for j, cs in enumerate(clust_ids):
|
|
18
|
+
specific_cluster = clono_col[clust_col == cs].copy()
|
|
19
|
+
clono_stat = specific_cluster.value_counts()
|
|
20
|
+
|
|
21
|
+
for i, cl in enumerate(clono_ids):
|
|
22
|
+
if cl in clono_stat.index: mat[i, j] = clono_stat[cl]
|
|
23
|
+
else: mat[i, j] = 0
|
|
24
|
+
|
|
25
|
+
return mat, clono_ids, clust_ids
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def expansion(adata, clonotype = 'clone.id', cluster = 'leiden', key = 'tcr.cluster.expansion'):
|
|
29
|
+
|
|
30
|
+
mat, clono_ids, clust_ids = clone_cluster_matrix(adata, clonotype = clonotype, cluster = cluster)
|
|
31
|
+
adata.obs[key] = 0
|
|
32
|
+
|
|
33
|
+
for j, cs in enumerate(clust_ids):
|
|
34
|
+
props = mat[:, j] / np.sum(mat[:, j])
|
|
35
|
+
props = props[np.nonzero(mat[:, j])]
|
|
36
|
+
|
|
37
|
+
if np.sum(mat[:, j]) < 5:
|
|
38
|
+
adata.obs.loc[adata.obs[cluster] == cs, key] = 0
|
|
39
|
+
else:
|
|
40
|
+
shannon_e = - np.sum(props * np.log2(props))
|
|
41
|
+
adata.obs.loc[adata.obs[cluster] == cs, key] = 1 - (shannon_e / np.log2(len(props)))
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def plasticity(adata, clonotype = 'clone.id', cluster = 'leiden', key = 'tcr.cluster.plasticity'):
|
|
45
|
+
|
|
46
|
+
mat, clono_ids, clust_ids = clone_cluster_matrix(adata, clonotype = clonotype, cluster = cluster)
|
|
47
|
+
adata.obs[key] = 0
|
|
48
|
+
|
|
49
|
+
for j, cs in enumerate(clust_ids):
|
|
50
|
+
# select all clones that present in this cluster
|
|
51
|
+
submat = mat[mat[:, j] > 0, :]
|
|
52
|
+
submat = (submat.T / submat.sum(axis = 1)).T # row normalize
|
|
53
|
+
overall = submat.sum(axis = 0)
|
|
54
|
+
overall = overall / overall.sum()
|
|
55
|
+
overall = overall[np.nonzero(overall)]
|
|
56
|
+
# completely deterministic, 0. completely random, 1.
|
|
57
|
+
|
|
58
|
+
if np.sum(mat[:, j]) < 5:
|
|
59
|
+
adata.obs.loc[adata.obs[cluster] == cs, key] = 0
|
|
60
|
+
else:
|
|
61
|
+
shannon_e = - np.sum(overall * np.log2(overall))
|
|
62
|
+
adata.obs.loc[adata.obs[cluster] == cs, key] = shannon_e
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def pairwise_transition(
|
|
66
|
+
adata, base, clonotype = 'clone.id', cluster = 'leiden',
|
|
67
|
+
key = 'tcr.cluster.ptrans'
|
|
68
|
+
):
|
|
69
|
+
|
|
70
|
+
mat, clono_ids, clust_ids = clone_cluster_matrix(adata, clonotype = clonotype, cluster = cluster)
|
|
71
|
+
adata.obs[key] = 0
|
|
72
|
+
baseid = clust_ids.index(base)
|
|
73
|
+
|
|
74
|
+
for j, cs in enumerate(clust_ids):
|
|
75
|
+
if j == baseid: continue
|
|
76
|
+
|
|
77
|
+
# select all clones that present in this cluster
|
|
78
|
+
submat = mat[mat[:, j] + mat[:, baseid] > 0, :]
|
|
79
|
+
submat = submat[:, [baseid, j]]
|
|
80
|
+
either_zero = (submat[:, 0] == 0) | (submat[:, 1] == 0)
|
|
81
|
+
weights = submat[:, 0] + submat[:, 1]
|
|
82
|
+
weights = weights / weights.sum()
|
|
83
|
+
submat = (submat.T / submat.sum(axis = 1)).T # row normalize
|
|
84
|
+
|
|
85
|
+
shannon_e = -(submat[:, 0] * np.log2(submat[:, 0]) + submat[:, 1] * np.log2(submat[:, 1]))
|
|
86
|
+
shannon_e[either_zero] = 0
|
|
87
|
+
adata.obs.loc[adata.obs[cluster] == cs, key] = np.sum(shannon_e * weights)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
# per clone statistics
|
|
91
|
+
|
|
92
|
+
def transition(adata, clonotype = 'clone.id', cluster = 'leiden', key = 'tcr.clone.trans'):
|
|
93
|
+
|
|
94
|
+
mat, clono_ids, clust_ids = clone_cluster_matrix(adata, clonotype = clonotype, cluster = cluster)
|
|
95
|
+
adata.obs[key] = 0
|
|
96
|
+
|
|
97
|
+
for i, cl in enumerate(clono_ids):
|
|
98
|
+
props = mat[i, :] / np.sum(mat[i, :])
|
|
99
|
+
props = props[np.nonzero(mat[i, :])]
|
|
100
|
+
shannon_e = - np.sum(props * np.log2(props))
|
|
101
|
+
adata.obs.loc[adata.obs[clonotype] == cl, key] = shannon_e
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def migration(adata, clonotype = 'clone.id', cluster = 'tissue', key = 'tcr.clone.migr'):
|
|
107
|
+
# completely the same.
|
|
108
|
+
transition(adata, clonotype = clonotype, cluster = cluster, key = key)
|
|
@@ -129,4 +129,23 @@ def compare_scatter(
|
|
|
129
129
|
plt.text(x = x, y = y, s = name, fontsize = 9, color = 'black')
|
|
130
130
|
|
|
131
131
|
if ax is None: return fig
|
|
132
|
-
else: return axes.figure
|
|
132
|
+
else: return axes.figure
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def matrix(
|
|
136
|
+
adata, layer = 'X', obs_names = None, var_names = None,
|
|
137
|
+
figsize = (3, 3), ax = None, **kwargs
|
|
138
|
+
):
|
|
139
|
+
mat = choose_layer(adata, layer = layer)
|
|
140
|
+
|
|
141
|
+
if ax is None: fig, ax = plt.subplots(figsize = figsize)
|
|
142
|
+
else: fig = ax.figure
|
|
143
|
+
|
|
144
|
+
ax.imshow(mat, **kwargs)
|
|
145
|
+
|
|
146
|
+
obs = adata.obs_names.tolist() if obs_names is None else adata.obs[obs_names].tolist()
|
|
147
|
+
var = adata.var_names.tolist() if var_names is None else adata.obs[var_names].tolist()
|
|
148
|
+
ax.set_xticks(range(len(var)), labels = var, rotation = 90, ha = "right", va = 'center', rotation_mode = "anchor")
|
|
149
|
+
ax.set_yticks(range(len(obs)), labels = obs)
|
|
150
|
+
|
|
151
|
+
return fig
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
|
|
2
|
+
from collections import defaultdict
|
|
3
|
+
import pandas as pd
|
|
4
|
+
import numpy as np
|
|
5
|
+
import matplotlib.pyplot as plt
|
|
6
|
+
import seaborn as sns
|
|
7
|
+
|
|
8
|
+
from exprmat.ansi import error
|
|
9
|
+
from exprmat.plotting.palettes import linear_palette, all_palettes
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def check_data_matches_labels(labels, data, side):
|
|
13
|
+
if len(labels > 0):
|
|
14
|
+
if isinstance(data, list):
|
|
15
|
+
data = set(data)
|
|
16
|
+
if isinstance(data, pd.Series):
|
|
17
|
+
data = set(data.unique().tolist())
|
|
18
|
+
if isinstance(labels, list):
|
|
19
|
+
labels = set(labels)
|
|
20
|
+
if labels != data:
|
|
21
|
+
if len(labels) <= 20: msg = "(labels: " + ",".join(labels) + ") "
|
|
22
|
+
if len(data) < 20: msg += "(data: " + ",".join(data) + ')'
|
|
23
|
+
error('{0} labels and data do not match. {1}'.format(side, msg))
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def sankey(
|
|
27
|
+
left, right, left_weights = None, right_weights = None,
|
|
28
|
+
colors = None, left_labels = None, right_labels = None,
|
|
29
|
+
aspect = 4, right_colors = False, cmap = 'Turbo',
|
|
30
|
+
fontsize = 9, figsize = (4, 4), ax = None
|
|
31
|
+
):
|
|
32
|
+
|
|
33
|
+
if left_weights is None: left_weights = []
|
|
34
|
+
if right_weights is None: right_weights = []
|
|
35
|
+
if left_labels is None: left_labels = []
|
|
36
|
+
if right_labels is None: right_labels = []
|
|
37
|
+
|
|
38
|
+
if len(left_weights) == 0: left_weights = np.ones(len(left))
|
|
39
|
+
if len(right_weights) == 0: right_weights = left_weights
|
|
40
|
+
|
|
41
|
+
if ax is None: fig, ax = plt.subplots(figsize = figsize)
|
|
42
|
+
else: fig = ax.figure
|
|
43
|
+
|
|
44
|
+
# create Dataframe
|
|
45
|
+
if isinstance(left, pd.Series): left = left.reset_index(drop = True)
|
|
46
|
+
if isinstance(right, pd.Series): right = right.reset_index(drop = True)
|
|
47
|
+
df = pd.DataFrame({
|
|
48
|
+
'left': left,
|
|
49
|
+
'right': right,
|
|
50
|
+
'left_weights': left_weights,
|
|
51
|
+
'right_weights': right_weights
|
|
52
|
+
}, index = range(len(left)))
|
|
53
|
+
|
|
54
|
+
if len(df[(df.left.isnull()) | (df.right.isnull())]):
|
|
55
|
+
error('sankey graph does not support null values.')
|
|
56
|
+
|
|
57
|
+
# identify all labels that appear 'left' or 'right'
|
|
58
|
+
all_labels = pd.Series(np.r_[
|
|
59
|
+
df.left.unique(),
|
|
60
|
+
df.right.unique()
|
|
61
|
+
]).unique()
|
|
62
|
+
|
|
63
|
+
if len(left_labels) == 0: left_labels = pd.Series(df.left.unique()).unique()
|
|
64
|
+
else: check_data_matches_labels(left_labels, df['left'], 'left')
|
|
65
|
+
|
|
66
|
+
if len(right_labels) == 0: right_labels = pd.Series(df.right.unique()).unique()
|
|
67
|
+
else: check_data_matches_labels(left_labels, df['right'], 'right')
|
|
68
|
+
|
|
69
|
+
# if no colorDict given, make one
|
|
70
|
+
if colors is None:
|
|
71
|
+
colors = {}
|
|
72
|
+
pal = linear_palette(all_palettes[cmap][
|
|
73
|
+
list(all_palettes[cmap].keys())[-1]
|
|
74
|
+
], len(all_labels))
|
|
75
|
+
for i, label in enumerate(all_labels):
|
|
76
|
+
colors[label] = pal[i]
|
|
77
|
+
|
|
78
|
+
else:
|
|
79
|
+
missing = [label for label in all_labels if label not in colors.keys()]
|
|
80
|
+
if missing: error('you should give each label a color.')
|
|
81
|
+
|
|
82
|
+
# determine widths of individual strips
|
|
83
|
+
ns_l = defaultdict()
|
|
84
|
+
ns_r = defaultdict()
|
|
85
|
+
for llabel in left_labels:
|
|
86
|
+
leftDict = {}
|
|
87
|
+
rightDict = {}
|
|
88
|
+
for rlabel in right_labels:
|
|
89
|
+
leftDict[rlabel] = df[(df.left == llabel) & (df.right == rlabel)].left_weights.sum()
|
|
90
|
+
rightDict[rlabel] = df[(df.left == llabel) & (df.right == rlabel)].right_weights.sum()
|
|
91
|
+
|
|
92
|
+
ns_l[llabel] = leftDict
|
|
93
|
+
ns_r[llabel] = rightDict
|
|
94
|
+
|
|
95
|
+
# Determine positions of left label patches and total widths
|
|
96
|
+
lw = defaultdict()
|
|
97
|
+
for i, llabel in enumerate(left_labels):
|
|
98
|
+
myd = {}
|
|
99
|
+
myd['left'] = df[df.left == llabel].left_weights.sum()
|
|
100
|
+
if i == 0:
|
|
101
|
+
myd['bottom'] = 0
|
|
102
|
+
myd['top'] = myd['left']
|
|
103
|
+
else:
|
|
104
|
+
myd['bottom'] = lw[left_labels[i - 1]]['top'] + 0.02 * df.left_weights.sum()
|
|
105
|
+
myd['top'] = myd['bottom'] + myd['left']
|
|
106
|
+
topedge = myd['top']
|
|
107
|
+
lw[llabel] = myd
|
|
108
|
+
|
|
109
|
+
# Determine positions of right label patches and total widths
|
|
110
|
+
rw = defaultdict()
|
|
111
|
+
for i, rlabel in enumerate(right_labels):
|
|
112
|
+
myd = {}
|
|
113
|
+
myd['right'] = df[df.right == rlabel].right_weights.sum()
|
|
114
|
+
if i == 0:
|
|
115
|
+
myd['bottom'] = 0
|
|
116
|
+
myd['top'] = myd['right']
|
|
117
|
+
else:
|
|
118
|
+
myd['bottom'] = rw[right_labels[i - 1]]['top'] + 0.02 * df.right_weights.sum()
|
|
119
|
+
myd['top'] = myd['bottom'] + myd['right']
|
|
120
|
+
topedge = myd['top']
|
|
121
|
+
rw[rlabel] = myd
|
|
122
|
+
|
|
123
|
+
# Total vertical extent of diagram
|
|
124
|
+
xmax = topedge / aspect
|
|
125
|
+
|
|
126
|
+
# Draw vertical bars on left and right of each label's section & print label
|
|
127
|
+
for llabel in left_labels:
|
|
128
|
+
|
|
129
|
+
plt.fill_between(
|
|
130
|
+
[- 0.02 * xmax, 0],
|
|
131
|
+
2 * [lw[llabel]['bottom']],
|
|
132
|
+
2 * [lw[llabel]['bottom'] + lw[llabel]['left']],
|
|
133
|
+
color = colors[llabel],
|
|
134
|
+
alpha = 0.99
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
if lw[llabel]['top'] - lw[llabel]['bottom'] >= fontsize:
|
|
138
|
+
plt.text(
|
|
139
|
+
- 0.05 * xmax, lw[llabel]['bottom'] + 0.5 * lw[llabel]['left'], llabel,
|
|
140
|
+
{'ha': 'right', 'va': 'center'},
|
|
141
|
+
fontsize = fontsize
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
for rlabel in right_labels:
|
|
145
|
+
|
|
146
|
+
plt.fill_between(
|
|
147
|
+
[xmax, 1.02 * xmax], 2 * [rw[rlabel]['bottom']],
|
|
148
|
+
2 * [rw[rlabel]['bottom'] + rw[rlabel]['right']],
|
|
149
|
+
color = colors[rlabel],
|
|
150
|
+
alpha = 0.99
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
if rw[rlabel]['top'] - rw[rlabel]['bottom'] >= fontsize:
|
|
154
|
+
plt.text(
|
|
155
|
+
1.05 * xmax,
|
|
156
|
+
rw[rlabel]['bottom'] + 0.5 * rw[rlabel]['right'], rlabel,
|
|
157
|
+
{'ha': 'left', 'va': 'center'},
|
|
158
|
+
fontsize = fontsize
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
# strips
|
|
162
|
+
for llabel in left_labels:
|
|
163
|
+
for rlabel in right_labels:
|
|
164
|
+
lab_color = llabel
|
|
165
|
+
if right_colors:
|
|
166
|
+
lab_color = rlabel
|
|
167
|
+
if len(df[(df.left == llabel) & (df.right == rlabel)]) > 0:
|
|
168
|
+
|
|
169
|
+
ys_d = np.array(50 * [lw[llabel]['bottom']] + 50 * [rw[rlabel]['bottom']])
|
|
170
|
+
ys_d = np.convolve(ys_d, 0.05 * np.ones(20), mode='valid')
|
|
171
|
+
ys_d = np.convolve(ys_d, 0.05 * np.ones(20), mode='valid')
|
|
172
|
+
ys_u = np.array(50 * [lw[llabel]['bottom'] + ns_l[llabel][rlabel]] + 50 * [rw[rlabel]['bottom'] + ns_r[llabel][rlabel]])
|
|
173
|
+
ys_u = np.convolve(ys_u, 0.05 * np.ones(20), mode='valid')
|
|
174
|
+
ys_u = np.convolve(ys_u, 0.05 * np.ones(20), mode='valid')
|
|
175
|
+
|
|
176
|
+
lw[llabel]['bottom'] += ns_l[llabel][rlabel]
|
|
177
|
+
rw[rlabel]['bottom'] += ns_r[llabel][rlabel]
|
|
178
|
+
plt.fill_between(
|
|
179
|
+
np.linspace(0, xmax, len(ys_d)), ys_d, ys_u, alpha = 0.65,
|
|
180
|
+
color = colors[lab_color]
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
ax.axis('off')
|
|
184
|
+
return fig
|