QuPath annotations#

goatpy can transform QuPath GeoJSON annotation exports into the registered coordinate system so they overlay correctly on the H&E canvas.

During registration#

Pass geojson_path directly to load_and_align:

sdata = gp.load_and_align(
    imzml_path="sample.imzML",
    he_path="sample.svs",
    geojson_path="annotations.geojson",
    geojson_shapes_key="annotations",         # key in sdata.shapes
    geojson_classification_key="classification",  # column in the GeoDataFrame
)

After registration#

If sdata was already built without annotations, add them afterwards:

sdata = gp.add_qupath_annotations(
    sdata,
    geojson_path="annotations.geojson",
    shapes_key="annotations",
)

This reads the affine matrix stored in sdata["maldi_adata"].uns["he_transform"] to reproduce the exact same transform used during registration.

Exporting from QuPath#

In QuPath, export annotations via:

File → Export annotations → GeoJSON

Make sure to export with “Include default excluded objects” unchecked, and leave coordinates in the default native pixel space (do not apply any scaling).

Accessing annotation labels#

The classification column is stored as a categorical in the shapes GeoDataFrame:

ann = sdata.shapes["annotations"]
print(ann["classification"].unique())

# Filter to a specific class
tumor = ann[ann["classification"] == "Tumor"]

Visualising with spatialdata-plot#

sdata.pl.render_images("he_image").pl.render_shapes(
    "annotations",
    color="classification",
    fill_alpha=0.3,
    outline_alpha=0.9,
).pl.show(coordinate_systems="global")