Skip to main content

visualize histology images with umap

Project description

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.obs column (categorical or numeric) from SpatialData.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 to obs.

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/shapely wheels 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-python in 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

  1. Click Open WSI in Viewer (if not already opened).
  2. Choose a Table (from sda.tables), Data axis (obs or obsm), 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.
  3. Optionally enter a Layer name and obs column, then click Save selection to write labels into AnnData.obs and 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_scale is provided, it overrides mpp.
  • If imagePath is provided, it overrides any path parsed from SpatialData.
  • If neither imagePath nor a parsable path exists, histomap shows a dialog explaining how to pass imagePath.

Data assumptions

  • sda.shapes["tiles"] is a GeoDataFrame with polygons; its index contains tile IDs.
  • sda.tables[<name>] is an AnnData where obs_names match 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 with global_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 obs column 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(...).


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

histomap-0.2.4.tar.gz (37.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

histomap-0.2.4-py3-none-any.whl (38.5 kB view details)

Uploaded Python 3

File details

Details for the file histomap-0.2.4.tar.gz.

File metadata

  • Download URL: histomap-0.2.4.tar.gz
  • Upload date:
  • Size: 37.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.4 CPython/3.11.13 Windows/10

File hashes

Hashes for histomap-0.2.4.tar.gz
Algorithm Hash digest
SHA256 c1091578698fc7a9555bdfb7f227e3ff9ea115bf01b2e03089160ae381ebf122
MD5 58e22d77d73ae1d7d201f1e80522a351
BLAKE2b-256 624a52ab015d2847a71136632382dea08882155b7a5320003414f72abff5c040

See more details on using hashes here.

File details

Details for the file histomap-0.2.4-py3-none-any.whl.

File metadata

  • Download URL: histomap-0.2.4-py3-none-any.whl
  • Upload date:
  • Size: 38.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.4 CPython/3.11.13 Windows/10

File hashes

Hashes for histomap-0.2.4-py3-none-any.whl
Algorithm Hash digest
SHA256 15b2bec133643cb1b59096c71bbef8374cd562f296768ad78ab734bc9611f8f7
MD5 fde8c3f044dc2e8b77bb787941929794
BLAKE2b-256 1524e50f63a438fa0fbc0c70cb921aed73bb0bf7e4250da741a4d67edc326b6c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page