大多数文章在进行空间转录组细胞可视化的时候,通常会使用 square bin 或是 cellbin,但是究其展示本质,其实还是 square bin,比如下面的这种,每个细胞的呈现形式是一个 spot_size 固定为某个值的点。

20240116172928

但是有的文章的可视化就做的非常好,每个细胞不仅能够显示细胞形态,也能够显示细胞类型,比如这一种:

20240116174324

那这样子的效果要如何绘制呢?我的理解是每个细胞的label,对应圈细胞结果上的一群细胞覆盖的像素点,然后这些像素点都被打上细胞label,对圈细胞结果分析之后,可视化的时候,把每个细胞对应的label的像素点绘制上不同的颜色。

代码如下所示

import scanpy as sc
import pandas as pd
import anndata as ad
from scipy.sparse import csr_matrix
import numpy as np
import numpy as np
from PIL import Image

# 这里的 cellbin 是你用来分析的 cellbin 数据,甚至迁移了细胞类型的数据
cellbin = ad.read('/data/work/07.3d/Result/Spateo/0112/slices/20.h5ad')

'''
AnnData object with n_obs × n_vars = 19415 × 17887
    obs: 'area', 'x', 'y', 'region', 'n_counts', 'slices', 'batch', 'celltype', 'celltype_main', 'celltype_main_sub', 'z'
    uns: 'celltype_colors', 'celltype_main_colors', 'celltype_main_sub_colors', 'data_unit', 'region_colors'
    obsm: '3d_align_spatial', '3d_align_spatial_confine', 'Nonrigid_align_spatial', 'Rigid_align_spatial', 'X_umap', 'align_spatial', 'bbox', 'spatial'
'''

# 我的 cellbin index 做一下预处理,大部分人不需要
cellbin.obs.index = [i.split('-')[0] for i in cellbin.obs.index.tolist()]

# 使用 spateo 圈细胞的时候的中间 label 文件
adata = ad.read('/data/work/01.Cellbin/02.Result/20/0804/Slice_20_labeled.h5ad')
'''
AnnData object with n_obs × n_vars = 14162 × 15326
    uns: '__type', 'pp', 'spatial'
    layers: 'augment_labels', 'augmented_labels_expanded', 'stain', 'stain_distances', 'stain_markers', 'stain_mask', 'watershed_labels'
'''
# layer 中的 augmented_labels_expanded 是我来圈细胞的 layer,接下来就会用这个作为我画 single cell 图的图片底板

# 取出图片底板
image = adata.layers['augmented_labels_expanded'].copy()

# 清除内存
del adata

# 查询 image 中的细胞数目
uni = np.unique(image)

# image_g 为在 cellbin 中的细胞 index
image_g = []
for i in uni:
    if str(i) in cellbin.obs.index:
        continue
    else:
        image_g.append(i)

# 将不在  cellbin 中的细胞的值归为 0 
control = np.isin(image, image_g)
control = ~control
image = np.where(control, image, 0)

# 重新计数
new_uni = np.unique(image)
dic = {}

# 防止乱码
k = max(new_uni)+1
for i in set(cellbin.obs['celltype']):
    dic[i] = k
    k+=1
    
index = [int(i) for i in cellbin.obs.index.tolist()]

# 你用来存储你的 每一个细胞类型的 color 的地方
color = list(set(cellbin.uns['celltype_colors']))

# 转换器
def Hex_to_RGB(hex):
    r = int(hex[1:3],16)
    g = int(hex[3:5],16)
    b = int(hex[5:7], 16)
    rgb = (r,g,b)
    return rgb

# 着色 dict
color_dict = {
    0: (0, 0, 0),       # 黑色
}
for i,index in enumerate(dic):
    color_dict[dic[index]] = Hex_to_RGB(color[i])

# 进行着色
for i in cellbin.obs.index:
    region = cellbin.obs.loc[i].celltype
    reigon_id = dic[region]
    image[image==int(i)] = reigon_id

height, width = image.shape
image_data = np.zeros((height, width, 3), dtype=np.uint8)

# 根据字典中的映射将数组中的值转换为RGB颜色
for value, color in color_dict.items():
    image_data[image == value] = color

# 创建图像
image_save = Image.fromarray(image_data)

# 保存图像
image_save.save('/data/work/07.3d/Script/0116/2.png')