Introducing CytoMAP: a toolbox for spatial analysis of segmented cell objects

Hello esteemed colleagues,

I would like to introduce you to CytoMAP, which is a program that includes multiple advanced data analytic techniques for analyzing cell position and phenotype data. The goal is to take established analytical techniques, such as clustering algorithms, distance measurements, dimensional reduction, etc. and package them in a user friendly way, allowing researchers to explore complex cellular datasets.

CytoMAP seeks to fill the need for easy to use software facilitating spatial analysis of single cells. Thus, CytoMAP deals primarily with already segmented cells, i.e. tables of cells with position and channel values. My goal is to help users do something more with their segmented image data.

If you are interested in learning more please see our recent publication:

CytoMAP is publicly available here:

There is a mostly complete Wiki available here:

A few additional notes for the curious.

  • CytoMAP works with tables of points independent from your chosen segmentation software and is technically not image analysis software
  • All of the analysis supports 2D or 3D data. (I hope to add support for time eventually)
  • CytoMAP supports analysis of large volumes, multiple samples, and many cell objects
  • CytoMAP excels at defining regions and cellular patterns in whole slide or volume image data
  • CytoMAP is UI based and does not require any coding knowledge


Thanks for Information

After I generate cell-intensity data with their x-y location from QuPath, how to organize for CytoMap? Can you provide any example of a QuPath .csv file compatible to CytoMap?

1 Like

I haven’t specifically used QuPath, but I do have example .csv files on gitlab;

The format is each row being a cell, and columns being channels, position etc. like the table shown below. The first row should be the header with channel names. Ideally the channel names shouldn’t have symbols or special characters. If CytoMAP cannot automatically identify which channel is position, it will ask. If there is no depth, i.e. Z position it will add a column of zeros since everything is written assuming 3 dimensional datasets.

CD31_corrected CD11c_corrected CD169_corrected MHC2_B220clean Myeloid PositionX PositionY PositionZ chID Sphericity Volume Classifier
3.12424 0.613276 11.7058 2.32278 80.7795 382.9 778.6 9.23048 5594 0.887945 241.933 1
10.9094 18.1807 10.3939 7.1032 67.0661 739.4 688.4 9.06742 5595 0.648447 334.402 1
20.1753 29.3018 7.93401 11.1055 69.5939 862.2 715.8 10.51935 5596 0.809646 342.535 1
9.62431 43.6059 4.44383 5.6372 76.8895 958.1 777.3 11.38515 5597 0.842428 75.3365 1
14.845 15.0257 19.8404 10.5 60.7404 979.8 784.1 9.72825 5598 0.607925 148.746 1
14.5974 18.9553 6.10919 4.65641 67.336 1066.2 685.2 10.10915 5599 0.798238 340.653 1
25.1736 9.52474 6.23959 4.34171 56.6489 1086.4 733.4 10.78305 5600 0.73209 172.278 1

There are a few ways to set up multiple sample imports.

  1. If you have multiple cell types and multiple samples:
    Each sample should be in its own folder with each cell type being in its own .csv.
  2. If you have multiple samples with only one .csv per sample, you can use Import Multiple Samples and select multiple .csv files. CytoMAP will then assume each .csv is a sample.

I re-arranged the data as shown above. I was trying to follow the Wiki page but it doesn’t say how to check if the data is loaded correctly. Here’s what I want to do:

  1. Calculate distance between marker 1 (say cyto-keratin) to marker 2 (CD8).
  2. I tried to use the “Cluster cell to phenotypes” - it shows the Davies-Bouldin value vs. No.Cluster plot but not sure how to see the ‘clusters’.
    Is there any step by step guide with an example?

I am working on adding example workflows. I have a few videos using some example data here

I found a bug in the plot of clustered cells causing the plot of the clustered cells not show up. The cluster values were still calculated. To view the clusters I usually make a new figure, then assign the C-axis to my model. I then try different markers on the X, and Y axes to get a feel for what the clusters mean. Here you can click on a point on the graph and it will tell you which cluster number it belongs to.

To calculate the distance between two populations you have to annotate those cells. I made an example video of how to do this here: Example Workflows/Distance.


Great! Thanks for the video - made it easier. Just one heads-up: the Local Density option is not available in my GUI. Is that something added recently? Also, generally speaking, how do I upgrade to the latest version? I have a few other queries: How do I export the distance or neighborhood information? How is individual channel gated/thresholded to determine positivity?
I will check back the Workflow folder time to time for more videos. This was really helpful. :clap: :clap: :clap:

If your data is coming from QuPath, you can calculate this very quickly ahead of time using the Detect Centroid Distances 2D.


This is a recent feature, which I would need to compile into the standalone version.

Unfortunately, as far as I can tell, MATLAB does not support updating deployed software. If you have a compiled, or standalone version of CytoMAP you would have to uninstall it, download the latest compiled version, then re-install it.

If you have a full MATLAB license you can download the CytoMAP repository from gitlab and run it like I did in the video. You could also use git to copy the CytoMAP repository to your local machine and keep it up to date.

In the main CytoMAP window, under the File drop down there are two export options.

  • Export Data Tables as .csv - this exports the raw neighborhoods or cell channel values to a table in the same format as the imported data.
  • File Export Data For Prism - this exports the cell channel values to a .csv in a different format more convenient for some external graphing software.
  • In most plots there is an export data to .csv option at the top which is a quick way to export a specific channel or two for a select cell population

I have only just recently started implementing this in CytoMAP. Currently I use the same clustering algorithms used to identify regions in tissues. These include k-means or self organizing maps, which look at all of the channels at once and try to find groups within the data with similar features. There is a ton of active research in this area of identifying cell types, and this is not CytoMAP’s main function.

If you only need to look at a few cell populations I would manually gate on these by looking at the original images and finding the average channel intensity of positive cells as descried by Gerner, et al. . If you have many channels, and lots of cell types I would then use clustering in CytoMAP, or other software like Phenograph etc.

If you need to calculate distances between cell populations, I think it makes more sense to do this in QuPath or whichever software you used to segment cells.

CytoMAP is good for defining regions in tissues using clustering algorithms based on local cellular composition and comparing these regions across sample cohorts. If you are calculating distance to a specific type of microenvironment that is difficult to define with manual annotation, then CytoMAP would also be useful.


Hi! I am trying to use the most updated feature to cluster neighborhoods on a gated region but it gets stuck in: " Preparing data for sorting" . Same thing happens when I try to cluster on cell-centered neighborhoods.

Sorry I have to ask for a workflow again. I classified the cells accordingly but nothing happens after it run the distance algorithm. Not sure what I’m doing wrong.

Nothing should happen visually, if it works. The measurements show up on the measurement list per cell. If you want to visualize it, the easiest way is with the Measure->Measurement maps.

1 Like

Hi Maria,

After some testing I found the way this worked was very fragile and if the manual neighborhoods were not selected in just the right way everything broke. I fixed this by adding a prompt. Now when you cluster or calculate statistics for manual regions CytoMAP prompts you with a list of available manually gated neighborhoods that are present in all of the selected samples.

I have updated the code and put the new compiled version on Gitlab and Mathworks.

There were some bugs making manual regions only work for raster scanned neighborhoods. I have fixed this in version 1.4.3. You can now use either manually gated neighborhoods from cell-centered neighborhoods or raster scanned neighborhoods.