Interactive exploration of single-cell embeddings with directional analysis
Project description
scSketch project
scSketch is an interactive exploration tool of single-cell embeddings (UMAP, tSNE, etc.) for Python notebooks. It is based on the jupyter-scatter widget by Fritz Lekschas and it reimplements the earlier SciViewer visualizer.
Directional sketch → compute directional analysis → click a gene for pathway context.
Select two groups → compute differential expression → browse results.
Usage
Quick Start
The easiest way to try scSketch is with the built-in demo (no installation required):
uvx scsketch demo
This single command will automatically install scSketch and all dependencies, then launch the demo notebook.
Alternatively, if you've cloned the repository, you can run the demo notebook directly with juv:
git clone https://github.com/colabobio/scsketch.git
cd scsketch
uvx juv run demo.ipynb
Then use in any notebook:
from scsketch import ScSketch
sketch = ScSketch(adata=...)
sketch.show()
See the demo notebook for more details
Use scSketch in your own notebook
scSketch requires Python 3.10 or later. Before installing, make sure your environment meets this requirement:
python --version # should print Python 3.10.x or higher
If you are using conda and need to create or upgrade an environment:
# Create a new environment with the right Python version
conda create -n my-env python=3.10
conda activate my-env
Then install scSketch into the environment backing your Jupyter kernel:
pip install scsketch
Optional: Numba-accelerated kernels ([fast] extra)
Differential expression computations can be significantly accelerated by Numba. Numba is an optional dependency — scSketch works without it, but automatically uses it when available. To install with Numba:
pip install "scsketch[fast]"
Note: If you install scSketch into a conda environment, make sure you also have JupyterLab installed in that same environment so the kernel picks up the right packages:
pip install jupyterlab jupyter lab
Then in a notebook:
import scanpy as sc
from scsketch import ScSketch
adata = sc.read_h5ad("my_data.h5ad")
# scSketch currently reads coordinates from `adata.obsm["X_umap"]`.
# If you have a different embedding (e.g. tSNE), you can copy it into `X_umap`:
# adata.obsm["X_umap"] = adata.obsm["X_tsne"]
sketch = ScSketch(
adata=adata,
metadata_cols=["louvain"], # optional: columns in `adata.obs` for coloring
color_by_default="louvain", # optional: which metadata to color by initially
)
# If this isn't the last line in the cell, use: `from IPython.display import display; display(sketch.show())`
sketch.show()
Directional Search: keep brush selections roughly linear
Directional Search reduces your selection to a 1D “along-the-sketch” axis by projecting cells onto a single direction vector. If your brush selection is very curved, loops back, or spans multiple branches/blobs, that 1D projection can mix multiple directions of variation and produce hard-to-interpret results.
Practical tips:
- Sketch along one clear gradient at a time (a selection closer to a straight line works best).
- If the trajectory bends, split it into multiple shorter selections and compare results.
Gene IDs vs gene symbols
scSketch currently uses adata.var_names as the gene identifier for display/search. If your AnnData uses Ensembl IDs (e.g. ENSG...) in var_names, you will see Ensembl IDs in the UI.
If you have gene symbols in a column like adata.var["gene_symbols"], you can create a visualization-only copy that displays symbols:
adata_view = adata.copy()
adata_view.var["ensembl_id"] = adata_view.var_names
adata_view.var_names = adata_view.var["gene_symbols"].astype(str)
adata_view.var_names_make_unique()
sketch = ScSketch(adata=adata_view, metadata_cols=["louvain"], color_by_default="louvain")
sketch.show()
Using scSketch with uv / uvx
uv is a fast Python package manager. If you are already using it, here are the recommended ways to integrate scSketch.
Add to an existing uv project:
uv add scsketch # base install
uv add "scsketch[fast]" # with Numba-accelerated kernels (recommended)
uv run jupyter lab
Standalone notebook with juv:
juv runs notebooks in isolated environments defined by inline metadata — no pyproject.toml needed.
# Add scsketch to an existing notebook (writes inline dependency metadata)
uvx juv add my_notebook.ipynb "scsketch[fast]"
# Launch it in an auto-provisioned environment
uvx juv run my_notebook.ipynb
The notebook becomes fully self-contained and reproducible: anyone with juv can run it without any prior setup.
Try the built-in demo without installing anything:
uvx scsketch demo
This uses uvx to run scSketch ephemerally — nothing is permanently installed in your environment.
Running the original notebook with juv
To run the original inline notebook, first install juv and then call:
juv run demo.ipynb
Development
This project uses uv for development and dependency management.
Setup
-
Clone the repository:
git clone https://github.com/colabobio/scsketch.git cd scsketch
-
Sync environment (installs dependencies):
uv sync
Development Workflow
You can run commands inside the project's environment using uv run.
-
Launch Jupyter Lab for testing:
uv run jupyter lab
Open
debug.ipynbto test changes. -
Hot-reloading JS/CSS: The
debug.ipynbnotebook is pre-configured withANYWIDGET_HMR=1. Any changes you save to files insrc/scsketch/static/will legally update the widget in your browser without reloading the page. -
Linting (Ruff):
uv run ruff check .
-
Testing: Run the unit test suite with
pytest:uv run pytest tests/
Optional: Manual Activation
If you prefer to activate the environment in your shell:
source .venv/bin/activate
# Now you can use `jupyter`, `python`, `pip` directly
jupyter lab
Or with editable installs:
python -m venv .venv
source .venv/bin/activate
python -m pip install -e ".[dev,fast]"
jupyter lab demo.ipynb
Debugging with VS Code
To debug the Python side of your widgets step-by-step:
-
Debugging Jupyter Notebooks:
- Open
debug.ipynbin VS Code. - Click the "Select Kernel" button at the top right and select your project environment (e.g.,
.venvor the one created byuv). - You can set breakpoints directly in the notebook cells or in the python files (
src/scsketch/widgets/*.py). - To debug code in external files (like the widgets), use the "Debug Cell" option (often found in the dropdown menu next to the run button of a cell).
- Open
-
Attaching to a running kernel: If you prefer using
jupyter labin your browser but want to debug Python code in VS Code:- Run
jupyter lab(e.g.,uv run jupyter lab). - Add this code to a cell at the beginning of your notebook:
import debugpy debugpy.listen(5678) print("Waiting for debugger attach...") debugpy.wait_for_client() print("Debugger attached")
- In VS Code, go to the Run and Debug view (Ctrl+Shift+D).
- Select "Python: Attach to Local Process" from the dropdown and click the Play button.
- VS Code will attach to your running kernel, and you can now use breakpoints in your local Python files.
- Run
Debugging Frontend (JavaScript)
Since the widgets run in the web browser (or VS Code's webview), you need to use browser developer tools to debug the JavaScript code (src/scsketch/static/*.js).
- Run the widget: Open
debug.ipynband run the cell that displays the widget. - Open Developer Tools:
- In Browser (Jupyter Lab): Right-click anywhere on the page > Inspect.
- In VS Code: Open the command palette (
Cmd+Shift+P) and run "Developer: Open Webview Developer Tools".
- Find your source:
- Go to the Sources tab in the developer tools.
- Use
Cmd+P(Mac) orCtrl+P(Windows/Linux) to search for your file (e.g.,correlation_table.js). - Note: Because of how modules are loaded, the file path might look like
localhost:xyz/.../correlation_table.js.
- Set Breakpoints: Click on the line number in the JS file to set a breakpoint.
- Trigger the code: Interact with the widget in the notebook. The debugger will pause on your breakpoint, allowing you to inspect variables and step through the code.
Publish a New Version
To bump the version use one of the following commands:
uvx bump-my-version bump minor(e.g., v0.1.0 → v0.2.0)uvx bump-my-version bump patch(e.g., v0.1.0 → v0.1.1)uvx bump-my-version bump major(e.g., v0.1.0 → v1.0.0)
Afterward do git push --follow-tags. Github actions will handle the rest.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file scsketch-0.2.1.tar.gz.
File metadata
- Download URL: scsketch-0.2.1.tar.gz
- Upload date:
- Size: 42.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
98e448223a61dc9c6b8acc82c3497563895e2401ca042d10ae2e140e058ae800
|
|
| MD5 |
95e6f870b12f54a92f41c904c10d8632
|
|
| BLAKE2b-256 |
63060c5ba8c9b195eb1e5762250f3349cf3ee9a308678c67967d64e9bde14a2f
|
Provenance
The following attestation bundles were made for scsketch-0.2.1.tar.gz:
Publisher:
publish.yml on colabobio/scsketch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
scsketch-0.2.1.tar.gz -
Subject digest:
98e448223a61dc9c6b8acc82c3497563895e2401ca042d10ae2e140e058ae800 - Sigstore transparency entry: 1329471677
- Sigstore integration time:
-
Permalink:
colabobio/scsketch@c9ed4605f621c3f9078ce1b93a2355d9bd7069c4 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/colabobio
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c9ed4605f621c3f9078ce1b93a2355d9bd7069c4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file scsketch-0.2.1-py3-none-any.whl.
File metadata
- Download URL: scsketch-0.2.1-py3-none-any.whl
- Upload date:
- Size: 52.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b02940c67071eee92585b376b066515461b204e25d0a685ec59171ab2c1c424d
|
|
| MD5 |
6381bff18b5d8c23b5ce5457f66e819d
|
|
| BLAKE2b-256 |
ba49be14bc92f06d0b70de4602667b7dc84bb779b40283cf3bf3ec616e287b82
|
Provenance
The following attestation bundles were made for scsketch-0.2.1-py3-none-any.whl:
Publisher:
publish.yml on colabobio/scsketch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
scsketch-0.2.1-py3-none-any.whl -
Subject digest:
b02940c67071eee92585b376b066515461b204e25d0a685ec59171ab2c1c424d - Sigstore transparency entry: 1329471743
- Sigstore integration time:
-
Permalink:
colabobio/scsketch@c9ed4605f621c3f9078ce1b93a2355d9bd7069c4 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/colabobio
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c9ed4605f621c3f9078ce1b93a2355d9bd7069c4 -
Trigger Event:
push
-
Statement type: