histomap
Napari dock widget to overlay tile polygons and table annotations from SpatialData onto an H&E image, and to interactively select cells in a 2D embedding (e.g., UMAP in AnnData.obsm) and visualize the selected regions on the H&E.
- Overlay mode: color polygons on the H&E by an
AnnData.obscolumn (categorical or numeric) fromSpatialData.tables[<name>]. - UMAP-lasso mode: open a 2D embedding from
AnnData.obsm(e.g.,X_umap), lasso points, and preview the corresponding tile polygons on the H&E; optionally save the selection back toobs.
Installation
# Recommended: use a fresh environment
conda create --name histomap python=3.11 -y
conda activate histomap
# If published on PyPI:
pip install histomap
# If installing from source in this repo:
# pip install -e .
Runtime dependencies (installed automatically if from PyPI)
- napari, PyQt5, magicgui
- geopandas, shapely
- anndata, matplotlib, spatialdata
- (Optional, for robust SVS reading)
openslide-python,napari-openslide
Windows notes
- If
geopandas/shapelywheels fail, upgrade pip (pip install -U pip) and try again.- For OpenSlide, install the prebuilt binaries or use
conda install -c conda-forge openslide openslide-pythonin the same environment.
Optional GPU acceleration (RAPIDS/cuML + CuPy)
The histomap.umap function auto-detects GPU and uses RAPIDS (cuML + CuPy) when available; otherwise it falls back to umap-learn on CPU. You do not need RAPIDS for CPU-only usage.
- macOS: RAPIDS/CUDA is not supported; use CPU (
umap-learn). - Linux with NVIDIA GPU: install RAPIDS packages into the same environment (versions must match your CUDA/driver).
Example using conda:
# Create a GPU environment (adjust Python/CUDA/RAPIDS versions to your system)
conda create --name histomap-gpu python=3.11 -y
conda activate histomap-gpu
# Install RAPIDS UMAP dependencies (channels may vary depending on versions)
conda install -c rapidsai -c conda-forge -c nvidia cuml cupy
# Then install histomap (CPU deps via pip) into the same env
pip install histomap # or: pip install -e .
Verification:
python - <<'PY'
import cupy
print('CUDA devices:', cupy.cuda.runtime.getDeviceCount())
PY
If RAPIDS is present and a CUDA device is available, histomap.umap(...) will automatically use the GPU; otherwise it will run on CPU.
Quick start
import histomap as hm
Method 1 — Use a SpatialData object
import spatialdata as sd
import histomap as hm
sda = sd.read_zarr("/path/to/spatialdata.zarr")
# Preferred: pass the H&E path explicitly (best on Windows)
viewer = hm.histomap(
sda,
imagePath="/path/to/HE_image.svs", # alias: imagePath="/path/to/HE_image.svs"
# mpp=0.263049, # µm/px (optional; if tiles are in microns, scale=1/mpp is auto-applied)
)
# If you omit imagePath, histomap will try to parse a path from str(sda).
# If no path is found, you’ll see a dialog asking you to pass imagePath explicitly.
Typical workflow in the UI
- Click Open WSI in Viewer (if not already opened).
- Choose a Table (from
sda.tables), Data axis (obsorobsm), and a column/key. -
- For
obs: click Render Overlay to color polygons on the H&E. - For
obsm(e.g.,X_umap): click Open UMAP + Lasso, lasso points, and inspect the green Lasso preview on the H&E.
- For
- Optionally enter a Layer name and obs column, then click Save selection to write labels into
AnnData.obsand add a persistent overlay layer.
Method 2 — Use with lazyslide/wsidata
import lazyslide as zs
from wsidata import open_wsi
import histomap as hm
wsi = open_wsi("/path/to/HE_image.svs")
# Assuming tiling & feature extraction are already done, e.g.:
# zs.pp.tile_tissues(wsi, tile_px=256, mpp=0.5)
# zs.tl.feature_extraction(wsi, model='chief')
# Launch viewer and overlay tiles/annotations stored in wsi.tables / wsi.shapes
viewer = hm.histomap(wsi)
Parameters (entry point)
viewer = hm.histomap(
sda_or_wsi, # SpatialData or compatible WSIData
*,
imagePath=None, # str | Path | None; preferred image to open (alias: imagePath)
mpp=None, # float | None; µm/px. If provided and no explicit scale, applies scale=(1/mpp, 1/mpp)
global_to_pixel_scale=None, # (sx, sy) override for polygon transform
global_to_pixel_translate=None, # (tx, ty) override
theme="dark",
canvas_bg="white",
)
Precedence
- If
global_to_pixel_scaleis provided, it overridesmpp. - If
imagePathis provided, it overrides any path parsed fromSpatialData. - If neither
imagePathnor a parsable path exists, histomap shows a dialog explaining how to passimagePath.
Data assumptions
sda.shapes["tiles"]is aGeoDataFramewith polygons; its index contains tile IDs.sda.tables[<name>]is anAnnDatawhereobs_namesmatch the tile IDs (string-matched; dtype mismatches are handled).- For UMAP-lasso,
AnnData.obsm[<key>]contains an(n_cells, 2+)embedding (e.g.,X_umap).
Tips & alignment
- Tiles already in pixels? Don’t pass
mpp. Use Calibrate (fit tiles) if needed. - Tiles in microns? Pass
mpp=<µm/px>and click Auto-align (use MPP) (or rely on the automatic scale if you didn’t override withglobal_to_pixel_scale). - The overlay layers inherit the image layer’s affine, so they remain aligned across pyramid levels.
Saving lasso selections (what gets written)
When you click Save selection:
- The chosen
obscolumn is created/normalized as plain Python strings (dtype=object) with no missing values. - Only selected rows receive the provided label (string). Non-selected rows remain unchanged (empty string by default).
- A persistent overlay layer is added with the saved selection (the transient Lasso preview is removed).
Why object strings?
Writing pandas’ nullable string dtype (dtype="string") to Zarr requires opting in (anndata.settings.allow_write_nullable_strings=True). Using plain object strings avoids that requirement and is maximally portable.
Troubleshooting
❗️“boolean value of NA is ambiguous” during wsi.write() / SpatialData.write()
You likely have pd.NA or mixed types in AnnData.obs. Ensure no NA in string-like columns and that they are object strings.
❗️“allow_write_nullable_strings is False”
Either set:
import anndata as ad
ad.settings.allow_write_nullable_strings = True
or convert to object strings.
❗️Cannot overwrite/move files on Windows after closing the viewer
Clear layers before saving: viewer.layers.clear() and run garbage collection.
❗️No H&E appears and you see “H&E Image Missing”
Pass the image explicitly:
viewer = hm.histomap(sda, imagePath="/absolute/path/to/HnE.svs")
FAQ
Q: Do I need openslide?
A: Only if you’re opening .svs/WSI formats through Napari.
Q: Can I use a custom image and MPP without modifying the dock UI?
A: Yes—pass imagePath=... and mpp=... to hm.histomap(...).
Metadata
Release files for histomap 0.2.9
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| histomap-0.2.9.tar.gz | 61.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| histomap-0.2.9-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 128.4 kB
Release files / histomap-0.2.9.tar.gz
| Download URL | histomap-0.2.9.tar.gz |
|---|---|
| Size | 61.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2f4bb2eba4e9d00a500a5491cf787f3d8362cd2dde37d5f9324634a34b90b1a4
|
|
BLAKE2b-256 checksum How to use checksums |
0fb84bab4382ad3117a8aec7bc3605ccbc8aa1dc1a698693bfeda04a0555d407
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.1.4 CPython/3.11.13 Windows/10
|
Release files / histomap-0.2.9-py3-none-any.whl
| Download URL | histomap-0.2.9-py3-none-any.whl |
|---|---|
| Size | 66.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
df937dbd7ced4aa537080a74ecd8c9e9b54ebd72624d9f85de99dade034ca2bc
|
|
BLAKE2b-256 checksum How to use checksums |
4bd0895e9320819f33257792a32852448949c6f3d33fcc4d9ab32226c3376d35
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.1.4 CPython/3.11.13 Windows/10
|