Skip to content

Visualizing a Xenium experiment on a remote server #501

@matthieuheitz

Description

@matthieuheitz

A collaborator gave me a folder with data from Xenium.
Being on Linux, I can't use Xenium Explorer, so I'm trying out Vitessce.

The data folder contains those files:

analysis/
aux_outputs/
cell_feature_matrix/
morphology_focus/
analysis.zarr.zip
analysis_summary.html
cell_boundaries.csv.gz
cell_boundaries.parquet
cell_feature_matrix.h5
cell_feature_matrix.zarr.zip
cells.csv.gz
cells.parquet
cells.zarr.zip
experiment.xenium
gene_panel.json
metrics_summary.csv
morphology.ome.tif
nucleus_boundaries.csv.gz
nucleus_boundaries.parquet
transcripts.csv.gz
transcripts.parquet
transcripts.zarr.zip

I downloaded the data on my server (RHEL9), and I'm trying to visualize it with Vitessce in a web browser on my desktop computer.
The data is big, which is why I don't put it on my desktop, and ideally, I would like the other users of the server to be able to also visualize that data (using Vitessce).
My hope is to not have to write the config file myself, and it seemed like the set of functions below would allow me to do so, but I'm not sure, so let me know if I'm hoping for something that doesn't exist.
On the server, I created a virtual environment with vitessce, spatialdata and spatialdata-io.
Then, I run this script:

import spatialdata as sd
import spatialdata_io
from vitessce import VitessceConfig, SpatialDataWrapper

DATA_DIR = "exp_D1"
zarr_filename = "my_xenium_data.zarr"
zarr_path = os.path.join(DATA_DIR,zarr_filename)

# 1. Load the Xenium directory (for the first time I run this script)
# It seems the spatialdata object needs to have its .path populated, and saving a zarr seems to be the way to do it.
#sdata = spatialdata_io.xenium(DATA_DIR)
#sdata.write(zarr_path)  # Save as Zarr

# Alternatively, read it from disk if already saved before
sdata = sd.read_zarr(zarr_path)

# 2. Create an automatic Vitessce setup
vc = VitessceConfig(schema_version="1.0.15", name='Xenium Review')

# 3. Generate the list of wrappers from your on-disk object
wrappers = SpatialDataWrapper.from_object(sdata)

# 4. Add wrapper(s) to the dataset
dataset = vc.add_dataset(name='D1')
for w in wrappers:
    dataset.add_object(w)

# 5. Launch the web interface
# open=False is so that it doesn't tell me that it cannot find a proper browser on my server.
vc.web_app(open=False,port=8003)

Then I set up an SSH tunnel on my desktop:
ssh -L 8003:localhost:8003 my_user@server_address.com
I'm able to access the data files when I visit http://localhost:8003 on my browser.

However, when I open the vitessce URL, I'm having problems.

First of all, the URL in the config is: "http://localhost:8003/A/0/545047fd-3dd5-4529-9544-98794727c018.sdata.zarr", which doesn't seem to match my file tree on my server, but maybe that's just vitessce having a symbolic internal file system?
Second of all, when I visit the vitessce URL, I land on a white page, so it seems it cannot find the data.
Can you help me understand what I'm doing wrong?

Here is my virtual env:

aiobotocore==3.4.0
aiohappyeyeballs==2.6.1
aiohttp==3.13.5
aioitertools==0.13.0
aiosignal==1.4.0
anndata==0.12.10
annotated-types==0.7.0
annsel==0.1.2
anyio==4.13.0
anywidget==0.10.0
array-api-compat==1.14.0
asciitree==0.3.3
asttokens==3.0.1
attrs==26.1.0
black==26.3.1
botocore==1.42.84
certifi==2026.2.25
charset-normalizer==3.4.7
click==8.3.2
cloudpickle==3.1.2
colorcet==3.1.0
comm==0.2.3
contourpy==1.3.3
cycler==0.12.1
dask==2024.11.2
dask-expr==1.1.19
dask-image==2025.11.0
datashader==0.19.0
decorator==5.2.1
Deprecated==1.3.1
distributed==2024.11.2
donfig==0.8.1.post1
executing==2.2.1
fasteners==0.20
FlowIO==1.4.0
fonttools==4.62.1
frozenlist==1.8.0
fsspec==2026.3.0
geopandas==1.1.3
google-crc32c==1.8.0
h11==0.16.0
h5py==3.16.0
idna==3.11
imagecodecs==2026.3.6
ImageIO==2.37.3
importlib_metadata==9.0.0
ipython==9.10.1
ipython_pygments_lexers==1.1.1
ipywidgets==8.1.8
jedi==0.19.2
Jinja2==3.1.6
jmespath==1.1.0
joblib==1.5.3
jupyterlab_widgets==3.0.16
kiwisolver==1.5.0
lazy-loader==0.5
legacy-api-wrap==1.5
llvmlite==0.47.0
locket==1.0.0
markdown-it-py==4.0.0
MarkupSafe==3.0.3
matplotlib==3.10.8
matplotlib-inline==0.2.1
mdurl==0.1.2
more-itertools==11.0.2
msgpack==1.1.2
multidict==6.7.1
multipledispatch==1.0.0
multiscale_spatial_image==2.0.3
mypy_extensions==1.1.0
narwhals==2.19.0
natsort==8.4.0
networkx==3.6.1
numba==0.65.0
numcodecs==0.15.1
numpy==2.4.4
ome-types==0.6.3
ome-zarr==0.9.0
packaging==26.1
pandas==2.3.3
param==2.3.3
parso==0.8.6
partd==1.4.2
pathlib_abc==0.5.2
pathspec==1.0.4
patsy==1.0.2
pexpect==4.9.0
pillow==12.2.0
PIMS==0.7
platformdirs==4.9.6
pooch==1.9.0
prompt_toolkit==3.0.52
propcache==0.4.1
psutil==7.2.2
psygnal==0.15.1
ptyprocess==0.7.0
pure_eval==0.2.3
pyarrow==23.0.1
pyct==0.6.0
pydantic==2.13.2
pydantic-extra-types==2.11.1
pydantic_core==2.46.2
Pygments==2.20.0
pynndescent==0.6.0
pyogrio==0.12.1
pyparsing==3.3.2
pyproj==3.7.2
python-dateutil==2.9.0.post0
pytokens==0.4.1
pytz==2026.1.post1
PyYAML==6.0.3
rangehttpserver==1.4.0
readfcs==2.1.0
requests==2.33.1
rich==15.0.0
s3fs==2026.3.0
scanpy==1.11.5
scikit-image==0.26.0
scikit-learn==1.8.0
scipy==1.17.1
seaborn==0.13.2
session-info2==0.4.1
shapely==2.1.2
six==1.17.0
slicerator==1.1.0
sortedcontainers==2.4.0
spatial_image==1.2.3
spatialdata==0.5.0
spatialdata-io==0.5.1
stack-data==0.6.3
starlette==1.0.0
statsmodels==0.14.6
tblib==3.2.2
threadpoolctl==3.6.0
tifffile==2026.3.3
toolz==1.1.0
tornado==6.5.5
tqdm==4.67.3
traitlets==5.14.3
typing-inspection==0.4.2
typing_extensions==4.15.0
tzdata==2026.1
umap-learn==0.5.12
universal_pathlib==0.3.10
urllib3==2.6.3
uvicorn==0.44.0
vitessce==3.8.3
wcwidth==0.6.0
widgetsnbextension==4.0.15
wrapt==2.1.2
xarray==2026.4.0
xarray-dataclass==3.0.0
xarray-schema==0.0.3
xarray-spatial==0.5.3
xmltodict==1.0.4
xsdata==26.2
yarl==1.23.0
zarr==2.18.7
zict==3.0.0
zipp==3.23.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions