Add & plot cell type annotation to spatialdata

Hello,
I have a xenium spatialdata object. I have a dataframe with cell types annotation (a column with a cell id, and a column with a cell type). The cell id in my dataframe is the same than the cell id in my shapes.
I would like to integrate this cell type information in my spatialdata object, and display it when I plot shapes (I want to have my 4 different cell types to be plotted with different colors). This is not explained in the spatialdata_plot tutorial, does someone know how to do that ?

Thanks a lot

Hi Max,

to accomplish the task that you described I suggest to have a look at this notebook, which showcases how to manage annotations: Working with annotations in SpatialData — spatialdata.

Please let me know if you have more follow up questions after this :blush:

Hi,
Thank you for your answer. I am sorry, but this tutorial is a bit messy regarding annotation, and I couldn’t find any working solution. It is really difficult to iterate over cell types annotation and visualize them.

In the tutorial, they give a specific color to a polygon by adding a column “color” in the spatialdata.shapes. This is a very easy solution, but it seems that the color given can only be an int; and whatever int is given, colors plotted are the same colors, in a gradient between blue and yellow. It makes very difficult to vizualize different cell types, since all colors are close to each other. Do you know if an other way exists ? For now I have to use Seurat on R to have a good vizualisation of celltypes…
Thank you very much,
Max

Thank you for checking the tutorial. Please if you could you be more explicit regarding why you find the tutorial messy; I will be happy to improve it if you have some suggestions.

Regarding the problem that you described, the annotation can be set either in the column of the dataframe either in an associated table; the type can be both numerical or categorical. The coloring is shown in a blue to yellow colormap because the values are specified as numerical; converting the column to a categorical would fix the issue.

I prepared this small example to show this, I hope it will help with your use case.

##
import spatialdata_plot
import matplotlib.pyplot as plt

from spatialdata.datasets import blobs_annotating_element
from spatialdata.models import TableModel
from anndata import AnnData
import pandas as pd

sdata = blobs_annotating_element("blobs_polygons").subset(["blobs_polygons"])
print(sdata)

##
# plotting the data without annotations
sdata.pl.render_shapes("blobs_polygons").pl.show()
plt.show()

##
# defining the annotations
celltype_dataframe = pd.DataFrame(
    {
        "cell_type": ["A", "B", "C", "A", "B"],
        "cell_id": sdata["blobs_polygons"].index,
    }
)

##
# option 1: merge the dataframe with the existing table
sdata["table"].obs = pd.merge(
    sdata["table"].obs, celltype_dataframe, left_on="instance_id", right_on="cell_id", how="left"
)

##
sdata.pl.render_shapes("blobs_polygons", color='cell_type').pl.show()
plt.show()

##
# option 2: add a new table
celltype_dataframe["region"] = ["blobs_polygons"] * 5
celltype_dataframe['cluster_id'] = [1, 1, 3, 2, 2]

annotations = AnnData(obs=celltype_dataframe)
annotations = TableModel.parse(annotations, region="blobs_polygons", region_key="region", instance_key="cell_id")
sdata["annotations"] = annotations
print(sdata)

##
# let's specify the table_name explicity (this should not be needed but there is a bug
# https://github.com/scverse/spatialdata-plot/issues/268)
sdata.pl.render_shapes("blobs_polygons", color="cluster_id", table_name='annotations').pl.show()
plt.show()

##
# the above plot was not showing categories because the column is numerical. To see categories we need to explicitly
# convert the dtype
sdata["annotations"].obs["cluster_id"] = sdata["annotations"].obs["cluster_id"].astype("category")
sdata.pl.render_shapes("blobs_polygons", color="cluster_id", table_name='annotations').pl.show()
plt.show()

Please let me know if you have questions on the example.