Data formats
MERFISHEYES reads the raw outputs of the common spatial platforms, so you don't need to pre-format anything. Drop a whole folder or a single file on the homepage; the format is worked out from what is inside.
At a glance
| Format | What to drop | Required | Also read if present |
|---|---|---|---|
| H5AD (AnnData) | A single .h5ad file | Coordinates in obsm['X_spatial'] | Embeddings such as obsm['X_umap'], and any cell type or metadata columns in obs |
| Xenium (10x) | The Xenium output folder | cells.csv(.gz) — the cell centroids | An expression matrix (cell_feature_matrix.h5, the cell_feature_matrix/ folder, or cell_by_gene.csv); a transcripts file is read as molecules |
| MERSCOPE (Vizgen) | The MERSCOPE output folder | cell_metadata.csv — per-cell coordinates | cell_by_gene.csv (expression matrix) |
| Molecules | One .parquet or .csv of per-molecule rows | A gene column, x and y (z for 3D data) | A cell id column |
| Image | An OME-Zarr image folder | Zarr v3, axes c, y, x; uint8 or uint16 | Several resolution levels |
| Already processed | A SpatialData store, an AnnData table in Zarr, or merfisheyes' own output folders | See the tabs below | Opens as it is — nothing is converted |
Format by format
Each tab shows the folder or file as it should look, which parts are required, and anything to watch out for. The same guide opens from What can I upload? on the homepage.
An AnnData file. Cells need coordinates; everything else is optional.
Upload: One .h5ad file → H5AD File
- data.h5ad
- obsm/X_spatialrequiredCell coordinates, [cells × 2] or [cells × 3]. obsm/spatial also works.
- XoptionalExpression matrix, [cells × genes], dense or sparse. Needed to colour by gene.
- var/_indexoptionalGene names (var/gene or var/genes also work).
- obs/<column>optionalCell types, clusters and other per-cell values — each becomes a colour-by column.
- obsm/X_umapoptionalEmbeddings: any obsm key starting with X_.
- uns/<column>_colorsoptionalYour own colours for a categorical column.
Making it yourself
From an AnnData (e.g. from Scanpy), or built from arrays
import anndata as ad
import pandas as pd
# counts: cells × genes (NumPy array or SciPy sparse matrix)
# xy: cells × 2 (or × 3) coordinates, e.g. in microns
adata = ad.AnnData(
X=counts,
obs=pd.DataFrame({"celltype": celltypes}, index=cell_ids),
var=pd.DataFrame(index=gene_names),
)
adata.obsm["X_spatial"] = xy # required
adata.obsm["X_umap"] = umap # optional
adata.write_h5ad("data.h5ad")- No coordinates in obsm? obs columns named center_x / center_y, x / y or centroid_x / centroid_y are used instead.
- A column with few distinct values is shown as categories; one with many numeric values as a gradient. Columns named leiden or louvain are always categories.
Molecule columns
Column names are detected per platform, and you can remap them when you upload. Parquet is strongly preferred for millions of molecules: it is columnar and needs far less memory than CSV.
| Platform | Gene | X | Y | Z | Cell ID |
|---|---|---|---|---|---|
| Xenium | feature_name | x_location | y_location | z_location | cell_id (UNASSIGNED = no cell) |
| MERSCOPE | gene | global_x | global_y | global_z | cell_id (-1 = no cell) |
| Custom | You pick each column from a dropdown |
Cell types you assigned yourself
Cell types don't have to be in the file. Run MapMyCells (or any tool) yourself, then choose Upload & process on server and add the resulting one-row-per-cell CSV in the MapMyCells celltype CSV (optional) box on the homepage. Its columns become columns to colour by, with their own palettes and differential expression. There is no cell typing on our side, so the labels stay yours.
The CSV has one row per cell, in the same order as the cells in your data, with a cell_id column first and one column per label. From an AnnData:
adata.obs[["my_celltype"]].to_csv("celltypes.csv", index_label="cell_id")