cellestial 0.1.0__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.
- cellestial-0.1.0/PKG-INFO +37 -0
- cellestial-0.1.0/README.md +16 -0
- cellestial-0.1.0/cellestial/__init__.py +0 -0
- cellestial-0.1.0/cellestial/core/__init__.py +0 -0
- cellestial-0.1.0/cellestial/core/scatterplot.py +120 -0
- cellestial-0.1.0/cellestial/decorators/__init__.py +0 -0
- cellestial-0.1.0/cellestial/decorators/util.py +17 -0
- cellestial-0.1.0/pyproject.toml +25 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: cellestial
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary:
|
|
5
|
+
Author: Zaf4
|
|
6
|
+
Author-email: zafermolbio@gmail.com
|
|
7
|
+
Requires-Python: >=3.11,<4.0
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Requires-Dist: anndata (>=0.11.0,<0.12.0)
|
|
12
|
+
Requires-Dist: cairosvg (>=2.7.1,<3.0.0)
|
|
13
|
+
Requires-Dist: lets-plot (>=4.5.1,<5.0.0)
|
|
14
|
+
Requires-Dist: polars (>=1.13.0,<2.0.0)
|
|
15
|
+
Requires-Dist: pooch (>=1.8.2,<2.0.0)
|
|
16
|
+
Requires-Dist: pyarrow (>=18.0.0,<19.0.0)
|
|
17
|
+
Requires-Dist: pycairo (>=1.27.0,<2.0.0)
|
|
18
|
+
Requires-Dist: scanpy[leiden] (>=1.10.4,<2.0.0)
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
21
|
+
# APIS
|
|
22
|
+
|
|
23
|
+
Apis (not APIs) comes from honey bees
|
|
24
|
+
An Interactive Single-Cell Plotting Tool over a ggplot-like API.
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install apis
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Usage
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
import scplot as sp
|
|
36
|
+
```
|
|
37
|
+
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Literal
|
|
4
|
+
# Core scverse libraries
|
|
5
|
+
import polars as pl
|
|
6
|
+
|
|
7
|
+
# Data retrieval
|
|
8
|
+
import scanpy as sc
|
|
9
|
+
from lets_plot import (
|
|
10
|
+
LetsPlot,
|
|
11
|
+
aes,
|
|
12
|
+
element_blank,
|
|
13
|
+
element_line,
|
|
14
|
+
element_text,
|
|
15
|
+
geom_blank,
|
|
16
|
+
geom_jitter,
|
|
17
|
+
geom_point,
|
|
18
|
+
geom_violin,
|
|
19
|
+
gggrid,
|
|
20
|
+
ggplot,
|
|
21
|
+
ggsize,
|
|
22
|
+
ggtb,
|
|
23
|
+
guide_colorbar,
|
|
24
|
+
guides,
|
|
25
|
+
labs,
|
|
26
|
+
layer_tooltips,
|
|
27
|
+
scale_color_continuous,
|
|
28
|
+
scale_color_gradient,
|
|
29
|
+
scale_color_hue,
|
|
30
|
+
scale_color_viridis,
|
|
31
|
+
theme,
|
|
32
|
+
theme_classic,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
LetsPlot.setup_html()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def scatter(
|
|
40
|
+
data,
|
|
41
|
+
key: str = "leiden",
|
|
42
|
+
*,
|
|
43
|
+
dimensions: Literal["umap", "pca", "tsne"] = "umap",
|
|
44
|
+
size=0.8,
|
|
45
|
+
interactive: bool = False,
|
|
46
|
+
color_low: str = "#ffffff",
|
|
47
|
+
color_high: str = "#377eb8",
|
|
48
|
+
):
|
|
49
|
+
if not isinstance(data, sc.AnnData):
|
|
50
|
+
raise ValueError("data must be an AnnData object")
|
|
51
|
+
# get the coordinates of the cells in the dimension reduced space
|
|
52
|
+
frame = pl.from_numpy(
|
|
53
|
+
data.obsm[f"X_{dimensions}"], schema=[f"{dimensions}1", f"{dimensions}2"]
|
|
54
|
+
).with_columns(pl.Series("ID", data.obs_names))
|
|
55
|
+
|
|
56
|
+
# deterministic names
|
|
57
|
+
if key in ["leiden", "louvain"]: # if it is a clustering
|
|
58
|
+
frame = frame.with_columns(
|
|
59
|
+
pl.Series("ID", data.obs_names), pl.Series("Cluster", data.obs[key])
|
|
60
|
+
)
|
|
61
|
+
# cluster scatter
|
|
62
|
+
scttr = (
|
|
63
|
+
ggplot(data=frame)
|
|
64
|
+
+ geom_point(
|
|
65
|
+
aes(x=f"{dimensions}2", y=f"{dimensions}1", color="Cluster"),
|
|
66
|
+
size=size,
|
|
67
|
+
tooltips=layer_tooltips(["ID", "Cluster"]),
|
|
68
|
+
)
|
|
69
|
+
+ scale_color_hue()
|
|
70
|
+
)
|
|
71
|
+
else: # if it is a gene
|
|
72
|
+
# adata.X is a matrix , axis0 is cells, axis1 is genes
|
|
73
|
+
# find the index of the gene
|
|
74
|
+
index = data.var_names.get_indexer(
|
|
75
|
+
data.var_names[data.var_names.str.startswith(key)]
|
|
76
|
+
) # get the index of the gene
|
|
77
|
+
frame = frame.with_columns(
|
|
78
|
+
pl.Series("ID", data.obs_names),
|
|
79
|
+
pl.Series(key, data.X[:, index].flatten().astype("float64")),
|
|
80
|
+
)
|
|
81
|
+
scttr = (
|
|
82
|
+
ggplot(data=frame)
|
|
83
|
+
+ geom_point(
|
|
84
|
+
aes(x=f"{dimensions}2", y=f"{dimensions}1", color=key),
|
|
85
|
+
size=size,
|
|
86
|
+
tooltips=layer_tooltips(["ID", key]),
|
|
87
|
+
)
|
|
88
|
+
+ scale_color_continuous(low=color_low, high=color_high)
|
|
89
|
+
+ theme_classic()
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
# add common layers
|
|
93
|
+
scttr += (
|
|
94
|
+
ggsize(700, 500)
|
|
95
|
+
+ theme_classic()
|
|
96
|
+
+ theme(
|
|
97
|
+
axis_text_x=element_blank(),
|
|
98
|
+
axis_text_y=element_blank(),
|
|
99
|
+
# axis_ticks_y=element_blank(),
|
|
100
|
+
# axis_ticks_x=element_blank(),
|
|
101
|
+
text=element_text(color="#1f1f1f", family="Arial", size=12, face="bold"),
|
|
102
|
+
title=element_text(color="#1f1f1f", family="Arial"),
|
|
103
|
+
axis_title_x=element_text(
|
|
104
|
+
color="#3f3f3f",
|
|
105
|
+
family="Arial",
|
|
106
|
+
size=16,
|
|
107
|
+
),
|
|
108
|
+
axis_title_y=element_text(color="#3f3f3f", family="Arial", size=16),
|
|
109
|
+
legend_text=element_text(color="#1f1f1f", size=10, face="plain"),
|
|
110
|
+
axis_line=element_line(color="#3f3f3f", size=0.2),
|
|
111
|
+
)
|
|
112
|
+
+ labs(
|
|
113
|
+
x=f"{dimensions}2".upper(), y=f"{dimensions}1".upper()
|
|
114
|
+
) # UMAP1 and UMAP2 rather than umap1 and umap2 etc.,
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
if interactive:
|
|
118
|
+
return scttr + ggtb()
|
|
119
|
+
else:
|
|
120
|
+
return scttr
|
|
File without changes
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from lets_plot import ggtb
|
|
2
|
+
|
|
3
|
+
def interactive(func):
|
|
4
|
+
def wrapper(*args, **kwargs):
|
|
5
|
+
|
|
6
|
+
inter = kwargs.get("interactive")
|
|
7
|
+
if inter is True:
|
|
8
|
+
return func(*args, **kwargs) + ggtb()
|
|
9
|
+
elif inter is False:
|
|
10
|
+
return func(*args, **kwargs)
|
|
11
|
+
else:
|
|
12
|
+
msg = f"expected True or False for 'interactive' argument, but received {inter}"
|
|
13
|
+
raise ValueError(msg)
|
|
14
|
+
|
|
15
|
+
return wrapper
|
|
16
|
+
|
|
17
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "cellestial"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = ""
|
|
5
|
+
authors = ["Zaf4 <zafermolbio@gmail.com>"]
|
|
6
|
+
readme = "README.md"
|
|
7
|
+
|
|
8
|
+
[tool.poetry.dependencies]
|
|
9
|
+
python = "^3.11"
|
|
10
|
+
anndata = "^0.11.0"
|
|
11
|
+
cairosvg = "^2.7.1"
|
|
12
|
+
lets-plot = "^4.5.1"
|
|
13
|
+
polars = "^1.13.0"
|
|
14
|
+
pooch = "^1.8.2"
|
|
15
|
+
pyarrow = "^18.0.0"
|
|
16
|
+
pycairo = "^1.27.0"
|
|
17
|
+
scanpy = {extras = ["leiden"], version = "^1.10.4"}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
[tool.poetry.group.dev.dependencies]
|
|
21
|
+
ipykernel = "^6.29.5"
|
|
22
|
+
|
|
23
|
+
[build-system]
|
|
24
|
+
requires = ["poetry-core"]
|
|
25
|
+
build-backend = "poetry.core.masonry.api"
|