Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

coordinate system of xenium explorer and stada are inconsistent

Open
#1,194 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
45/100
Issue type
Bug
Clarity
Needs clarification
Activity status
Active
Tech stack
python

Research direction

Start by tracing the xenium() and xenium_aligned_image() entry points with the provided Xenium output and alignment CSV, then inspect the coordinate metadata for morphology_focus, cell_labels, cell_boundaries, and cell_circles. Document the units and required transformation, and show how to extract and visualize each sample while preserving the Xenium Explorer coordinate system.

Written by the indexing model from the issue text.

Description

Dear sir:
Hi, I’m currently a beginner working with Xenium spatial transcriptomics, and I have a question about coordinate systems in SpatialData.

I have one Xenium slide containing 8 samples. In Xenium Explorer, the coordinate system appears to be in micrometer-scale units. However, when I load the data into SpatialData using:

sdata = xenium(
path="/STtonsil/Data/output/",
cells_as_circles=True
)

sdata.images["he_image"] = xenium_aligned_image(
image_path="../slide_1/0104154_Default_Extended.ome.tif",
alignment_file="../slide_1/slide1_HE_staining_matrix.csv"
)

I obtain the following SpatialData object:

SpatialData object
├── Images
│ ├── 'he_image': DataArray[cyx] (3, 111104, 56320)
│ └── 'morphology_focus': DataTree[cyx] (4, 112141, 54121), ...
├── Labels
│ ├── 'cell_labels': DataTree[yx] ...
│ └── 'nucleus_labels': DataTree[yx] ...
├── Points
│ └── 'transcripts': DataFrame ... (3D points)
├── Shapes
│ ├── 'cell_boundaries': GeoDataFrame ...
│ ├── 'cell_circles': GeoDataFrame ...
│ └── 'nucleus_boundaries': GeoDataFrame ...
└── Tables
└── 'table': AnnData ...

All of these elements are currently associated with the global coordinate system.

When I visualize the images using:

import matplotlib.pyplot as plt

axes = plt.subplots(1, 2, figsize=(10, 10))[1].flatten()

sdata.pl.render_images("he_image").pl.show(
ax=axes[0],
title="H&E image"
)

sdata.pl.render_images("morphology_focus").pl.show(
ax=axes[1],
title="Morphology image"
)

the x-axis of the resulting plot ranges from approximately 0 to 50,000. However, in Xenium Explorer, the corresponding coordinate system appears to range only up to approximately 10,000 µm.

Therefore, the coordinates do not seem to match. For example, when I extract the coordinates of sample C1 from my AnnData object:

xy_C1 = adata_slide1[
adata_slide1.obs["sampleid"] == "C1"
].obsm["spatial"]

xmin_C1, ymin_C1 = xy_C1.min(axis=0)
xmax_C1, ymax_C1 = xy_C1.max(axis=0)

print(
xmin_C1,
ymin_C1,
xmax_C1,
ymax_C1
)

the resulting coordinates do not correspond to the coordinates I see in Xenium Explorer.

Could you please explain how I can correctly convert or transform the SpatialData global coordinates into the actual Xenium micrometer coordinate system?

More specifically, I would like to know:

What coordinate system are morphology_focus, cell_labels, cell_boundaries, and cell_circles using in this SpatialData object?
How can I convert their coordinates to the same micrometer-scale coordinate system used by Xenium Explorer?
What is the correct way to extract and visualize each of the 8 samples separately while keeping the spatial coordinates consistent with Xenium Explorer?
Is there a recommended SpatialData function or transformation for converting between the image pixel coordinates and the Xenium physical (µm) coordinates?

I would really appreciate any guidance on this, as I’m still learning how Xenium and SpatialData handle coordinate systems. Thank you very much for your help!

spatialdata figure coordinate:

Image
Dominant language
Python
Stars
394
Forks
95
Avg merge
3d 9h
Merged PRs (30d)
5

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from scverse/spatialdata

All issues in scverse/spatialdata

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.