Spatial Analysis

This notebook depends on the ImageProcessing and SingleCellAnalysis Notebooks to have been executed first! Be sure to do those notebooks before trying this one.

[1]:
import os
import numpy as np
import pandas as pd
import palmettobug as pbug
The PalmettoBUG package is copyrighted 2024-2025 by the Medical University of South Carolina and licensed under the GPL-3 license.
It is free & open source software, can  be redistributed in compliance with the GPL3 license, and comes with absolutely no warranty.
In python, use palmettobug.print_license() to see the license, or use palmettobug.print_3rd_party_license_info() to print information
about the licenses and copyright of 3rd party software used in PalmettoBUG itself or in the creation of PalmettoBUG.
[2]:
pbug.__version__
[2]:
'0.2.11'

CHANGE The following directory to match an existing directory on your computer if you are testing this tutorial on your own machine!

[3]:
my_computer_path =  "C:/Users/Default/Desktop"  ## CHANGE This DIRECTORY to match an existing directory on your computer if you testing this tutorial on your own machine!

Load a Previously made Analysis

The spatial module of the PalmettoBUG package requires that a single-cell analysis has already been loaded, and that that analysis has the information on cell centroids and other spatial information (this should be automatically the case for the data generated through palmettobug itself for an imaging experiment). Of course, this cannot be done on a single-cell analysis derived from solution-mode data.

In the next couple of cells I load a project directory & Analysis directory previously created by other notebooks in the Core Pipeline tutorials. I also load a saved clustering (merging) from the analysis.

[4]:
'''This cell contains the code to go from an already set up MCD project (as in, .tiff files and segmentation masks have already been generated in the expected folders) to an analysis
Normally, you may have already done the Analysis, and could go straight into setting up the SpatialAnalysis, but since these steps are separated into two notebooks in this example
we need to re-enter the project and create the Single Cell Analysis again.
'''

project_directory = f"{my_computer_path}/Example_IMC"
resolutions = [1.0, 1.0]    ## in micrometers. 1 micron is standard IMC resolution
ImageAnalysis = pbug.imc_entrypoint(project_directory, resolutions =  resolutions, from_mcds = False)

## Setup the analysis directory // set up the ImageAnalysis.directory_object for later access of critical directories
analysis_folder_name = "MyAmazingAnalysis"
ImageAnalysis.directory_object.make_analysis_dirs(analysis_folder_name)
input_img_folder = ImageAnalysis.directory_object.img_dir + "/img"
input_mask_folder = ImageAnalysis.directory_object.masks_dir + "/example_deepcell_masks"  ## for replicability with example masks. Also, 'deepcell', etc.
[5]:
'''This cell contains the code to enter an already made analysis directory where a merging ('merging') has already been performed'''

Analysis_experiment = pbug.Analysis()
Analysis_experiment.load_data(ImageAnalysis.directory_object.Analysis_internal_dir)


merging_name = 'merging'
Analysis_experiment.do_scaling("%quantile")    ## loading a saved clustering requires that the data matches, so the scaling of the data when the annotation was saved needs to be applied before loading the data.
                                               ## The data scaling can be changed after loading the clustering
Analysis_experiment.load_clustering(ImageAnalysis.directory_object.Analysis_internal_dir + f"/clusterings/{merging_name}.csv")
[6]:
''' The spatial modules by default export plots to a predefined directory structure
(in the folder ImageAnalysis.directory_object.Analysis_internal_dir + "/Spatial_plots").

Note that this newly created output_directory variable is not used anywhere in this notebook, it is only
here a helpful pointer to where to look for the exported plots if you are having difficulty finding them.'''

output_directory = ImageAnalysis.directory_object.Analysis_internal_dir + "/Spatial_plots"

Set up SpatialAnalysis Class, and neighbor plots

The neighbor plots (interaction, enrichment, centrality) are essentially just wrappers on squipdy methods which operate on the underlying anndata object inside the PalmettoBUG.Analysis and PalmettoBUG.SpatialAnalysis classes.

[7]:
space_analysis = pbug.SpatialAnalysis()
space_analysis.add_Analysis(Analysis_experiment)
space_analysis.do_neighbors('Radius', 20)                 ## this runs the squidpy neighbors method, using the mask centroids
[8]:
''' neighbor plots (each wraps a squidpy method: see squidpy's documenttion for more thorough details) --

1). Interaction plots. These show the raw number of interactions between cell types. However, this is sensitive to which cell types are the most common in the images

2). Neighborhood Enrichment plots. These use a permutation test to see if celltypes interact more than would have been expected by chance. The values of the heatmap
reflect z-scores of the difference between the expected number of interactions and the actually observed number of interactions.

3). Centrality plots. These calculate various centrality statistics on the data. See squidpy documentation for more information.

Interaction and Enrichment plots can be 'facetted' inside palmettobug. This effectively means that the data is subsetted into multiple anndata objects, grouping by the
unique values of the supplied facet_by column in the SpatialAnalysis.exp.data.obs dataframe (here, 'condition'). The first panel of a facetted plot is always the entire dataset's interaction/enrichment
plot, but each subsequent panel shows that plot if only the data for that group is considered. This could be useful for comparing the association of the cell types across conditions.

If filename is set to None (as in the examples), the plot is not written to the disk anywhere, only returned by the function.
'''
space_analysis.plot_neighbor_enrichment(clustering = "merging", facet_by = "condition", col_num = 1, seed = 42, n_perms = 1000, filename = "Neighborhood_enrichemnt")
[8]:
../../_images/notebooks_CoreImagingPipeline_SpatialAnalysis_11_0.png
[9]:
plot = space_analysis.plot_neighbor_interactions(clustering = "merging", facet_by = "None", filename = "Interaction_matrix")
plot
[9]:
../../_images/notebooks_CoreImagingPipeline_SpatialAnalysis_12_0.png
[10]:
''' There are three kinds of centrality statistic -- see API documentation  / squidpy's centrality methods for more details '''
space_analysis.plot_neighbor_centrality(clustering = "merging", filename = "Closeness_centrality")
ERROR: Unable to fetch palette, reason: 'merging_colors'. Using `None`.
[10]:
../../_images/notebooks_CoreImagingPipeline_SpatialAnalysis_13_1.png

Making Cell maps: Visualization cell types in their spatial context

These can either be with the format “points”, where cells are represented as circles of varying sizes around their centroids, or as “masks” – which uses a squidpy method to display the cells’ original segmentation shapes.

[11]:
''' Note how the id parameter is the filename of the FCS file from which the single-cell data came from -- not the TIFF file!
This is because of how the SpatialAnalysis class is operating on an anndata object from an Analysis object, which is used for
both imaging and solution mode experiments, and operates primarily with the FCS files.

Alternatively, you pass in a number (corresponding to the sample_id corresponding to that file in the metadata csv) instead of the filename.
This is used in the 'masks' example immediately after this to create a plot for this same image.
'''

plot = space_analysis.plot_cell_maps("points", clustering = 'merging', id = 'CRC_1_ROI_002.ome.fcs')  ### Note!!!  While it does return the figure as shown here, this function is also writing to the disk a copy of the figure
                                                                               ## The figure's filename is determined by the name of the image, so if plot_cell_maps is called again on the SAME image, it will OVERWRITE
                                                                               ## the copy of this figure on the disk. If you want to avoid overwriting and save multiple versions of the cell maps plots for a single image,
                                                                               ## you need to save the new plot to a new location (using plot.savefig(_alternatefile_path) or similar), or manually rename / copy the old plot
                                                                               ## into a new location before calling plot_cell_maps() for the second time
plot
[11]:
../../_images/notebooks_CoreImagingPipeline_SpatialAnalysis_15_0.png
[12]:
''' Note the parameter id ___________   '''

plot = space_analysis.plot_cell_maps("masks", id = '1')
plot
[12]:
../../_images/notebooks_CoreImagingPipeline_SpatialAnalysis_16_0.png

Group Cells into Cellular Neighborhoods (CNs)

This clusters cells based on the celltype composition of their neighbors, using either FlowSOM or Leiden clustering. Because these are unsupervised algorithms, annotation and merging is required afterwards to keep biologically relevant labels.

It adds a column to Analysis.data.obs and SpatialAnalysis.exp.data.obs, with the name ‘CN’ that contains the clustering numbers from the algorithm. It also creates a plot – a UMAP for leiden clustering, and a spanning tree plot for FlowSOM, which is returned as a figure.

Here I do leiden clusteirng, although FlowSOM has the advantages of being faster to run allowing control over the final number of clusters – which can be quite useful during annottaion / merging.

[13]:
figure = space_analysis.do_neighborhood_CNs(clustering = "merging",
                                              leiden_or_flowsom  = "Leiden",
                                              seed  = 42,
                                              resolution  = 0.15,
                                              min_dist  = 0.1,
                                              n_neighbors  = 15,
                                           plot_filename = "Leiden_UMAP")
figure
C:\Users\benca\miniforge3\envs\main\lib\site-packages\tqdm\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from .autonotebook import tqdm as notebook_tqdm
C:\Users\Default\Desktop\PalmettoBUG\palmettobug\Analysis_functions\SpatialAnalysis.py:1288: FutureWarning: In the future, the default backend for leiden will be igraph instead of leidenalg.

 To achieve the future defaults please pass: flavor="igraph" and n_iterations=2.  directed must also be False to work with igraph's implementation.
  sc.tl.leiden(new_anndata,
[13]:
../../_images/notebooks_CoreImagingPipeline_SpatialAnalysis_18_1.png
[14]:
space_analysis.exp.data.obs
[14]:
sample_id file_name patient_id condition merging CN
0 0 CRC_1_ROI_001.ome.fcs 7139 SSA discard 1
1 0 CRC_1_ROI_001.ome.fcs 7139 SSA beta_catenin 1
2 0 CRC_1_ROI_001.ome.fcs 7139 SSA beta_catenin 1
3 0 CRC_1_ROI_001.ome.fcs 7139 SSA beta_catenin 6
4 0 CRC_1_ROI_001.ome.fcs 7139 SSA beta_catenin 8
... ... ... ... ... ... ...
36922 9 CRC_3_ROI_004.ome.fcs 7139 TA CD32b 2
36923 9 CRC_3_ROI_004.ome.fcs 7139 TA CD11b 2
36924 9 CRC_3_ROI_004.ome.fcs 7139 TA p_selectin 4
36925 9 CRC_3_ROI_004.ome.fcs 7139 TA beta_catenin 6
36926 9 CRC_3_ROI_004.ome.fcs 7139 TA p_selectin 2

36927 rows × 6 columns

[15]:
figure = space_analysis.plot_cell_maps('masks', id = '1',
              clustering = "CN")
figure
[15]:
../../_images/notebooks_CoreImagingPipeline_SpatialAnalysis_20_0.png
[16]:
space_analysis.plot_CN_heatmap("merging")
[16]:
../../_images/notebooks_CoreImagingPipeline_SpatialAnalysis_21_0.png
[17]:
space_analysis.exp.data.obs['CN']
[17]:
0        1
1        1
2        1
3        6
4        8
        ..
36922    2
36923    2
36924    4
36925    6
36926    2
Name: CN, Length: 36927, dtype: int64
[18]:
figure = space_analysis.plot_CN_abundance("merging")
../../_images/notebooks_CoreImagingPipeline_SpatialAnalysis_23_0.png

Ripley’s Statistics and SpaceANOVA

SpaceANOVA works by calculating the celltype-to-celltype Ripley’s statistics (K , L, and g) over a set of radii for every celltype–celltype pair in every image. Then, those Ripley’s statistics (usually g) can be treated as functions for the purposes of a functional ANOVA test. This allows the entire shape of the celltype–celltype association to be used in the statistical comparison, and not a single selected radii.

To run, this method key parameters are:

1). condition1 and condition2 --> these can be left blank (default = None for both) to do multi-comparisons, and get statistics looking at all conditions at once. Otherwise, two conditions in the 'condition' column of SpatialAnalysis.exp.data.obs should be provided to do a pairwise comparison

2). celltype_key --> Ths is the column in SpatialAnalysis.exp.data.obs containing the cell type clustering (usually 'merging', but also could be 'metaclustering', 'leiden', 'classification', or a custom grouping)

3). max, min, step --> These integers define the radii to examine. The radii can be seen using the python range object: range(min, max, step)

4). threshold --> If the number of cells of a given celltype is less than this integer, than that celltype-celltype comparison will be ignored for that image, as in No Ripley's statistic will be calculated. Note that if ALL the images for a given condition(s) fails to meet this threshold for a given celltype, such that only one condition has data, then that celltype-celltype comparison will be dropped from the statistical analysis.

5). permutations --> If > 0, then a permutation correction of the data will be performed, using the number of permutations defined by this parameter. Permutation correction is almost always recommended as it corrects for the actual distribution of point in the data. However, it does slow the calculation.

For other parameters, see the API documentation.

[19]:
'''
Some 'cell types' were very rare in this annotation and create a lot of extra warning messages when they fail to meet the threshold in an image -- I will drop them
to simplify the outputs.

WARNING! WARNING! WARNING! This step is very committal and affects all methods from the Analysis and SpatialAnalysis steps! If you only want to drop cell types for spaceANOVA,
you will want to either do spaceANOVA analysis last, or reload the single-cell Analysis afterwards to restore the dropped cells!
'''
Analysis_experiment.filter_data('discard', 'merging')
Analysis_experiment.filter_data('CD31', 'merging')
Analysis_experiment.filter_data('CD32b', 'merging')
Analysis_experiment.filter_data('e_cadherin', 'merging')
[20]:
space_analysis.do_SpaceANOVA_ripleys_stats(condition1 = None,
                                    condition2 = None,
                                    clustering = 'merging',
                                    max = 100,
                                    min = 10,
                                    step = 5,
                                    threshold = 10,
                                    permutations = 10,
                                    seed = 42,
                                    center_on_zero = False)
The celltype immune is only present in one condition -- ANOVAs and F-statistics will not be available for that celltype!
One or both of cellTypes beta_catenin or CD20 has less than 10 cells in the image 5!
One or both of cellTypes beta_catenin or CD8 has less than 10 cells in the image 5!
One or both of cellTypes beta_catenin or CD11b has less than 10 cells in the image 8!
One or both of cellTypes beta_catenin or CD68 has less than 10 cells in the image 8!
One or both of cellTypes beta_catenin or collagen has less than 10 cells in the image 6!
One or both of cellTypes beta_catenin or collagen has less than 10 cells in the image 8!
One or both of cellTypes beta_catenin or p_selectin has less than 10 cells in the image 5!
One or both of cellTypes beta_catenin or FoxP3 has less than 10 cells in the image 0!
One or both of cellTypes beta_catenin or FoxP3 has less than 10 cells in the image 3!
One or both of cellTypes beta_catenin or FoxP3 has less than 10 cells in the image 4!
One or both of cellTypes beta_catenin or FoxP3 has less than 10 cells in the image 5!
One or both of cellTypes beta_catenin or FoxP3 has less than 10 cells in the image 8!
One or both of cellTypes beta_catenin or immune has less than 10 cells in the image 0!
One or both of cellTypes beta_catenin or immune has less than 10 cells in the image 1!
One or both of cellTypes beta_catenin or immune has less than 10 cells in the image 2!
One or both of cellTypes beta_catenin or immune has less than 10 cells in the image 3!
One or both of cellTypes beta_catenin or immune has less than 10 cells in the image 4!
One or both of cellTypes beta_catenin or immune has less than 10 cells in the image 5!
One or both of cellTypes beta_catenin or immune has less than 10 cells in the image 8!
One or both of cellTypes CD4 or CD20 has less than 10 cells in the image 5!
One or both of cellTypes CD4 or CD8 has less than 10 cells in the image 5!
One or both of cellTypes CD4 or CD11b has less than 10 cells in the image 8!
One or both of cellTypes CD4 or CD68 has less than 10 cells in the image 8!
One or both of cellTypes CD4 or collagen has less than 10 cells in the image 6!
One or both of cellTypes CD4 or collagen has less than 10 cells in the image 8!
One or both of cellTypes CD4 or p_selectin has less than 10 cells in the image 5!
One or both of cellTypes CD4 or FoxP3 has less than 10 cells in the image 0!
One or both of cellTypes CD4 or FoxP3 has less than 10 cells in the image 3!
One or both of cellTypes CD4 or FoxP3 has less than 10 cells in the image 4!
One or both of cellTypes CD4 or FoxP3 has less than 10 cells in the image 5!
One or both of cellTypes CD4 or FoxP3 has less than 10 cells in the image 8!
One or both of cellTypes CD4 or immune has less than 10 cells in the image 0!
One or both of cellTypes CD4 or immune has less than 10 cells in the image 1!
One or both of cellTypes CD4 or immune has less than 10 cells in the image 2!
One or both of cellTypes CD4 or immune has less than 10 cells in the image 3!
One or both of cellTypes CD4 or immune has less than 10 cells in the image 4!
One or both of cellTypes CD4 or immune has less than 10 cells in the image 5!
One or both of cellTypes CD4 or immune has less than 10 cells in the image 8!
One or both of cellTypes CD20 or beta_catenin has less than 10 cells in the image 5!
One or both of cellTypes CD20 or CD4 has less than 10 cells in the image 5!
One or both of cellTypes CD20 or CD20 has less than 10 cells in the image 5!
One or both of cellTypes CD20 or CD8 has less than 10 cells in the image 5!
One or both of cellTypes CD20 or CD11b has less than 10 cells in the image 5!
One or both of cellTypes CD20 or CD11b has less than 10 cells in the image 8!
One or both of cellTypes CD20 or CD68 has less than 10 cells in the image 5!
One or both of cellTypes CD20 or CD68 has less than 10 cells in the image 8!
One or both of cellTypes CD20 or collagen has less than 10 cells in the image 5!
One or both of cellTypes CD20 or collagen has less than 10 cells in the image 6!
One or both of cellTypes CD20 or collagen has less than 10 cells in the image 8!
One or both of cellTypes CD20 or p_selectin has less than 10 cells in the image 5!
One or both of cellTypes CD20 or FoxP3 has less than 10 cells in the image 0!
One or both of cellTypes CD20 or FoxP3 has less than 10 cells in the image 3!
One or both of cellTypes CD20 or FoxP3 has less than 10 cells in the image 4!
One or both of cellTypes CD20 or FoxP3 has less than 10 cells in the image 5!
One or both of cellTypes CD20 or FoxP3 has less than 10 cells in the image 8!
One or both of cellTypes CD20 or immune has less than 10 cells in the image 0!
One or both of cellTypes CD20 or immune has less than 10 cells in the image 1!
One or both of cellTypes CD20 or immune has less than 10 cells in the image 2!
One or both of cellTypes CD20 or immune has less than 10 cells in the image 3!
One or both of cellTypes CD20 or immune has less than 10 cells in the image 4!
One or both of cellTypes CD20 or immune has less than 10 cells in the image 5!
One or both of cellTypes CD20 or immune has less than 10 cells in the image 8!
One or both of cellTypes CD8 or beta_catenin has less than 10 cells in the image 5!
One or both of cellTypes CD8 or CD4 has less than 10 cells in the image 5!
One or both of cellTypes CD8 or CD20 has less than 10 cells in the image 5!
One or both of cellTypes CD8 or CD8 has less than 10 cells in the image 5!
One or both of cellTypes CD8 or CD11b has less than 10 cells in the image 5!
One or both of cellTypes CD8 or CD11b has less than 10 cells in the image 8!
One or both of cellTypes CD8 or CD68 has less than 10 cells in the image 5!
One or both of cellTypes CD8 or CD68 has less than 10 cells in the image 8!
One or both of cellTypes CD8 or collagen has less than 10 cells in the image 5!
One or both of cellTypes CD8 or collagen has less than 10 cells in the image 6!
One or both of cellTypes CD8 or collagen has less than 10 cells in the image 8!
One or both of cellTypes CD8 or p_selectin has less than 10 cells in the image 5!
One or both of cellTypes CD8 or FoxP3 has less than 10 cells in the image 0!
One or both of cellTypes CD8 or FoxP3 has less than 10 cells in the image 3!
One or both of cellTypes CD8 or FoxP3 has less than 10 cells in the image 4!
One or both of cellTypes CD8 or FoxP3 has less than 10 cells in the image 5!
One or both of cellTypes CD8 or FoxP3 has less than 10 cells in the image 8!
One or both of cellTypes CD8 or immune has less than 10 cells in the image 0!
One or both of cellTypes CD8 or immune has less than 10 cells in the image 1!
One or both of cellTypes CD8 or immune has less than 10 cells in the image 2!
One or both of cellTypes CD8 or immune has less than 10 cells in the image 3!
One or both of cellTypes CD8 or immune has less than 10 cells in the image 4!
One or both of cellTypes CD8 or immune has less than 10 cells in the image 5!
One or both of cellTypes CD8 or immune has less than 10 cells in the image 8!
One or both of cellTypes CD11b or beta_catenin has less than 10 cells in the image 8!
One or both of cellTypes CD11b or CD4 has less than 10 cells in the image 8!
One or both of cellTypes CD11b or CD20 has less than 10 cells in the image 5!
One or both of cellTypes CD11b or CD20 has less than 10 cells in the image 8!
One or both of cellTypes CD11b or CD8 has less than 10 cells in the image 5!
One or both of cellTypes CD11b or CD8 has less than 10 cells in the image 8!
One or both of cellTypes CD11b or CD11b has less than 10 cells in the image 8!
One or both of cellTypes CD11b or CD68 has less than 10 cells in the image 8!
One or both of cellTypes CD11b or collagen has less than 10 cells in the image 6!
One or both of cellTypes CD11b or collagen has less than 10 cells in the image 8!
One or both of cellTypes CD11b or p_selectin has less than 10 cells in the image 5!
One or both of cellTypes CD11b or p_selectin has less than 10 cells in the image 8!
One or both of cellTypes CD11b or FoxP3 has less than 10 cells in the image 0!
One or both of cellTypes CD11b or FoxP3 has less than 10 cells in the image 3!
One or both of cellTypes CD11b or FoxP3 has less than 10 cells in the image 4!
One or both of cellTypes CD11b or FoxP3 has less than 10 cells in the image 5!
One or both of cellTypes CD11b or FoxP3 has less than 10 cells in the image 8!
One or both of cellTypes CD11b or immune has less than 10 cells in the image 0!
One or both of cellTypes CD11b or immune has less than 10 cells in the image 1!
One or both of cellTypes CD11b or immune has less than 10 cells in the image 2!
One or both of cellTypes CD11b or immune has less than 10 cells in the image 3!
One or both of cellTypes CD11b or immune has less than 10 cells in the image 4!
One or both of cellTypes CD11b or immune has less than 10 cells in the image 5!
One or both of cellTypes CD11b or immune has less than 10 cells in the image 8!
One or both of cellTypes CD68 or beta_catenin has less than 10 cells in the image 8!
One or both of cellTypes CD68 or CD4 has less than 10 cells in the image 8!
One or both of cellTypes CD68 or CD20 has less than 10 cells in the image 5!
One or both of cellTypes CD68 or CD20 has less than 10 cells in the image 8!
One or both of cellTypes CD68 or CD8 has less than 10 cells in the image 5!
One or both of cellTypes CD68 or CD8 has less than 10 cells in the image 8!
One or both of cellTypes CD68 or CD11b has less than 10 cells in the image 8!
One or both of cellTypes CD68 or CD68 has less than 10 cells in the image 8!
One or both of cellTypes CD68 or collagen has less than 10 cells in the image 6!
One or both of cellTypes CD68 or collagen has less than 10 cells in the image 8!
One or both of cellTypes CD68 or p_selectin has less than 10 cells in the image 5!
One or both of cellTypes CD68 or p_selectin has less than 10 cells in the image 8!
One or both of cellTypes CD68 or FoxP3 has less than 10 cells in the image 0!
One or both of cellTypes CD68 or FoxP3 has less than 10 cells in the image 3!
One or both of cellTypes CD68 or FoxP3 has less than 10 cells in the image 4!
One or both of cellTypes CD68 or FoxP3 has less than 10 cells in the image 5!
One or both of cellTypes CD68 or FoxP3 has less than 10 cells in the image 8!
One or both of cellTypes CD68 or immune has less than 10 cells in the image 0!
One or both of cellTypes CD68 or immune has less than 10 cells in the image 1!
One or both of cellTypes CD68 or immune has less than 10 cells in the image 2!
One or both of cellTypes CD68 or immune has less than 10 cells in the image 3!
One or both of cellTypes CD68 or immune has less than 10 cells in the image 4!
One or both of cellTypes CD68 or immune has less than 10 cells in the image 5!
One or both of cellTypes CD68 or immune has less than 10 cells in the image 8!
One or both of cellTypes collagen or beta_catenin has less than 10 cells in the image 6!
One or both of cellTypes collagen or beta_catenin has less than 10 cells in the image 8!
One or both of cellTypes collagen or CD4 has less than 10 cells in the image 6!
One or both of cellTypes collagen or CD4 has less than 10 cells in the image 8!
One or both of cellTypes collagen or CD20 has less than 10 cells in the image 5!
One or both of cellTypes collagen or CD20 has less than 10 cells in the image 6!
One or both of cellTypes collagen or CD20 has less than 10 cells in the image 8!
One or both of cellTypes collagen or CD8 has less than 10 cells in the image 5!
One or both of cellTypes collagen or CD8 has less than 10 cells in the image 6!
One or both of cellTypes collagen or CD8 has less than 10 cells in the image 8!
One or both of cellTypes collagen or CD11b has less than 10 cells in the image 6!
One or both of cellTypes collagen or CD11b has less than 10 cells in the image 8!
One or both of cellTypes collagen or CD68 has less than 10 cells in the image 6!
One or both of cellTypes collagen or CD68 has less than 10 cells in the image 8!
One or both of cellTypes collagen or collagen has less than 10 cells in the image 6!
One or both of cellTypes collagen or collagen has less than 10 cells in the image 8!
One or both of cellTypes collagen or p_selectin has less than 10 cells in the image 5!
One or both of cellTypes collagen or p_selectin has less than 10 cells in the image 6!
One or both of cellTypes collagen or p_selectin has less than 10 cells in the image 8!
One or both of cellTypes collagen or FoxP3 has less than 10 cells in the image 0!
One or both of cellTypes collagen or FoxP3 has less than 10 cells in the image 3!
One or both of cellTypes collagen or FoxP3 has less than 10 cells in the image 4!
One or both of cellTypes collagen or FoxP3 has less than 10 cells in the image 5!
One or both of cellTypes collagen or FoxP3 has less than 10 cells in the image 6!
One or both of cellTypes collagen or FoxP3 has less than 10 cells in the image 8!
One or both of cellTypes collagen or immune has less than 10 cells in the image 0!
One or both of cellTypes collagen or immune has less than 10 cells in the image 1!
One or both of cellTypes collagen or immune has less than 10 cells in the image 2!
One or both of cellTypes collagen or immune has less than 10 cells in the image 3!
One or both of cellTypes collagen or immune has less than 10 cells in the image 4!
One or both of cellTypes collagen or immune has less than 10 cells in the image 5!
One or both of cellTypes collagen or immune has less than 10 cells in the image 6!
One or both of cellTypes collagen or immune has less than 10 cells in the image 8!
One or both of cellTypes p_selectin or beta_catenin has less than 10 cells in the image 5!
One or both of cellTypes p_selectin or CD4 has less than 10 cells in the image 5!
One or both of cellTypes p_selectin or CD20 has less than 10 cells in the image 5!
One or both of cellTypes p_selectin or CD8 has less than 10 cells in the image 5!
One or both of cellTypes p_selectin or CD11b has less than 10 cells in the image 5!
One or both of cellTypes p_selectin or CD11b has less than 10 cells in the image 8!
One or both of cellTypes p_selectin or CD68 has less than 10 cells in the image 5!
One or both of cellTypes p_selectin or CD68 has less than 10 cells in the image 8!
One or both of cellTypes p_selectin or collagen has less than 10 cells in the image 5!
One or both of cellTypes p_selectin or collagen has less than 10 cells in the image 6!
One or both of cellTypes p_selectin or collagen has less than 10 cells in the image 8!
One or both of cellTypes p_selectin or p_selectin has less than 10 cells in the image 5!
One or both of cellTypes p_selectin or FoxP3 has less than 10 cells in the image 0!
One or both of cellTypes p_selectin or FoxP3 has less than 10 cells in the image 3!
One or both of cellTypes p_selectin or FoxP3 has less than 10 cells in the image 4!
One or both of cellTypes p_selectin or FoxP3 has less than 10 cells in the image 5!
One or both of cellTypes p_selectin or FoxP3 has less than 10 cells in the image 8!
One or both of cellTypes p_selectin or immune has less than 10 cells in the image 0!
One or both of cellTypes p_selectin or immune has less than 10 cells in the image 1!
One or both of cellTypes p_selectin or immune has less than 10 cells in the image 2!
One or both of cellTypes p_selectin or immune has less than 10 cells in the image 3!
One or both of cellTypes p_selectin or immune has less than 10 cells in the image 4!
One or both of cellTypes p_selectin or immune has less than 10 cells in the image 5!
One or both of cellTypes p_selectin or immune has less than 10 cells in the image 8!
One or both of cellTypes FoxP3 or beta_catenin has less than 10 cells in the image 0!
One or both of cellTypes FoxP3 or beta_catenin has less than 10 cells in the image 3!
One or both of cellTypes FoxP3 or beta_catenin has less than 10 cells in the image 4!
One or both of cellTypes FoxP3 or beta_catenin has less than 10 cells in the image 5!
One or both of cellTypes FoxP3 or beta_catenin has less than 10 cells in the image 8!
One or both of cellTypes FoxP3 or CD4 has less than 10 cells in the image 0!
One or both of cellTypes FoxP3 or CD4 has less than 10 cells in the image 3!
One or both of cellTypes FoxP3 or CD4 has less than 10 cells in the image 4!
One or both of cellTypes FoxP3 or CD4 has less than 10 cells in the image 5!
One or both of cellTypes FoxP3 or CD4 has less than 10 cells in the image 8!
One or both of cellTypes FoxP3 or CD20 has less than 10 cells in the image 0!
One or both of cellTypes FoxP3 or CD20 has less than 10 cells in the image 3!
One or both of cellTypes FoxP3 or CD20 has less than 10 cells in the image 4!
One or both of cellTypes FoxP3 or CD20 has less than 10 cells in the image 5!
One or both of cellTypes FoxP3 or CD20 has less than 10 cells in the image 8!
One or both of cellTypes FoxP3 or CD8 has less than 10 cells in the image 0!
One or both of cellTypes FoxP3 or CD8 has less than 10 cells in the image 3!
One or both of cellTypes FoxP3 or CD8 has less than 10 cells in the image 4!
One or both of cellTypes FoxP3 or CD8 has less than 10 cells in the image 5!
One or both of cellTypes FoxP3 or CD8 has less than 10 cells in the image 8!
One or both of cellTypes FoxP3 or CD11b has less than 10 cells in the image 0!
One or both of cellTypes FoxP3 or CD11b has less than 10 cells in the image 3!
One or both of cellTypes FoxP3 or CD11b has less than 10 cells in the image 4!
One or both of cellTypes FoxP3 or CD11b has less than 10 cells in the image 5!
One or both of cellTypes FoxP3 or CD11b has less than 10 cells in the image 8!
One or both of cellTypes FoxP3 or CD68 has less than 10 cells in the image 0!
One or both of cellTypes FoxP3 or CD68 has less than 10 cells in the image 3!
One or both of cellTypes FoxP3 or CD68 has less than 10 cells in the image 4!
One or both of cellTypes FoxP3 or CD68 has less than 10 cells in the image 5!
One or both of cellTypes FoxP3 or CD68 has less than 10 cells in the image 8!
One or both of cellTypes FoxP3 or collagen has less than 10 cells in the image 0!
One or both of cellTypes FoxP3 or collagen has less than 10 cells in the image 3!
One or both of cellTypes FoxP3 or collagen has less than 10 cells in the image 4!
One or both of cellTypes FoxP3 or collagen has less than 10 cells in the image 5!
One or both of cellTypes FoxP3 or collagen has less than 10 cells in the image 6!
One or both of cellTypes FoxP3 or collagen has less than 10 cells in the image 8!
One or both of cellTypes FoxP3 or p_selectin has less than 10 cells in the image 0!
One or both of cellTypes FoxP3 or p_selectin has less than 10 cells in the image 3!
One or both of cellTypes FoxP3 or p_selectin has less than 10 cells in the image 4!
One or both of cellTypes FoxP3 or p_selectin has less than 10 cells in the image 5!
One or both of cellTypes FoxP3 or p_selectin has less than 10 cells in the image 8!
One or both of cellTypes FoxP3 or FoxP3 has less than 10 cells in the image 0!
One or both of cellTypes FoxP3 or FoxP3 has less than 10 cells in the image 3!
One or both of cellTypes FoxP3 or FoxP3 has less than 10 cells in the image 4!
One or both of cellTypes FoxP3 or FoxP3 has less than 10 cells in the image 5!
One or both of cellTypes FoxP3 or FoxP3 has less than 10 cells in the image 8!
One or both of cellTypes FoxP3 or immune has less than 10 cells in the image 0!
One or both of cellTypes FoxP3 or immune has less than 10 cells in the image 1!
One or both of cellTypes FoxP3 or immune has less than 10 cells in the image 2!
One or both of cellTypes FoxP3 or immune has less than 10 cells in the image 3!
One or both of cellTypes FoxP3 or immune has less than 10 cells in the image 4!
One or both of cellTypes FoxP3 or immune has less than 10 cells in the image 5!
One or both of cellTypes FoxP3 or immune has less than 10 cells in the image 8!
One or both of cellTypes immune or beta_catenin has less than 10 cells in the image 0!
One or both of cellTypes immune or beta_catenin has less than 10 cells in the image 1!
One or both of cellTypes immune or beta_catenin has less than 10 cells in the image 2!
One or both of cellTypes immune or beta_catenin has less than 10 cells in the image 3!
One or both of cellTypes immune or beta_catenin has less than 10 cells in the image 4!
One or both of cellTypes immune or beta_catenin has less than 10 cells in the image 5!
One or both of cellTypes immune or beta_catenin has less than 10 cells in the image 8!
One or both of cellTypes immune or CD4 has less than 10 cells in the image 0!
One or both of cellTypes immune or CD4 has less than 10 cells in the image 1!
One or both of cellTypes immune or CD4 has less than 10 cells in the image 2!
One or both of cellTypes immune or CD4 has less than 10 cells in the image 3!
One or both of cellTypes immune or CD4 has less than 10 cells in the image 4!
One or both of cellTypes immune or CD4 has less than 10 cells in the image 5!
One or both of cellTypes immune or CD4 has less than 10 cells in the image 8!
One or both of cellTypes immune or CD20 has less than 10 cells in the image 0!
One or both of cellTypes immune or CD20 has less than 10 cells in the image 1!
One or both of cellTypes immune or CD20 has less than 10 cells in the image 2!
One or both of cellTypes immune or CD20 has less than 10 cells in the image 3!
One or both of cellTypes immune or CD20 has less than 10 cells in the image 4!
One or both of cellTypes immune or CD20 has less than 10 cells in the image 5!
One or both of cellTypes immune or CD20 has less than 10 cells in the image 8!
One or both of cellTypes immune or CD8 has less than 10 cells in the image 0!
One or both of cellTypes immune or CD8 has less than 10 cells in the image 1!
One or both of cellTypes immune or CD8 has less than 10 cells in the image 2!
One or both of cellTypes immune or CD8 has less than 10 cells in the image 3!
One or both of cellTypes immune or CD8 has less than 10 cells in the image 4!
One or both of cellTypes immune or CD8 has less than 10 cells in the image 5!
One or both of cellTypes immune or CD8 has less than 10 cells in the image 8!
One or both of cellTypes immune or CD11b has less than 10 cells in the image 0!
One or both of cellTypes immune or CD11b has less than 10 cells in the image 1!
One or both of cellTypes immune or CD11b has less than 10 cells in the image 2!
One or both of cellTypes immune or CD11b has less than 10 cells in the image 3!
One or both of cellTypes immune or CD11b has less than 10 cells in the image 4!
One or both of cellTypes immune or CD11b has less than 10 cells in the image 5!
One or both of cellTypes immune or CD11b has less than 10 cells in the image 8!
One or both of cellTypes immune or CD68 has less than 10 cells in the image 0!
One or both of cellTypes immune or CD68 has less than 10 cells in the image 1!
One or both of cellTypes immune or CD68 has less than 10 cells in the image 2!
One or both of cellTypes immune or CD68 has less than 10 cells in the image 3!
One or both of cellTypes immune or CD68 has less than 10 cells in the image 4!
One or both of cellTypes immune or CD68 has less than 10 cells in the image 5!
One or both of cellTypes immune or CD68 has less than 10 cells in the image 8!
One or both of cellTypes immune or collagen has less than 10 cells in the image 0!
One or both of cellTypes immune or collagen has less than 10 cells in the image 1!
One or both of cellTypes immune or collagen has less than 10 cells in the image 2!
One or both of cellTypes immune or collagen has less than 10 cells in the image 3!
One or both of cellTypes immune or collagen has less than 10 cells in the image 4!
One or both of cellTypes immune or collagen has less than 10 cells in the image 5!
One or both of cellTypes immune or collagen has less than 10 cells in the image 6!
One or both of cellTypes immune or collagen has less than 10 cells in the image 8!
One or both of cellTypes immune or p_selectin has less than 10 cells in the image 0!
One or both of cellTypes immune or p_selectin has less than 10 cells in the image 1!
One or both of cellTypes immune or p_selectin has less than 10 cells in the image 2!
One or both of cellTypes immune or p_selectin has less than 10 cells in the image 3!
One or both of cellTypes immune or p_selectin has less than 10 cells in the image 4!
One or both of cellTypes immune or p_selectin has less than 10 cells in the image 5!
One or both of cellTypes immune or p_selectin has less than 10 cells in the image 8!
One or both of cellTypes immune or FoxP3 has less than 10 cells in the image 0!
One or both of cellTypes immune or FoxP3 has less than 10 cells in the image 1!
One or both of cellTypes immune or FoxP3 has less than 10 cells in the image 2!
One or both of cellTypes immune or FoxP3 has less than 10 cells in the image 3!
One or both of cellTypes immune or FoxP3 has less than 10 cells in the image 4!
One or both of cellTypes immune or FoxP3 has less than 10 cells in the image 5!
One or both of cellTypes immune or FoxP3 has less than 10 cells in the image 8!
One or both of cellTypes immune or immune has less than 10 cells in the image 0!
One or both of cellTypes immune or immune has less than 10 cells in the image 1!
One or both of cellTypes immune or immune has less than 10 cells in the image 2!
One or both of cellTypes immune or immune has less than 10 cells in the image 3!
One or both of cellTypes immune or immune has less than 10 cells in the image 4!
One or both of cellTypes immune or immune has less than 10 cells in the image 5!
One or both of cellTypes immune or immune has less than 10 cells in the image 8!

Plot Ripley’s statistics graphs

Key parameters are:

1). a celltype-celltype comparison

2). the stat to plot (K, L, or g)

3). whether to include an f values panel (if not None).  Can plot the f statistic, or (adjusted) p-values for an ANOVA performed at each radii.

For other parameters, see API documentation.

The f-statistics panel is quite useful for examining at which radii distance a given celltype pair have the most significant difference in association between conditions. This is particularly useful when the functional ANOVA shows a statistically significant difference between the conditions, as functional ANOVA does not given information as to what distance is the most important for that significant difference.

[21]:
plot = space_analysis.plot_spaceANOVA_function(
                                 stat = 'g',
                                 comparison = "beta_catenin___FoxP3",
                                 seed = 42,
                                 f_stat = 'f',
                                 hline = 1,
                                 output_directory = None)
../../_images/notebooks_CoreImagingPipeline_SpatialAnalysis_28_0.png
[22]:
''' Note how only one condition has a curve and not f values -- this is because the other condition did not pass
the cell threshold in any of its images for the collagen celltype. This also why the "immune" cell type is not
present in the functional ANOVA results.


'''

figure = space_analysis.plot_spaceANOVA_function(comparison = "beta_catenin___immune", seed = 42, stat = 'K', f_stat = 'f', hline = 1)
One of the celltype in this comparison -- beta_catenin___immune -- is only present in one condition! Will not plot f statistic!
../../_images/notebooks_CoreImagingPipeline_SpatialAnalysis_29_1.png

Run Functional ANOVAs

Running the functional ANOVA after the Ripley’s statistics are calculated is fairly straightforward:

1). Choose the Ripley statistic to use (usually g)

2). Choose a random seed (default = the seed selected when runinng the Ripley's statistics). This is needed because the functional ANOVA itself (oneway_anova from the scikit-fda library) needs a seed.

When completed, a set of three dataframes are made (one for the three statistics: adjusted pvalue, pvalue, and statistic). The p value adjustment is by the Benjamini-Hochberg False Discovery Rate correction for multiple comparisons.

The statistic (fstat) is the sampling statistic outputted by the functional ANOVA – its significance is not the same as the f statistic in a traditional ANOVA (its value does not correspond with the p value as far as I can tell). I export it here for completeness, in case experts in this statistical test may find it useful.

[23]:
padj, p, stat = space_analysis.run_SpaceANOVA_statistics('g', 42)
padj
[23]:
beta_catenin CD4 CD20 CD8 CD11b CD68 collagen p_selectin FoxP3
beta_catenin 0.7652 0.8189 0.8381 0.6834 0.5909 0.5909 0.7997 0.8189 0.8768
CD4 0.8189 0.8189 0.6831 0.5909 0.5909 0.7997 0.5909 0.8189 0.5909
CD20 0.9030 0.6849 0.7391 0.6831 0.8189 0.8189 0.7652 0.5909 0.7391
CD8 0.7380 0.5909 0.6834 0.8189 0.8494 0.5909 0.7997 0.7336 0.5909
CD11b 0.5909 0.5909 0.8189 0.8494 0.8319 0.7901 0.5909 0.7391 0.7391
CD68 0.5909 0.8189 0.8189 0.5909 0.7901 0.5909 0.6831 0.8650 0.8189
collagen 0.7997 0.5909 0.7652 0.7901 0.5909 0.6831 0.6849 0.6831 0.8189
p_selectin 0.8189 0.8189 0.5909 0.6831 0.7391 0.8189 0.6831 0.7901 0.5909
FoxP3 0.8756 0.5909 0.7391 0.5909 0.7391 0.8189 0.8189 0.6269 0.7391
[24]:
space_analysis.plot_spaceANOVA_heatmap('p', filename = "SpaceANOVA_heatmap")
[24]:
../../_images/notebooks_CoreImagingPipeline_SpatialAnalysis_32_0.png

Spatial Euclidean Distance Transform

Calculate the distance from each mask to a particular pixel classification. This is done by calculating a euclidean distance transfrom (edt) for each pixel class in a pixel classifier’s output, then calculating a summary statistic from the mask regions on the edt map (just like calculating the region measurements for any of the traditional channels in an image).

This derives a value of the average or minimum distance from the pixel class for every cell in the dataset, which can be added to the data as if it was another channel, with its own marker_class.

Important parameters:

1). & 2). pixel classification and masks folders

3). smoothing -- if > 0, used to remove isolated instances of pixel classes. If used, this is intended to reduce the effect of extremely small regions of the pixel class, by removing many of those regions
The smoothing applied is similar to the smoothing available when training/predicting from an unsupervised classifier

4). stat -- what aggregate statistic to use when measuring from cell regions. Usually either "mean" for average distance or "min" for minimum distance from cells to the pixel class
"median" is also possible.

5). normalized (only used if stat is 'mean' or 'median') -- whether to divide the average of the cell by the average of the entire image that it is in. This helps control for when a pixel class is
much more abundant in one image vs. another.

6). background -- whether to include background as one of the pixel classes to calculate edt values for. Default = False, but sometimes (like this case) the background class is associate
with a meaningful biological label.

7). marker_class -- what marker_class to associate with this antigen (see Analysis_panel or Analysis.data.var to see the usual marker_classes: type,state, none). If there are more than one pixel class in a classifier's output, they will all be given the same marker_class (whatever is provided here). The default is 'spatial_edt' because usually you will want to plot the edt values separately from the traditional antigen markers. Additionally, the plotting / statistics methods for edt data that will be shown immediately after this are, by default, specific to this 'spatial_edt' marker_class.
    However, as an example of alternate marker_class: you could choose a marker_class of 'type' and then use the edt values A). as part of cell clustering with FlowSOM and B). plot the edt values in the same plots as the traditional markers that are also of the same 'type' marker_class.

It is possible to load more than one edt from more than one pixel classifier’s outputs. If the classes should be strictly non-overlapping (as is the case here), than one pixel classifier should be enough. However, if each pixel class could overlap – for example, if each class is meant to represent the distance to a different Extracellular Matrix protein, and these proteins can coexist in the same location in the tissue – then it is better to make individual classifiers for each target class, and then load the edt data for each one-by-one by calling the do_edt method for each.

[25]:
''' Because I dropped cells for spaceANOVA, I will now reload the experiment to restore the dropped cells '''

''' To reload, create  a new Analysis in the same directory and repeat any scaling / cluster loading steps '''
Analysis_experiment = pbug.Analysis()
Analysis_experiment.load_data(ImageAnalysis.directory_object.Analysis_internal_dir)

merging_name = 'merging'
Analysis_experiment.do_scaling("%quantile")    ## loading a saved clustering requires that the data matches, so the scaling of the data when the annotation was saved needs to be applied before loading the data.
                                               ## The data scaling can be changed after loading the clustering
Analysis_experiment.load_clustering(ImageAnalysis.directory_object.Analysis_internal_dir + f"/clusterings/{merging_name}.csv")

'''Then connect the SpatialAnalysis object to the new Analysis '''
space_analysis.add_Analysis(Analysis_experiment)
[26]:
space_analysis.do_edt(pixel_classifier_folder = f"{project_directory}/Pixel_Classification/lumen_epithelia_laminapropria",
                        masks_folder = f"{project_directory}/masks/example_deepcell_masks", ## again, this is used for replicability with masks
                        smoothing = 10,
                        stat = 'mean',
                        normalized = True,
                        background = True,    ## because for this classifier background represents something ('lumen'). Set to False by default
                        marker_class = 'spatial_edt')
[26]:
(                                          fcs_colnames  \
 antigen
 distance to background          distance to background
 distance to epithelia            distance to epithelia
 distance to lamina_propria  distance to lamina_propria

                                                antigen marker_class
 antigen
 distance to background          distance to background  spatial_edt
 distance to epithelia            distance to epithelia  spatial_edt
 distance to lamina_propria  distance to lamina_propria  spatial_edt  ,
        distance to background  distance to epithelia  \
 0                    1.928277               2.282109
 1                    0.317124               0.020194
 2                    2.628931               2.553191
 3                    0.643616               0.000000
 4                    0.951623               0.000000
 ...                       ...                    ...
 36922                1.324805               1.075706
 36923                2.249863               1.017674
 36924                2.467552               0.788239
 36925                2.633600               0.684937
 36926                3.105019               0.942029

        distance to lamina_propria
 0                        0.000000
 1                        0.591028
 2                        0.000000
 3                        2.064327
 4                        2.078905
 ...                           ...
 36922                    0.000000
 36923                    0.000000
 36924                    0.000000
 36925                    0.000000
 36926                    0.000000

 [36927 rows x 3 columns])
[27]:
''' Remember that higher values on the boxplot indicates further distances from the pixel class  '''

space_analysis.plot_edt_boxplot('distance to epithelia', filename = "EDT_boxplot")
C:\Users\benca\miniforge3\envs\main\lib\site-packages\seaborn\categorical.py:700: PendingDeprecationWarning: vert: bool will be deprecated in a future version. Use orientation: {'vertical', 'horizontal'} instead.
  artists = ax.bxp(**boxplot_kws)
C:\Users\benca\miniforge3\envs\main\lib\site-packages\seaborn\categorical.py:700: PendingDeprecationWarning: vert: bool will be deprecated in a future version. Use orientation: {'vertical', 'horizontal'} instead.
  artists = ax.bxp(**boxplot_kws)
[27]:
../../_images/notebooks_CoreImagingPipeline_SpatialAnalysis_36_1.png
[28]:
''' This plotting method depends on there being >1 set of edt values loaded, and will throw an error if there is only 1!  '''

space_analysis.plot_edt_heatmap('merging', filename = "EDT_heatmap")
[28]:
../../_images/notebooks_CoreImagingPipeline_SpatialAnalysis_37_0.png
[29]:
''' This just runs a basic ANOVA / or Kruskal-Wallis test comparing the aggregated edt distributions in ROIs between the conditions in the data.
As in, it takes the mean or median of the edt values for each celltype in each image, and then uses the distribution of those averages per celltype
to run a statistical test between the two conditions.

By default, it uses the mean to aggregate and runs an ANOVA test.
'''

space_analysis.run_edt_statistics('merging', filename = "edt_stats")
[29]:
antigen merging p_value p_adj F statistic avg SSA mean exprs SSA avg stdev avg TA mean exprs TA avg stdev
28 distance to lamina_propria CD11b 0.003457 0.1452 16.780000 0.005380 0.005380 0.019760 0.005531
17 distance to epithelia CD32b 0.023350 0.3413 7.816000 0.146400 0.027790 0.189300 0.015050
27 distance to epithelia p_selectin 0.035150 0.3413 6.410000 0.118600 0.016680 0.150700 0.023740
22 distance to epithelia beta_catenin 0.037460 0.3413 6.205000 0.009471 0.007083 0.020130 0.005792
24 distance to epithelia discard 0.041040 0.3413 5.917000 0.132700 0.023480 0.200700 0.063950
30 distance to lamina_propria CD31 0.048750 0.3413 5.393000 0.006522 0.009925 0.057200 0.053710
16 distance to epithelia CD31 0.069790 0.3723 4.377000 0.131900 0.048720 0.214600 0.077700
34 distance to lamina_propria CD8 0.071030 0.3723 4.330000 0.031260 0.018360 0.011760 0.000546
14 distance to epithelia CD11b 0.088110 0.3723 3.770000 0.141000 0.014960 0.183300 0.051620
40 distance to lamina_propria immune 0.091560 0.3723 3.674000 0.013310 0.024800 0.050710 0.037570
35 distance to lamina_propria FoxP3 0.097510 0.3723 3.519000 0.013120 0.014090 0.029210 0.011830
31 distance to lamina_propria CD32b 0.117700 0.3984 3.072000 0.003797 0.003718 0.014890 0.015280
23 distance to epithelia collagen 0.123300 0.3984 2.967000 0.152100 0.017560 0.114800 0.049920
26 distance to epithelia immune 0.148900 0.4467 2.551000 0.050280 0.063130 0.104300 0.026210
37 distance to lamina_propria collagen 0.172100 0.4819 2.249000 0.005255 0.007287 0.051950 0.078210
8 distance to background beta_catenin 0.239100 0.6258 1.618000 0.087030 0.026010 0.107500 0.022950
10 distance to background discard 0.253300 0.6258 1.516000 0.142000 0.052990 0.182300 0.046520
32 distance to lamina_propria CD4 0.279200 0.6260 1.347000 0.005667 0.003532 0.003300 0.002411
4 distance to background CD4 0.294900 0.6260 1.256000 0.168800 0.037610 0.194000 0.029750
2 distance to background CD31 0.298100 0.6260 1.238000 0.152600 0.054460 0.191100 0.052230
36 distance to lamina_propria beta_catenin 0.315400 0.6293 1.147000 0.146700 0.113100 0.082980 0.036870
25 distance to epithelia e_cadherin 0.337600 0.6293 1.040000 0.034850 0.045140 0.068190 0.058660
39 distance to lamina_propria e_cadherin 0.344600 0.6293 1.009000 0.079440 0.076550 0.168100 0.200300
9 distance to background collagen 0.428800 0.7504 0.694600 0.187700 0.067930 0.154800 0.048110
18 distance to epithelia CD4 0.479700 0.7814 0.549600 0.162900 0.038860 0.184300 0.053040
41 distance to lamina_propria p_selectin 0.483700 0.7814 0.539200 0.012390 0.013190 0.018500 0.012390
29 distance to lamina_propria CD20 0.519600 0.7974 0.453600 0.013130 0.009893 0.009385 0.005880
7 distance to background FoxP3 0.532800 0.7974 0.424900 0.111100 0.078050 0.139000 0.039220
15 distance to epithelia CD20 0.550600 0.7974 0.388200 0.148500 0.055550 0.168600 0.038760
0 distance to background CD11b 0.608300 0.8428 0.284500 0.154900 0.060270 0.172000 0.023020
1 distance to background CD20 0.622100 0.8428 0.262700 0.186200 0.056700 0.170100 0.031290
33 distance to lamina_propria CD68 0.642500 0.8433 0.232600 0.002411 0.002903 0.003831 0.006432
11 distance to background e_cadherin 0.673100 0.8524 0.191700 0.083460 0.026840 0.063190 0.111800
21 distance to epithelia FoxP3 0.690000 0.8524 0.171100 0.104200 0.060070 0.119800 0.056020
5 distance to background CD68 0.739700 0.8876 0.118400 0.196600 0.059150 0.185900 0.018170
19 distance to epithelia CD68 0.767900 0.8959 0.093260 0.159100 0.026660 0.152000 0.047440
20 distance to epithelia CD8 0.855300 0.9709 0.035480 0.146600 0.134000 0.133600 0.024580
3 distance to background CD32b 0.905600 0.9718 0.014990 0.192500 0.038100 0.195300 0.032030
6 distance to background CD8 0.908900 0.9718 0.013960 0.182600 0.124400 0.175100 0.013700
13 distance to background p_selectin 0.939000 0.9718 0.006231 0.160600 0.066640 0.157900 0.015370
12 distance to background immune 0.957800 0.9718 0.002974 0.145400 0.156100 0.140900 0.057410
38 distance to lamina_propria discard 0.971800 0.9718 0.001331 0.024800 0.020890 0.025260 0.016790
[ ]: