exprmat 0.1.41__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.
Files changed (226) hide show
  1. {exprmat-0.1.41 → exprmat-0.1.43}/PKG-INFO +3 -1
  2. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/__init__.py +12 -7
  3. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/ansi.py +16 -6
  4. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/cnv/infercnv.py +3 -3
  5. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/descriptive/tcr.py +0 -2
  6. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/cnmf.py +4 -0
  7. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/cnv.py +2 -2
  8. exprmat-0.1.43/exprmat/plotting/milestone.py +118 -0
  9. exprmat-0.1.43/exprmat/plotting/trajectory.py +345 -0
  10. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/preprocessing/linear.py +10 -2
  11. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/preprocessing/plot.py +4 -3
  12. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/preprocessing/qc.py +4 -4
  13. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/reader/experiment.py +165 -55
  14. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/reader/matcher.py +4 -4
  15. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/reader/static.py +166 -11
  16. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/reduction/__init__.py +23 -1
  17. exprmat-0.1.43/exprmat/reduction/diffmap.py +73 -0
  18. exprmat-0.1.43/exprmat/reduction/forceatlas.py +273 -0
  19. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/reduction/plot.py +18 -6
  20. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/reduction/scvi.py +30 -3
  21. exprmat-0.1.43/exprmat/reduction/umap.py +194 -0
  22. exprmat-0.1.43/exprmat/trajectory/elpi.py +703 -0
  23. exprmat-0.1.43/exprmat/trajectory/pseudotime.py +332 -0
  24. exprmat-0.1.43/exprmat/trajectory/root.py +175 -0
  25. exprmat-0.1.43/exprmat/transfer/__init__.py +0 -0
  26. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/transfer/atlas.py +78 -0
  27. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/utils.py +55 -1
  28. exprmat-0.1.43/license +0 -0
  29. {exprmat-0.1.41 → exprmat-0.1.43}/pyproject.toml +3 -1
  30. exprmat-0.1.41/exprmat/reader/__init__.py +0 -2
  31. exprmat-0.1.41/exprmat/reduction/forceatlas.py +0 -41
  32. exprmat-0.1.41/exprmat/reduction/umap.py +0 -55
  33. {exprmat-0.1.41 → exprmat-0.1.43}/Cargo.lock +0 -0
  34. {exprmat-0.1.41 → exprmat-0.1.43}/Cargo.toml +0 -0
  35. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/clustering/__init__.py +0 -0
  36. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/clustering/cnmf.py +0 -0
  37. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/clustering/dbscan.py +0 -0
  38. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/clustering/kmeans.py +0 -0
  39. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/clustering/leiden.py +0 -0
  40. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/clustering/nmf.py +0 -0
  41. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/clustering/rogue.py +0 -0
  42. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/clustering/seriation.py +0 -0
  43. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/clustering/spectral.py +0 -0
  44. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/clustering/utils.py +0 -0
  45. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/cnv/__init__.py +0 -0
  46. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/cnv/cnvscore.py +0 -0
  47. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/configuration.py +0 -0
  48. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/data/__init__.py +0 -0
  49. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/data/cistarget.py +0 -0
  50. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/data/cre.py +0 -0
  51. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/data/finders.py +0 -0
  52. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/data/geneset.py +0 -0
  53. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/data/io.py +0 -0
  54. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/data/lr.py +0 -0
  55. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/data/presets.py +0 -0
  56. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/data/signature.py +0 -0
  57. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/data/tf.py +0 -0
  58. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/descriptive/__init__.py +0 -0
  59. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/descriptive/aggregate.py +0 -0
  60. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/descriptive/atac.py +0 -0
  61. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/descriptive/aucell.py +0 -0
  62. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/descriptive/de.py +0 -0
  63. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/descriptive/gse.py +0 -0
  64. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/descriptive/kde.py +0 -0
  65. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/descriptive/recovery.py +0 -0
  66. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/descriptive/summary.py +0 -0
  67. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/deseq/dataset.py +0 -0
  68. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/deseq/gridsearch.py +0 -0
  69. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/deseq/inference.py +0 -0
  70. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/deseq/preprocessing.py +0 -0
  71. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/deseq/stats.py +0 -0
  72. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/deseq/utils.py +0 -0
  73. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/dynamics/__init__.py +0 -0
  74. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/dynamics/generank.py +0 -0
  75. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/dynamics/linreg.py +0 -0
  76. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/dynamics/moments.py +0 -0
  77. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/dynamics/optimization.py +0 -0
  78. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/dynamics/parallel.py +0 -0
  79. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/dynamics/preprocess.py +0 -0
  80. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/dynamics/pseudotime.py +0 -0
  81. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/dynamics/transition.py +0 -0
  82. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/dynamics/utils.py +0 -0
  83. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/dynamics/velocity.py +0 -0
  84. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/grn/__init__.py +0 -0
  85. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/grn/infergrn.py +0 -0
  86. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/grn/modules.py +0 -0
  87. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/grn/prune.py +0 -0
  88. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/grn/regressors.py +0 -0
  89. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/grn/utils.py +0 -0
  90. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/image/__init__.py +0 -0
  91. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/image/align.py +0 -0
  92. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/lr/__init__.py +0 -0
  93. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/lr/aggregate.py +0 -0
  94. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/lr/method.py +0 -0
  95. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/lr/methods/__init__.py +0 -0
  96. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/lr/methods/cellchat.py +0 -0
  97. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/lr/methods/cellphonedb.py +0 -0
  98. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/lr/methods/connectome.py +0 -0
  99. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/lr/methods/geomean.py +0 -0
  100. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/lr/methods/logfc.py +0 -0
  101. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/lr/methods/natmi.py +0 -0
  102. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/lr/methods/rank_aggregate.py +0 -0
  103. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/lr/methods/scseqcomm.py +0 -0
  104. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/lr/methods/singlecellsignalr.py +0 -0
  105. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/lr/pipeline.py +0 -0
  106. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/lr/preprocess.py +0 -0
  107. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/lr/resources.py +0 -0
  108. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/lr/utils.py +0 -0
  109. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/peaks/__init__.py +0 -0
  110. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/peaks/callpeak.py +0 -0
  111. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/peaks/common.py +0 -0
  112. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/peaks/coverage.py +0 -0
  113. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/peaks/footprint.py +0 -0
  114. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/peaks/idr/__init__.py +0 -0
  115. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/peaks/idr/constants.py +0 -0
  116. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/peaks/idr/idr.py +0 -0
  117. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/peaks/idr/invcdf.pyx +0 -0
  118. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/peaks/idr/optimization.py +0 -0
  119. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/peaks/idr/utils.py +0 -0
  120. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/peaks/linkage.py +0 -0
  121. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/peaks/motif.py +0 -0
  122. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/peaks/sequence.py +0 -0
  123. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/__init__.py +0 -0
  124. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/atac.py +0 -0
  125. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/A.pk +0 -0
  126. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/B.pk +0 -0
  127. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/C.pk +0 -0
  128. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/D.pk +0 -0
  129. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/E.pk +0 -0
  130. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/F.pk +0 -0
  131. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/G.pk +0 -0
  132. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/H.pk +0 -0
  133. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/I.pk +0 -0
  134. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/J.pk +0 -0
  135. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/K.pk +0 -0
  136. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/L.pk +0 -0
  137. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/M.pk +0 -0
  138. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/N.pk +0 -0
  139. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/O.pk +0 -0
  140. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/P.pk +0 -0
  141. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/Q.pk +0 -0
  142. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/R.pk +0 -0
  143. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/S.pk +0 -0
  144. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/T.pk +0 -0
  145. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/U.pk +0 -0
  146. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/V.pk +0 -0
  147. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/W.pk +0 -0
  148. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/X.pk +0 -0
  149. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/Y.pk +0 -0
  150. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/data/Z.pk +0 -0
  151. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/de.py +0 -0
  152. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/expression.py +0 -0
  153. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/gse.py +0 -0
  154. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/lr.py +0 -0
  155. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/palettes.py +0 -0
  156. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/sankey.py +0 -0
  157. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/sequence.py +0 -0
  158. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/summary.py +0 -0
  159. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/track.py +0 -0
  160. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/utils.py +0 -0
  161. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/plotting/velocity.py +0 -0
  162. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/preprocessing/__init__.py +0 -0
  163. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/preprocessing/doublets/__init__.py +0 -0
  164. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/preprocessing/doublets/composite.py +0 -0
  165. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/preprocessing/doublets/scrublet.py +0 -0
  166. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/preprocessing/emptydrops.py +0 -0
  167. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/preprocessing/filter.py +0 -0
  168. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/preprocessing/impute/__init__.py +0 -0
  169. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/preprocessing/impute/magic.py +0 -0
  170. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/preprocessing/integrate.py +0 -0
  171. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/preprocessing/normal.py +0 -0
  172. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/preprocessing/sctransform/__init__.py +0 -0
  173. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/preprocessing/sctransform/estimate.py +0 -0
  174. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/preprocessing/sctransform/ksmooth.py +0 -0
  175. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/preprocessing/sctransform/residual.py +0 -0
  176. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/preprocessing/sctransform/transform.py +0 -0
  177. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/preprocessing/sparse.py +0 -0
  178. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/preprocessing/uniform.py +0 -0
  179. {exprmat-0.1.41/exprmat/transfer → exprmat-0.1.43/exprmat/reader}/__init__.py +0 -0
  180. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/reader/conversions.py +0 -0
  181. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/reader/metadata.py +0 -0
  182. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/reader/spatial.py +0 -0
  183. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/reader/updater.py +0 -0
  184. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/reduction/mde.py +0 -0
  185. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/reduction/nn.py +0 -0
  186. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/reduction/outliers.py +0 -0
  187. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/reduction/pca.py +0 -0
  188. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/reduction/spectral.py +0 -0
  189. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/reduction/tsne.py +0 -0
  190. /exprmat-0.1.41/license → /exprmat-0.1.43/exprmat/trajectory/__init__.py +0 -0
  191. {exprmat-0.1.41 → exprmat-0.1.43}/exprmat/trajectory/pcurve.py +0 -0
  192. {exprmat-0.1.41 → exprmat-0.1.43}/readme.md +0 -0
  193. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2/Cargo.toml +0 -0
  194. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2/license +0 -0
  195. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2/readme +0 -0
  196. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2/src/call_peaks.rs +0 -0
  197. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2/src/embedding.rs +0 -0
  198. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2/src/export.rs +0 -0
  199. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2/src/knn.rs +0 -0
  200. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2/src/lib.rs +0 -0
  201. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2/src/motif.rs +0 -0
  202. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2/src/network.rs +0 -0
  203. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2/src/preprocessing.rs +0 -0
  204. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2/src/utils/anndata.rs +0 -0
  205. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2/src/utils.rs +0 -0
  206. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2-core/Cargo.toml +0 -0
  207. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2-core/src/embedding.rs +0 -0
  208. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2-core/src/export.rs +0 -0
  209. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2-core/src/feature_count/counter.rs +0 -0
  210. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2-core/src/feature_count/data_iter.rs +0 -0
  211. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2-core/src/feature_count/matrix.rs +0 -0
  212. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2-core/src/feature_count/mod.rs +0 -0
  213. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2-core/src/genome.rs +0 -0
  214. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2-core/src/lib.rs +0 -0
  215. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2-core/src/motif.rs +0 -0
  216. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2-core/src/network.rs +0 -0
  217. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2-core/src/preprocessing/bam/flagstat.rs +0 -0
  218. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2-core/src/preprocessing/bam/header.rs +0 -0
  219. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2-core/src/preprocessing/bam/mark_duplicates.rs +0 -0
  220. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2-core/src/preprocessing/bam.rs +0 -0
  221. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2-core/src/preprocessing/import.rs +0 -0
  222. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2-core/src/preprocessing/mod.rs +0 -0
  223. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2-core/src/preprocessing/qc.rs +0 -0
  224. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2-core/src/utils/knn.rs +0 -0
  225. {exprmat-0.1.41 → exprmat-0.1.43}/snapatac2-core/src/utils/mod.rs +0 -0
  226. {exprmat-0.1.41 → 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.41
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 db_ver
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
  ]
@@ -1,6 +1,7 @@
1
1
 
2
2
  import re
3
3
  import os
4
+ import sys
4
5
 
5
6
  from functools import partial
6
7
  from tqdm import tqdm
@@ -91,12 +92,12 @@ def common_length(string: str, limit: int) -> str:
91
92
  return x_str
92
93
 
93
94
  elif len(string) + cn_length > limit:
94
- x_str = string[-(limit - 4):]
95
+ x_str = string[-(limit - 3):]
95
96
  cn = len(re.findall(cn_re, x_str))
96
- while cn + len(x_str) > limit - 4:
97
+ while cn + len(x_str) > limit - 3:
97
98
  x_str = x_str[1:]
98
99
  cn = len(re.findall(cn_re, x_str))
99
- return '... ' + x_str
100
+ return '.. ' + x_str
100
101
 
101
102
  else: return ('{:<' + str(limit - cn_length) + '}').format(string)
102
103
 
@@ -156,13 +157,22 @@ def yellow(x): return '\033[33m' + x + '\033[0m'
156
157
  def blue(x): return '\033[34m' + x + '\033[0m'
157
158
  def purple(x): return '\033[35m' + x + '\033[0m'
158
159
  def cyan(x): return '\033[36m' + x + '\033[0m'
160
+ def annot(x): return '\033[90;3m' + x + '\033[0m'
159
161
 
160
162
 
161
163
  progress_styles = {
162
164
  'ncols': 80,
163
165
  'ascii': '-━',
164
- 'bar_format': ' {bar} {desc:20} {n:5d} / {total:<5d} ({elapsed} < {remaining})'
166
+ 'bar_format': ' {bar} {desc:20} {n:5d} / {total:<5d} ({elapsed} < {remaining})',
167
+ 'file': sys.stderr
165
168
  }
166
169
 
167
- pprog = partial(tqdm, **progress_styles)
168
- pproga = partial(tqdma, **progress_styles)
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) <= 2 else '' for x in labels]
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 = list(chr_pos_dict.keys()),
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
+ )
@@ -68,7 +68,15 @@ def normalize_total(
68
68
  if target_total is None:
69
69
  target_total = np.mean(tots_use)
70
70
 
71
- b = np.array(float(target_total) / tots_use.T)[0]
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
+
79
+ if len(b.shape) == 2: b = b[0]
72
80
  if not sp.issparse(E):
73
81
  # this will densify the matrix, causing incredibly large memory comsumption
74
82
  # when treating with an sparse matrix.
@@ -83,7 +91,7 @@ def normalize_total(
83
91
  elif sp.isspmatrix_csc(E):
84
92
  e_norm = E.copy()
85
93
  e_norm.data *= b[E.indices]
86
-
94
+
87
95
  return e_norm
88
96
 
89
97