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.1.8.tar.gz (19.7 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.1.8-py3-none-any.whl (18.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: histomap-0.1.8.tar.gz
  • Upload date:
  • Size: 19.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.4.2 CPython/3.10.9 Darwin/24.4.0

File hashes

Hashes for histomap-0.1.8.tar.gz
Algorithm Hash digest
SHA256 90e5872670773496cc01c21ed87c6e8a29d735d144cba57b340e0a54abcc19a4
MD5 a60bc5adaafce3cce858056333a06c13
BLAKE2b-256 f42c123d4509f55c417a72854cbd87dfa1c25bfa921fbc97edd5a3709c7b0161

See more details on using hashes here.

File details

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

File metadata

  • Download URL: histomap-0.1.8-py3-none-any.whl
  • Upload date:
  • Size: 18.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.4.2 CPython/3.10.9 Darwin/24.4.0

File hashes

Hashes for histomap-0.1.8-py3-none-any.whl
Algorithm Hash digest
SHA256 2ac73d4f83ee9d38be5de68230301e318af8ad3b319b65f4827011e02969592f
MD5 bc5dec67b7a73401730be4817aabb5d5
BLAKE2b-256 e717f123febd0f2614cb0926ed34ba502568fa32c8251f3127a0f3d6cbfa2c68

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