当前位置:首页>python>Xenium 空转数据实战|全流程Python分析

Xenium 空转数据实战|全流程Python分析

  • 2026-07-04 02:09:11
Xenium 空转数据实战|全流程Python分析

编者按

本期更新的是Xenium格式的全流程Python分析,我们将其整个流程都完整封装进了OmicVerse,希望对相关研究者有所帮助。

需要注意的是,本文里的可视化函数不支持通过squidpy,spatialdata方式读取的nanostring数据。

steorra

10x Genomics Xenium 是这两年用得越来越多的一类高分辨率空间转录组平台。它和传统 spot 级技术最大的区别,不是“分辨率更高”这句空话,而是数据结构真的变了。你拿到手的不只是一个表达矩阵,还会同时拿到细胞质心坐标、polygon 边界,以及形态学图像。

所以 Xenium 教程真正难的地方,从来都不只是“把数据读进来”。更现实的问题是:坐标有没有对上,分割边界靠不靠谱,最后算出来的聚类能不能放回组织里解释。

本教程以 10x 提供的公开数据集Xenium FFPE Human Breast Cancer Replicate 1为例,演示 OmicVerse 里一条比较顺手、也比较实用的 Xenium 工作流:

  1. 准备 Xenium 必需文件,并确认目录结构。
  2. ov.io.read_xenium()读入数据,检查坐标、metadata 和 polygon。
  3. 做基础细胞级 QC、标准化、降维和 Leiden 聚类。
  4. 先在整张切片上看聚类结果,再在局部区域检查真实细胞 polygon。
  5. 如果提供形态学图像,就把聚类和 marker 直接叠加回组织背景中。

你会发现,Xenium 和 CosMx、Visium HD 的分析思路有不少相通的地方,但它对“局部区域放大”和“图像配准检查”的依赖会更强。原因很简单:它天生就是带分割边界的单细胞空间数据。

1. 环境设置

这一部分主要完成三件事:导入omicverse、设置统一绘图风格,以及启用自动重载。

  • ov.style(font_path='Arial'):保证后续图像在不同机器上导出时风格尽量一致。
  • %autoreload 2:如果你在本地调试 OmicVerse 源码,重新运行单元时会自动加载修改后的模块。
  • Pathnumpy:后面分别用于路径组织和基础数值操作。
from pathlib import Path
import numpy as np
import omicverse as ov
ov.style(font_path='Arial')

%load_ext autoreload
%autoreload 2
🔬 Starting plot initialization...
Using already downloaded Arial font from: /tmp/omicverse_arial.ttf
Registered as: Arial
🧬 Detecting GPU devices…
✅ NVIDIA CUDA GPUs detected: 1
    • [CUDA 0] NVIDIA H100 80GB HBM3
      Memory: 79.1 GB | Compute: 9.0

   ____            _     _    __
  / __ \____ ___  (_)___| |  / /__  _____________
 / / / / __ `__ \/ / ___/ | / / _ \/ ___/ ___/ _ \
/ /_/ / / / / / / / /__ | |/ /  __/ /  (__  )  __/
\____/_/ /_/ /_/_/\___/ |___/\___/_/  /____/\___/

🔖 Version: 2.1.2rc1   📚 Tutorials: https://omicverse.readthedocs.io/
✅ plot_set complete.

和前面几篇教程一样,这里也会初始化 OmicVerse 的 CPU/GPU 混合运行模式。对 Xenium 这种十几万细胞量级的数据来说,后面的 PCA、邻接图和 Leiden 会更受益。

ov.settings.cpu_gpu_mixed_init()
CPU-GPU mixed mode activated
Available GPU accelerators: CUDA

2. 准备 Xenium 数据目录

这里使用的是 10x 官方公开的Xenium FFPE Human Breast Cancer Replicate 1。数据量不算小,大约 16.7 万个细胞、313 个基因,但正好适合拿来走一遍完整流程。

Xenium 的原始outs/目录通常挺大。除了计数矩阵和细胞 metadata,它还会附带边界文件和多通道形态学 OME-TIFF。真要动手分析时,你不用一上来就把所有文件都背下来。先记住最关键的几样就够了:

  • cell_feature_matrix.h5:细胞 × 基因计数矩阵。
  • cells.csv.gz:细胞级 metadata,包括质心坐标。
  • cell_boundaries.parquet:每个细胞的 polygon 边界。
  • experiment.xenium:实验 metadata。

如果你还想把聚类结果叠加到 DAPI / morphology 背景上,则需要额外下载morphology_focus.ome.tif

# !mkdir -p data/xenium_breast_rep1
# BASE='https://cf.10xgenomics.com/samples/xenium/1.0.1/Xenium_FFPE_Human_Breast_Cancer_Rep1'
# !wget -O data/xenium_breast_rep1/cell_feature_matrix.h5  $BASE/Xenium_FFPE_Human_Breast_Cancer_Rep1_cell_feature_matrix.h5
# !wget -O data/xenium_breast_rep1/cells.csv.gz            $BASE/Xenium_FFPE_Human_Breast_Cancer_Rep1_cells.csv.gz
# !wget -O data/xenium_breast_rep1/cell_boundaries.parquet $BASE/Xenium_FFPE_Human_Breast_Cancer_Rep1_cell_boundaries.parquet
# !wget -O data/xenium_breast_rep1/experiment.xenium       $BASE/Xenium_FFPE_Human_Breast_Cancer_Rep1_experiment.xenium
# 可选项:只有需要叠加形态学背景时才下载
# !wget -O data/xenium_breast_rep1/morphology_focus.ome.tif $BASE/Xenium_FFPE_Human_Breast_Cancer_Rep1_morphology_focus.ome.tif

正式读入前,先把目录树打印出来,这一步很值。Xenium 这种多文件拼起来的数据,很多问题其实都是路径问题。早点看清楚,省得后面报错了再倒回来找。

sample_dir = Path('data') / 'xenium_breast_rep1'
ov.utils.print_tree(sample_dir)
xenium_breast_rep1/
├── cell_boundaries.parquet
├── cell_feature_matrix.h5
├── cells.csv.gz
├── experiment.xenium
└── morphology_focus.ome.tif

3. 读取 Xenium 数据集

这里的核心入口是ov.io.read_xenium()。它做的事不只是“读矩阵”,而是把 Xenium 最关键的几类空间信息一起装进同一个AnnData

  • 计数矩阵来自cell_feature_matrix.h5
  • cells.csv.gz合并到obs
  • 细胞质心坐标写入obsm['spatial']
  • cell_boundaries.parquet被转换成 WKTPOLYGON字符串,存到obs['geometry']
  • experiment.xenium则进入uns['spatial'][library_id]['metadata']

这一步对 Xenium 特别重要。因为只要这些对象都被规整进同一个adata,后面很多事就会自然很多:整切片看全局,局部区域看 polygon,叠加形态学图像做检查,全都能接得上。

adata = ov.io.read_xenium(sample_dir, load_image=False)
adata
[Xenium] Reading Xenium data from: /scratch/users/steorra/xenium_test/breast_rep1
[Xenium] Loaded cell polygons (geometry WKT) for 167780/167780 cells
[Xenium] Done (n_obs=167780, n_vars=313, library_id=Replicate 1)
AnnData object with n_obs × n_vars = 167780 × 313
    obs: 'transcript_counts', 'control_probe_counts', 'control_codeword_counts', 'total_counts', 'cell_area', 'nucleus_area', 'geometry'
    var: 'gene_ids', 'feature_types', 'genome'
    uns: 'spatial', 'omicverse_io'
    obsm: 'spatial'

读完以后别急着往下跑。先打印几个关键量,确认三件事:

  • 当前样本的library_id
  • 细胞坐标在整张切片中的范围;
  • polygon 是否真的被成功写入。
library_id = next(iter(adata.uns['spatial']))
sf = adata.uns['spatial'][library_id]['scalefactors']
print('library_id          :', library_id)
print('spatial range (µm)  :',
      adata.obsm['spatial'].min(axis=0).tolist(), '->',
      adata.obsm['spatial'].max(axis=0).tolist())
print('pixel size (µm/px)  :'1 / sf['tissue_hires_scalef'])
print('mean cell diameter :', round(sf['spot_diameter_fullres'] / sf['tissue_hires_scalef'], 2), 'µm')
print('cells with geometry:', (adata.obs['geometry'] != '').sum())
library_id          : Replicate 1
spatial range (µm)  : [2.1325161457061768, 3.642256736755371] -> [7523.0869140625, 5474.37939453125]
pixel size (µm/px)  : 0.2125
mean cell diameter : 15.7 µm
cells with geometry: 164000

4. 在整张切片上做第一次空间 QC

在进入过滤和聚类之前,先别急。先对整张切片做一个整体预览。这里看两个最常用的量:

  • total_counts:每个细胞捕获到的总转录本数;
  • cell_area:细胞面积。

原因也很直接。对于肿瘤样本,计数通常会在肿瘤上皮区域更集中;而细胞面积往往能帮你很快区分更小的免疫细胞和更大的上皮细胞。如果这里看上去就不对劲,后面的聚类大概率也解释不通。

import matplotlib.pyplot as plt
fig, axs = plt.subplots(12, figsize=(125))
ov.pl.embedding(
    adata, basis='spatial', color='total_counts',
    vmax='p99', cmap='Reds', ax=axs[0], show=False, title='total_counts',
)
axs[0].invert_yaxis()
ov.pl.embedding(
    adata, basis='spatial', color='cell_area',
    vmax='p99', cmap='viridis', ax=axs[1], show=False, title='cell_area (µm²)',
)
axs[1].invert_yaxis()
plt.tight_layout()
先在整张组织上查看total_countscell_area的空间分布。

5. 做基础细胞级 QC

接下来做一个最基础的过滤:去掉转录本数太低的细胞。对 Xenium 来说,这类对象通常是分割伪影、边缘细胞,或者离背景太近的位置。

这里用10个 counts 作为一个比较温和的阈值。目的不是一步到位把 QC 做到极致,而是先把最明显异常的对象拿掉。真到项目里,你还是应该结合total_counts分布再细调。

import scipy.sparse as sp
counts = np.asarray(adata.X.sum(axis=1)).ravel() if sp.issparse(adata.X) else adata.X.sum(axis=1)
print(f'cells pre-QC : {adata.n_obs}')
adata = adata[counts >= 10].copy()
print(f'cells post-QC: {adata.n_obs} (>= 10 transcripts/cell)')
cells pre-QC : 167780
cells post-QC: 164000 (>= 10 transcripts/cell)

6. 标准化、对数变换与缩放

Xenium 这份 panel 一共只有 313 个基因,所以这里不再做 HVG 选择,而是直接把全部基因送进 PCA。整体预处理流程沿用单细胞里最常见的一套:

  1. normalize_total
  2. log1p
  3. scale

这里没什么花哨技巧,核心就是把数据整理到适合降维和图构建的状态。

ov.pp.normalize_total(adata, target_sum=1e4)
ov.pp.log1p(adata)
ov.pp.scale(adata)
🔍 Count Normalization:
   Target sum: 10000.0
   Exclude highly expressed: False

✅ Count Normalization Completed Successfully!
   ✓ Processed: 164,000 cells × 313 genes
   ✓ Runtime: 0.04s
╭─ SUMMARY: scale ───────────────────────────────────────────────────╮
│  Duration: 0.7115s                                                 │
│  Shape:    164,000 x 313 (Unchanged)                               │
│                                                                    │
│  CHANGES DETECTED                                                  │
│  ────────────────                                                  │
│  ● UNS    │ ✚ REFERENCE_MANU                                       │
│           │ ✚ status                                               │
│           │ ✚ status_args                                          │
│                                                                    │
│  ● LAYERS │ ✚ scaled (array, 164000x313)                           │
│                                                                    │
╰────────────────────────────────────────────────────────────────────╯

7. 计算 PCA、邻接图与 Leiden 聚类

这一段就是标准下游分析主线:先 PCA,再建邻接图,最后跑 Leiden。

对这个大小的 Xenium 切片来说,resolution=0.5一般会得到一个中等粒度的聚类结果。先拿它看组织 compartment 和主要细胞状态很合适。如果你想拆得更细,就继续调高;如果只想保留更粗的结构,就往下调。

ov.pp.pca(adata, layer='scaled', n_pcs=50)
ov.pp.neighbors(
    adata, n_neighbors=15,
    use_rep='scaled|original|X_pca', n_pcs=50,
)
ov.pp.leiden(adata, resolution=0.5)
print(f"leiden: {adata.obs['leiden'].nunique()} clusters")
🚀 Using GPU to calculate PCA...
NVIDIA CUDA GPUs detected:
📊 [CUDA 0] NVIDIA H100 80GB HBM3
    ------------------------------ 5/81559 MiB (0.0%)
computing PCA🔍
    with n_comps=50

Using CUDA device: NVIDIA H100 80GB HBM3
✅ Using built-in torch_pca for GPU-accelerated PCA
   🚀 Using torch_pca PCA for CUDA GPU acceleration
   🚀 torch_pca PCA backend: CUDA GPU acceleration (supports sparse matrices)
   📊 PCA input data type: ndarray, shape: (164000, 313), dtype: float64
   🔧 solver_used_in_uns (planned): covariance_eigh
🔧 PCA solver used: covariance_eigh
    finished✅ (0.56s)

╭─ SUMMARY: pca ─────────────────────────────────────────────────────╮
│  Duration: 0.5841s                                                 │
│  Shape:    164,000 x 313 (Unchanged)                               │
│                                                                    │
│  CHANGES DETECTED                                                  │
│  ────────────────                                                  │
│  ● UNS    │ ✚ pca                                                  │
│           │ └─ params: {'zero_center': True, 'use_highly_variable': Fa...│
│           │ ✚ scaled|original|cum_sum_eigenvalues                  │
│           │ ✚ scaled|original|pca_var_ratios                       │
│                                                                    │
│  ● OBSM   │ ✚ X_pca (array, 164000x50)                             │
│           │ ✚ scaled|original|X_pca (array, 164000x50)             │
│                                                                    │
╰────────────────────────────────────────────────────────────────────╯
🚀 Using torch CPU/GPU mixed mode to calculate neighbors...
NVIDIA CUDA GPUs detected:
📊 [CUDA 0] NVIDIA H100 80GB HBM3
    ------------------------------ 1487/81559 MiB (1.8%)
🚀 Mixed mode default transformer: pyg

🔍 K-Nearest Neighbors Graph Construction:
   Mode: cpu-gpu-mixed
   Neighbors: 15
   Method: torch
   Metric: euclidean
   Transformer: pyg
   Representation: scaled|original|X_pca
   PCs used: 50
   🔍 Computing neighbor distances...
   💡 Using PyTorch Geometric KNN on cuda
🔍 Computing connectivity matrix...
   💡 Using UMAP-style connectivity
✓ Graph is fully connected

✅ KNN Graph Construction Completed Successfully!
   ✓ Processed: 164,000 cells with 15 neighbors each
   ✓ Results added to AnnData object:
     • 'neighbors': Neighbors metadata (adata.uns)
     • 'distances': Distance matrix (adata.obsp)
     • 'connectivities': Connectivity matrix (adata.obsp)

╭─ SUMMARY: neighbors ───────────────────────────────────────────────╮
│  Duration: 12.3926s                                                │
│  Shape:    164,000 x 313 (Unchanged)                               │
│                                                                    │
│  CHANGES DETECTED                                                  │
│  ────────────────                                                  │
│  ● UNS    │ ✚ neighbors                                            │
│           │ └─ params: {'n_neighbors': 15, 'method': 'torch', 'random_...│
│                                                                    │
│  ● OBSP   │ ✚ connectivities (sparse matrix, 164000x164000)        │
│           │ ✚ distances (sparse matrix, 164000x164000)             │
│                                                                    │
╰────────────────────────────────────────────────────────────────────╯
⚙️ Using torch CPU/GPU mixed mode to calculate Leiden...
NVIDIA CUDA GPUs detected:
📊 [CUDA 0] NVIDIA H100 80GB HBM3
    |----------------------------- 2943/81559 MiB (3.6%)
Using batch size `n_batches` calculated from sqrt(n_obs): 404
Leiden:   0%|          | 0/10 [00:00<?, ?it/s]
L0 Batched(404):   0%|          | 0/100 [00:00<?, ?it/s]
L1 Batched(404):   0%|          | 0/100 [00:00<?, ?it/s]
L2 Batched(404):   0%|          | 0/100 [00:00<?, ?it/s]
L3 Batched(404):   0%|          | 0/100 [00:00<?, ?it/s]
╭─ SUMMARY: leiden ──────────────────────────────────────────────────╮
│  Duration: 158.7248s                                               │
│  Shape:    164,000 x 313 (Unchanged)                               │
│                                                                    │
│  CHANGES DETECTED                                                  │
│  ────────────────                                                  │
│  ● OBS    │ ✚ leiden (category)                                    │
│                                                                    │
│  ● UNS    │ ✚ leiden                                               │
│           │ └─ params: {'resolution': 0.5, 'random_state': 0, 'local_i...│
│                                                                    │
╰────────────────────────────────────────────────────────────────────╯
leiden: 20 clusters

8. 在整张切片尺度查看聚类与 marker

完成 Leiden 之后,先不要急着看局部 polygon。先回到整张切片上确认整体格局。这里同时画:

  • leiden:看大尺度空间 compartment;
  • 一个代表性 marker:看它和聚类分布是否大体一致。

这一步更像“导航图”。先把大方向看明白,后面你才知道该去放大哪一块。

marker = next((g for g in ['KRT7''EPCAM''ERBB2''ESR1''KRT14']
if g in adata.var_names), adata.var_names[0])

fig, axs = plt.subplots(12, figsize=(136))
ov.pl.embedding(
    adata, basis='spatial', color='leiden',
    palette=ov.pl.palette_112,
    legend_fontsize=8, ax=axs[0], show=False, title='Leiden clusters',
)
axs[0].invert_yaxis()
ov.pl.embedding(
    adata, basis='spatial', color=marker,
    vmax='p99.2', cmap='Reds', ax=axs[1], show=False, title=marker,
)
axs[1].invert_yaxis()
plt.tight_layout()
Leiden 聚类与 marker 基因可以先用质心散点方式做整体预览。

9. 在局部区域查看真实细胞 polygon

和 Visium HD 的 bin 视图不一样,Xenium 一个很值钱的地方,就是它天然带着细胞级 polygon。走到这一步,就不该只停留在质心散点图了,而要切到ov.pl.spatialseg()看真实分割边界。

不过这里有个很现实的限制:整张 16 万细胞切片的 polygon 如果一次性全画出来,图会又慢又挤,单个细胞几乎看不清。所以更合理的做法是:

  • 整切片层面,用ov.pl.embedding()看全局;
  • 局部区域,用ov.pl.spatialseg()看真实细胞边界。
ov.pl.spatialseg(
    adata, color='leiden',
    library_id=library_id,
    edges_color='white', edges_width=0.3,
    alpha=1.0, legend_fontsize=8,
    palette=ov.pl.palette_112,
    crop_coord=(2000320025003700),
    figsize=(76),
)
裁剪到局部区域后,ov.pl.spatialseg更适合观察真实细胞 polygon。

如果把同一块区域切换成 marker 着色,你就能更直观地判断:当前聚类边界和基因表达模式到底是不是一回事。很多时候,这一步比单独看表格更有说服力。

import numpy as np
expr = adata[:, marker].X.toarray().ravel() if hasattr(adata[:, marker].X, 'toarray'else np.asarray(adata[:, marker].X).ravel()
vmax_marker = float(np.percentile(expr[expr > 0], 99)) if (expr > 0).any() else1.0

ov.pl.spatialseg(
    adata, color=marker,
    library_id=library_id,
    edges_color='white', edges_width=0.3,
    alpha=1.0, legend_fontsize=8,
    cmap='Reds', vmax=vmax_marker,
    crop_coord=(2000320025003700),
    figsize=(76),
)
同一区域按 marker 着色后,可以直接检查表达与分割边界是否一致。

10. 如需底图,可叠加形态学图像

如果你已经下载了morphology_focus.ome.tif,下一步就可以把 Leiden 标签直接放回形态学背景里看。这里重新调用read_xenium(load_image=True),读取带图像版本的对象,再把已经算好的 Leiden 标签带过去。

这样做的好处很直接:不用为了加一张底图,就在带图像版本上重跑整条分析流程。

adata_img = ov.io.read_xenium(sample_dir, load_image=True)
adata_img.obs['leiden'] = adata.obs['leiden']   # carry over labels
ov.pl.spatialseg(
    adata_img, color='leiden', library_id=library_id,
    alpha_img=0.5, alpha=0.8,
    palette=ov.pl.palette_112,
    crop_coord=(2000320025003700),
)

对于 Xenium 这类大图像样本,一个经验非常重要:无论你是看聚类还是 marker,都优先用crop_coord放大局部区域,而不是直接在整张背景图上硬画全部 polygon。

11. 保存处理后的对象

分析完成后,把当前AnnData直接写盘保存。下次再打开时,就可以跳过前面的读入、QC 和聚类步骤,直接进入可视化或下游分析。

adata.write('data/xenium_breast_rep1_processed.h5ad')
# adata = ov.read('data/xenium_breast_rep1_processed.h5ad')

12. 用缓存加速重复读取

Xenium 还有一个很适合做工程优化的点:第一次读取时,read_xenium()不只是读矩阵,还要把cells.csv.gzcell_boundaries.parquet和实验 metadata 一起组装进AnnData,其中 polygon 的 WKT 构建会花掉一部分时间。

所以,如果你会反复重开 notebook 或来回调图,最好直接用cache_file=写一个缓存版 h5ad。后面再读同一个缓存文件时,速度通常会快很多。

import time, os

cache_path = 'data/xenium_breast_rep1_cache.h5ad'
if os.path.exists(cache_path):
    os.remove(cache_path)  # 为了展示时间差异,这里先删除旧缓存

t0 = time.time()
_ = ov.io.read_xenium(sample_dir, load_image=False, cache_file=cache_path)
t_cold = time.time() - t0

t0 = time.time()
_ = ov.io.read_xenium(sample_dir, cache_file=cache_path)
t_warm = time.time() - t0

print(f'cold (raw parse + cache write): {t_cold:.2f} s')
print(f'warm (cache read)              : {t_warm:.2f} s')
print(f'speedup                        : {t_cold / t_warm:.1f}x')
[Xenium] Reading Xenium data from: /scratch/users/steorra/xenium_test/breast_rep1
[Xenium] Loaded cell polygons (geometry WKT) for 167780/167780 cells
[Xenium] Wrote cache AnnData to: /scratch/users/steorra/analysis/omicverse_dev/omicverse/omicverse_guide/docs/Tutorials-space/data/xenium_breast_rep1_cache.h5ad
[Xenium] Done (n_obs=167780, n_vars=313, library_id=Replicate 1)
[Xenium] Reading cached AnnData from: /scratch/users/steorra/analysis/omicverse_dev/omicverse/omicverse_guide/docs/Tutorials-space/data/xenium_breast_rep1_cache.h5ad
cold (raw parse + cache write): 9.70 s
warm (cache read)              : 0.27 s
speedup                        : 35.9x

13. 把聚类结果真正放回形态学背景中

前面的load_image=True只是说明 Xenium 可以带底图读入。这里再往前走一步,真正把聚类和 marker 叠加回形态学图像里,看空间结果是不是和组织结构对得上。

对 Xenium 来说,这一步往往比单纯看 UMAP 或数值表格更重要。因为你最后真正想回答的,通常不是“分成了几个群”,而是“这些群在组织里到底在哪儿,边界合不合理,和形态学有没有对应关系”。

# 一次性调用:读取图像、组装完整 AnnData,并把结果写入缓存
adata_img = ov.io.read_xenium(
    sample_dir,
    load_image=True,
    image_max_dim=4096,
    cache_file='data/xenium_breast_rep1_with_image_cache.h5ad',
)
# 把已经处理好的 adata 中的 Leiden 标签带过来,
# 这样无需在带图像版本上重新跑整条分析流程。
adata_img = adata_img[adata.obs_names].copy()
adata_img.obs['leiden'] = adata.obs['leiden'].values
img = adata_img.uns['spatial'][library_id]['images']['hires']
sf  = adata_img.uns['spatial'][library_id]['scalefactors']
print('image shape     :', img.shape, 'dtype:', img.dtype)
print('hires_scalef    :', round(sf['tissue_hires_scalef'], 4),
'(micron -> image-pixel)')
print('fullres diameter:', round(sf['spot_diameter_fullres'], 2), 'px')
[Xenium] Reading cached AnnData from: /scratch/users/steorra/analysis/omicverse_dev/omicverse/omicverse_guide/docs/Tutorials-space/data/xenium_breast_rep1_with_image_cache.h5ad
image shape     : (1611, 2213) dtype: uint16
hires_scalef    : 0.2941 (micron -> image-pixel)
fullres diameter: 4.62 px

下面这几张图的读法其实很简单:

  • 先看 Leiden 和组织结构是否大体对得上;
  • 再看 marker 和局部组织状态是否一致;
  • 最后用轮廓线叠加 DAPI,检查 polygon 和细胞核是否真正配准。
ov.pl.spatialseg(
    adata_img, color='leiden',
    library_id=library_id,
    edges_color='white', edges_width=0.4,
    alpha=0.45, alpha_img=1.0,
    legend_fontsize=8,
    palette=ov.pl.palette_112,
    crop_coord=(2000320025003700),
    figsize=(76),
)
叠加到形态学背景后,可以直接比较聚类边界与组织结构。
ov.pl.spatialseg(
    adata_img, color=marker,
    library_id=library_id,
    edges_color='white', edges_width=0.4,
    alpha=0.65, alpha_img=1.0,
    legend_fontsize=8,
    cmap='Reds', vmax=vmax_marker,
    crop_coord=(2000320025003700),
    figsize=(76),
)
同一块区域按 marker 着色,有助于验证局部组织状态。
ov.pl.spatialseg(
    adata_img, color='KRT7',
    library_id=library_id,
    edges_color='white', edges_width=0.4,
    alpha=0.65, alpha_img=1.0,
    legend_fontsize=8,
    cmap=ov.pl.create_custom_colormap('
#a51616'), vmax=10,
    crop_coord=(2000320025003700),
    figsize=(76),
)
KRT7 在形态学背景上的分布能更直观看到肿瘤相关区域。

有时为了更容易看清单细胞轮廓,可以进一步增大seg_contourpx。这种调整不改变表达值,只是让边界显示得更明显。

ov.pl.spatialseg(
    adata_img, color='KRT7',
    library_id=library_id,
    edges_color='white', edges_width=0.4,
    alpha=0.65, alpha_img=1.0,
    legend_fontsize=8,
    cmap=ov.pl.create_custom_colormap('#a51616'), vmax=10,
    seg_contourpx=1.5,
    crop_coord=(2000320025003700),
    figsize=(76),
)
增大seg_contourpx后,polygon 边界会更加清晰。

快速对齐检查:把 polygon 轮廓叠加到 DAPI 上

这是 Xenium 教程里一个很值得保留的小检查。很多时候,聚类本身看起来没什么问题,但如果 polygon 和 DAPI 没对齐,后面的空间解释还是会偏。

所以最后做一个很直接的 sanity check:只保留 polygon 轮廓线,不做填充,然后叠加到一个更小的 DAPI 局部区域上。理想情况下,每个 polygon 里面都应该能看到对应的亮核。

# 直接手工渲染 polygon,这样可以完整控制 facecolor='none',
# 避免填充颜色把 DAPI 背景完全遮住(`ov.pl.spatialseg(alpha=0, ...)`
# 在 alpha 为 0 时会直接跳过整个 collection)。
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon as _MplPoly
from matplotlib.collections import PatchCollection
from shapely import wkt as _wkt

x0u, x1u, y0u, y1u = 2400280029003300# 更紧的局部裁剪(微米)
sf = adata_img.uns['spatial'][library_id]['scalefactors']['tissue_hires_scalef']
xy = adata_img.obsm['spatial']
mask = (xy[:,0] > x0u) & (xy[:,0] < x1u) & (xy[:,1] > y0u) & (xy[:,1] < y1u)

fig, ax = plt.subplots(figsize=(76))
img = adata_img.uns['spatial'][library_id]['images']['hires']
ax.imshow(img, origin='upper', cmap='gray',
          vmax=float(np.percentile(img, 99.5)))
patches = []
for i in np.where(mask)[0]:
    w = adata_img.obs['geometry'].iloc[i]
ifnot w: continue
    geom = _wkt.loads(w)
ifnot hasattr(geom, 'exterior'): continue
    xs, ys = geom.exterior.xy
    pts = np.column_stack((np.array(xs)*sf, np.array(ys)*sf))
    patches.append(_MplPoly(pts, closed=True))
ax.add_collection(PatchCollection(
    patches, facecolor='none', edgecolor='yellow', linewidth=0.5, alpha=0.9,
))
ax.set_xlim(x0u * sf, x1u * sf)
ax.set_ylim(y1u * sf, y0u * sf)   # 反转 y 轴以匹配图像坐标习惯
ax.set_title(f'alignment check — {len(patches)} cells (yellow) on DAPI')
ax.set_aspect('equal')
plt.show()
最后用只保留轮廓线的方式检查 polygon 与 DAPI 的配准是否准确。

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-04 11:03:26 HTTP/2.0 GET : https://f.mffb.com.cn/a/487694.html
  2. 运行时间 : 0.089421s [ 吞吐率:11.18req/s ] 内存消耗:4,560.98kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=66e6eca87f7aa566fdfaae9442a7c484
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000585s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000885s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000347s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000250s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000521s ]
  6. SELECT * FROM `set` [ RunTime:0.000208s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000566s ]
  8. SELECT * FROM `article` WHERE `id` = 487694 LIMIT 1 [ RunTime:0.000594s ]
  9. UPDATE `article` SET `lasttime` = 1783134206 WHERE `id` = 487694 [ RunTime:0.006027s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000235s ]
  11. SELECT * FROM `article` WHERE `id` < 487694 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000418s ]
  12. SELECT * FROM `article` WHERE `id` > 487694 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000349s ]
  13. SELECT * FROM `article` WHERE `id` < 487694 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.005811s ]
  14. SELECT * FROM `article` WHERE `id` < 487694 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.005010s ]
  15. SELECT * FROM `article` WHERE `id` < 487694 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.000688s ]
0.091037s