domains / science / spatial-transcriptomics-visualization / spatial-visualization
The two skills cover the same domain (spatial transcriptomics visualization) but differ significantly in depth and intent. The first copy (OpenClaw) is a practical 'cookbook' of code snippets for common plotting tasks (basic plots, gene expression, co-expression, napari). The second copy (GPTomics) is a conceptual guide focused on 'honest visualization,' emphasizing the distinction between spot/capture data (Visium) and imaging/FOV data (Xenium/MERFISH), the importance of correct scalefactors, and avoiding artifacts like interpolation or misleading colormaps. The first copy lacks the critical platform-specific logic and honesty warnings present in the second, while the second copy is truncated and lacks the specific code examples for complex tasks like co-expression RGB plots or multi-panel figures found in the first. Combining them provides both the practical code and the necessary scientific rigor.
| Repository | Path |
|---|---|
| FreedomIntelligence/OpenClaw-Medical-Skills | skills/spatial-transcriptomics-analysis/bioSkills/spatial-visualization/SKILL.md |
| GPTomics/bioSkills | spatial-transcriptomics/spatial-visualization/SKILL.md |
| Role | Repository | Path |
|---|---|---|
| peer | FreedomIntelligence/OpenClaw-Medical-Skills | skills/spatial-transcriptomics-analysis/bioSkills/spatial-visualization/SKILL.md |
| peer | GPTomics/bioSkills | spatial-transcriptomics/spatial-visualization/SKILL.md |
---
name: bio-spatial-transcriptomics-spatial-visualization
description: Visualize spatial transcriptomics data using Squidpy and Scanpy. Distinguishes between spot/capture (Visium) and imaging/FOV (Xenium/MERFISH) data to ensure honest, artifact-free visualization.
tool_type: python
primary_tool: squidpy
---
# Spatial Visualization
Create visualizations for spatial transcriptomics data. The first step is to identify the data platform to select the correct plotting strategy.
## 1. Platform Fork & Honesty Principles
**Spot/Capture Data (Visium, Slide-seq):**
- Data consists of spots on a hexagonal lattice.
- Use `sc.pl.spatial` or `sq.pl.spatial_scatter`.
- **Critical:** Use the dataset's `scalefactors` to map coordinates to the histology image.
- **Spot Size:** Set `spot_size` or `size` to reflect the real capture diameter (e.g., 55um for Visium). Do not inflate size to fake coverage.
**Imaging/FOV Data (Xenium, MERFISH, CosMx):**
- Data consists of individual molecules or segmented cells (point cloud).
- Use `sq.pl.spatial_scatter` with `shape=None` for points or polygon shapes for segmentation.
- **Do not** use spot-based plotters that assume a lattice.
- **Do not** interpolate or use KDE to create continuous surfaces from sparse molecule data.
**General Honesty Rules:**
- Avoid non-uniform colormaps (jet/rainbow); use perceptually uniform maps (viridis, plasma).
- Explicitly set `vmin`/`vmax` to avoid silent clipping.
- Do not interpret UMAP/tSNE distances as spatial distances.
## 2. Required Imports
```python
import squidpy as sq
import scanpy as sc
import matplotlib.pyplot as plt
import numpy as np
```
## 3. Basic Spatial Plots
### Spot/Capture (Visium)
```python
# Plot spots colored by a variable
sq.pl.spatial_scatter(adata, color='total_counts', size=1.3)
# Using Scanpy (handles scalefactors automatically if available)
sc.pl.spatial(adata, color='leiden', spot_size=1.5)
```
### Imaging/FOV (Xenium/MERFISH)
```python
# Point cloud visualization
sq.pl.spatial_scatter(adata, color='leiden', shape=None)
```
## 4. Tissue Image Overlay
```python
# With tissue background (Visium)
sc.pl.spatial(adata, color='leiden', img_key='hires', alpha_img=0.5)
# Without tissue
sc.pl.spatial(adata, color='leiden', img_key=None)
```
## 5. Gene Expression on Tissue
```python
# Single gene
sc.pl.spatial(adata, color='CD3D', cmap='viridis', vmin=0, vmax='p99')
# Multiple genes side by side
genes = ['CD3D', 'MS4A1', 'CD14', 'NKG7']
sc.pl.spatial(adata, color=genes, ncols=2, cmap='Reds', vmin=0)
```
## 6. Co-expression Plot (RGB)
Visualize co-expression of two genes using RGB channels.
```python
gene1, gene2 = 'CD3D', 'CD8A'
expr1 = adata[:, gene1].X.toarray().flatten()
expr2 = adata[:, gene2].X.toarray().flatten()
from matplotlib.colors import Normalize
norm = Normalize(vmin=0, vmax=np.percentile(np.concatenate([expr1, expr2]), 99))
colors = np.zeros((adata.n_obs, 3))
colors[:, 0] = norm(expr1) # Red channel
colors[:, 1] = norm(expr2) # Green channel
fig, ax = plt.subplots(figsize=(8, 8))
coords = adata.obsm['spatial']
ax.scatter(coords[:, 0], coords[:, 1], c=colors, s=10)
ax.set_aspect('equal')
ax.set_title(f'{gene1} (red) + {gene2} (green)')
plt.savefig('coexpression.png', dpi=300)
```
## 7. Interactive Visualization with Napari
```python
import napari
viewer = napari.Viewer()
library_id = list(adata.uns['spatial'].keys())[0]
img = adata.uns['spatial'][library_id]['images']['hires']
viewer.add_image(img, name='tissue')
coords = adata.obsm['spatial']
scalef = adata.uns['spatial'][library_id]['scalefactors']['tissue_hires_scalef']
viewer.add_points(coords * scalef, size=10, name='spots')
napari.run()
```
## 8. Publication-Quality Figures
```python
fig, ax = plt.subplots(figsize=(8, 8))
sc.pl.spatial(
adata,
color='leiden',
ax=ax,
show=False,
frameon=False,
title='',
legend_loc='right margin',
)
plt.savefig('figure.pdf', dpi=300, bbox_inches='tight')
```