[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7EFT2ZGGN6T8DEP06VBXPFD":3,"skill-same:01M7EFT2ZGGN6T8DEP06VBXPFD":62},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":30,"commitSha":31,"skillDirectory":32,"forksCount":14,"repositoryHtmlUrl":33,"repositoryHomepageUrl":33,"ownerHtmlUrl":34,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":35,"install":36,"resources":49},"01M7EFT2ZGGN6T8DEP06VBXPFD","bio-spatial-transcriptomics-spatial-visualization",null,"Plots spatial transcriptomics expression, clusters, and annotations on tissue using Squidpy and Scanpy. Use when choosing the plotter and spot size by platform fork (sc.pl.spatial \u002F sq.pl.spatial_scatter with real scalefactors and capture diameter for spot\u002Fcapture data like Visium and Slide-seq, versus molecule\u002Fsegmentation overlays for imaging\u002FFOV data like Xenium, MERFISH, and CosMx); getting the histology coordinate-frame transform right (micron\u003C->pixel, scalefactors) so points land on the image; and avoiding the honest-visualization traps where interpolation\u002FKDE manufactures spatial pattern not in the data, oversized markers fake tissue coverage, jet and other non-uniform colormaps distort structure, and non-metric UMAP\u002FtSNE distances are misread as spatial conclusions.","Mr-Nobody-Anonymous\u002FAll-skills","Mr-Nobody-Anonymous","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F184253119?v=4","01M7AEXFJHKTYQW5R0ZCQQTWFV","anonymous","01M7C00M3GQR4QKP9GZA42GFAK",0,"MIT","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fbiology\u002Fbio-spatial-transcriptomics-spatial-visualization\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: bio-spatial-transcriptomics-spatial-visualization\ndescription: Plots spatial transcriptomics expression, clusters, and annotations on tissue using Squidpy and Scanpy. Use when choosing the plotter and spot size by platform fork (sc.pl.spatial \u002F sq.pl.spatial_scatter with real scalefactors and capture diameter for spot\u002Fcapture data like Visium and Slide-seq, versus molecule\u002Fsegmentation overlays for imaging\u002FFOV data like Xenium, MERFISH, and CosMx); getting the histology coordinate-frame transform right (micron\u003C->pixel, scalefactors) so points land on the image; and avoiding the honest-visualization traps where interpolation\u002FKDE manufactures spatial pattern not in the data, oversized markers fake tissue coverage, jet and other non-uniform colormaps distort structure, and non-metric UMAP\u002FtSNE distances are misread as spatial conclusions.\ntool_type: python\nprimary_tool: squidpy\nsource: \"https:\u002F\u002Fgithub.com\u002FGPTomics\u002FbioSkills\"\nsource_repository: \"GPTomics\u002FbioSkills\"\nsource_path: \"spatial-transcriptomics\u002Fspatial-visualization\u002FSKILL.md\"\nlicense: \"MIT\"\nimported_at: \"2026-09-20\"\n---\n\n## Version Compatibility\n\nReference examples tested with: squidpy 1.4+, scanpy 1.10+, anndata 0.10+, matplotlib 3.8+\n\nBefore using code patterns, verify installed versions match. If versions differ:\n- Python: `pip show \u003Cpackage>` then `help(module.function)` to check signatures\n\nIf code throws ImportError, AttributeError, or TypeError, introspect the installed\npackage and adapt the example to match the actual API rather than retrying.\n\n# Spatial Visualization\n\n**\"Plot expression \u002F clusters \u002F a score on my tissue section\"** -> Render per-feature values at their real spatial coordinates, optionally over the histology image, without inventing structure the assay did not measure.\n- Spot\u002Fcapture fork (Visium, Visium HD, Slide-seq): `scanpy.pl.spatial` or `squidpy.pl.spatial_scatter` WITH the dataset's `scalefactors` and a `spot_size`\u002F`size` set to the real capture diameter.\n- Imaging\u002FFOV fork (Xenium, MERFISH\u002FMERSCOPE, CosMx): `squidpy.pl.spatial_scatter` with `shape=None` for the cell\u002Fmolecule point cloud, or polygon shapes for segmentation overlays, or a platform viewer (Xenium Explorer, napari, Vitessce, TissUUmaps).\n\n## Governing Principle\n\nPlotting differs by the platform-class fork, and rendering choices can manufacture pattern that is not in the data.\n\nThe first decision is which side of the fork the data sits on, because it selects the plotter and the meaning of marker size. Spot\u002Fcapture data carries a histology image and a `scalefactors` block that maps array coordinates to image pixels; the plotted spot stands for a real capture spot (a 55 um Visium spot is a 1-10-cell mixture, not a cell) and the marker size should reflect that capture diameter. Imaging\u002FFOV data is a point cloud of segmented cells or individual transcript molecules with no Visium-style hex lattice; forcing it through a spot plotter or oversizing markers paints continuous tissue coverage over what is actually sparse, discrete detections. Using the wrong plotter or an arbitrary spot size silently misrepresents the tissue.\n\nThe deeper trap is that several common rendering choices invent structure. Smoothing, kernel-density, kriging, or contouring a sparse spatial field produces a continuous surface that looks like high-resolution biology but is interpolated -- the apparent gradients and domains can be artifacts of the kernel, and any spatial statistic (Moran's I, domain calls) computed on the smoothed field is partly circular. Oversized markers are rhetorical: in `scanpy.pl.spatial` `size` is a scaling factor on the spot diameter, so inflating it merges neighbors and fakes contiguity the assay never resolved. A perceptually non-uniform colormap (jet\u002Frainbow) invents banding and edges in a smooth gradient and is unreadable under color-vision deficiency, and silent `vmin`\u002F`vmax` clipping can erase or exaggerate differences. Finally, UMAP\u002FtSNE distances are NOT metric (the same caveat as single-cell\u002Fclustering) -- gaps and cluster spacing in an embedding carry no spatial meaning and must not be read as tissue conclusions. Honest spatial visualization shows the raw points, names the transform and any clipping, and never lets a plotting parameter assert biology the measurement did not contain.\n\n## Plot genre by platform fork\n\n| Plot genre | Spot\u002Fcapture fork (Visium, Slide-seq) | Imaging\u002FFOV fork (Xenium, MERFISH, CosMx) | Honesty pitfall to avoid |\n|------------|----------------------------------------|--------------------------------------------|--------------------------|\n| Expression \u002F cluster on tissue | `sc.pl.spatial` (uses `scalefactors`) or `sq.pl.spatial_scatter` | `sq.pl.spatial_scatter(shape=None)` point cloud | Oversized `spot_size`\u002F`size` faking coverage |\n| Histology overlay | `sc.pl.spatial(img_key='hires')`; scalefactor maps coords->pixels | `sq.pl.spatial_scatter(img=True, img_res_key=...)` with the registered image | Wrong coordinate frame (micron vs pixel) -> points off image |\n| Single-molecule \u002F transcript map | not applicable (no molecule table) | scatter the transcript x,y table, or Xenium Explorer \u002F napari | Treating segmented matrix as raw molecules |\n| Segmentation \u002F boundary overlay | not applicable | `sq.pl.spatial_scatter` polygon shapes, or napari\u002FTissUUmaps | Hiding segmentation error behind tidy cell polygons |\n| Continuous field \u002F heatmap | per-spot color, NO interpolation | per-cell color, NO interpolation | KDE\u002Fkriging\u002Fcontour manufacturing gradients |\n| Embedding (UMAP\u002FtSNE) | `sc.pl.umap` for QC only | `sc.pl.umap` for QC only | Reading non-metric embedding distance as spatial |\n\nWhen competing rendering options exist (point cloud vs polygon overlay, sequential vs diverging colormap), verify the current platform viewer and Squidpy plotting docs before committing -- spatial tooling and platform exports change quickly.\n\n## Spot\u002FCapture Plot with Real Scalefactors and Spot Size\n\n**Goal:** Show expression or cluster labels at true spot positions on a spot\u002Fcapture section with a marker size that reflects the capture geometry, not a guess.\n\n**Approach:** Let `sc.pl.spatial` read the `uns['spatial']` `scalefactors` so spot coordinates align to the histology image; size markers from the recorded spot diameter rather than an arbitrary constant.\n\n```python\nimport scanpy as sc\nimport squidpy as sq\n\n# scalefactors live in adata.uns['spatial'][library_id]; sc.pl.spatial reads them automatically.\nsc.pl.spatial(adata, color=['leiden', 'total_counts'], img_key='hires', alpha_img=0.6, ncols=2)\n\n# A spot is a 1-10-cell MIXTURE, not a cell -- do not relabel spot clusters as cell types.\n# squidpy resolves the scalefactor from library_id; size here is relative to the spot diameter.\nsq.pl.spatial_scatter(adata, color='leiden', library_id='V1_Human_Lymph_Node', size=1.0)\n```\n\n## Imaging\u002FFOV Overlay (Point Cloud and Segmentation)\n\n**Goal:** Render imaging-platform cells or molecules in their real micron coordinates without imposing a spot lattice they do not have.\n\n**Approach:** Use `sq.pl.spatial_scatter` with `shape=None` for the segmented-cell point cloud (or polygon shapes when boundaries are stored), and overlay the registered image only when its transform is known.\n\n```python\n# Imaging data is a point cloud, not a hex grid: shape=None plots cells as points in micron space.\n# With no image, `size` is the ACTUAL dot size, not a scaling factor -- keep it small so sparse\n# detections do not visually merge into fake continuous tissue.\nsq.pl.spatial_scatter(adata, color='cell_type', shape=None, size=8, img=False)\n\n# Overlay the registered morphology image only when the coordinate frame is trusted.\nsq.pl.spatial_scatter(adata, color='EPCAM', shape=None, size=8, img=True, img_alpha=0.5)\n```\n\n## Histology Coordinate-Frame Overlay\n\n**Goal:** Place transcripts\u002Fspots on the H&E or DAPI image so each point lands on the histological structure it came from.\n\n**Approach:** Map array\u002Fmicron coordinates into image-pixel space with the correct scalefactor (or platform affine); never plot raw micron coordinates onto a pixel image. Inspect the alignment before trusting any structure read off the overlay.\n\n```python\n# Spot\u002Fcapture: hires-image pixel coords = spatial coords * tissue_hires_scalef.\nlibrary_id = list(adata.uns['spatial'].keys())[0]\nscalef = adata.uns['spatial'][library_id]['scalefactors']['tissue_hires_scalef']\nimg = adata.uns['spatial'][library_id]['images']['hires']\n\nimport matplotlib.pyplot as plt\nfig, ax = plt.subplots(figsize=(8, 8))\nax.imshow(img)                                   # image is in pixel space\ncoords_px = adata.obsm['spatial'] * scalef       # transform microns\u002Farray units -> pixels\nax.scatter(coords_px[:, 0], coords_px[:, 1], s=6, c='red')\nax.set_axis_off()                                # a small misalignment puts expression in the wrong structure\n```\n\n## Honest Continuous Field (Colormap and No Interpolation)\n\n**Goal:** Show a continuous score across the section truthfully -- visible raw points, a perceptually uniform colormap, and disclosed clipping.\n\n**Approach:** Color each measured spot\u002Fcell directly (never interpolate between them), pick a perceptually uniform map, and state any `vmin`\u002F`vmax` clip rather than letting it silently reshape the gradient.\n\n```python\n# Color the MEASURED points only. Do NOT KDE\u002Fkriging\u002Fcontour a sparse field -- that manufactures\n# gradients and any Moran's I \u002F domain call computed on the smoothed surface is partly circular.\nsc.pl.spatial(adata, color='CD3D', cmap='viridis', vmin=0, vmax='p99')   # 'p99' clip is disclosed, not hidden\n\n# Avoid jet\u002Frainbow: perceptually non-uniform maps invent banding and fail color-vision-deficiency\n# readers. Scientific colour maps (Crameri) are perceptually uniform; install cmcrameri to use them.\n# import cmcrameri.cm as cmc; sc.pl.spatial(adata, color='CD3D', cmap=cmc.batlow)\n```\n\n## Interactive Exploration\n\nLarge imaging sections and multi-resolution images are better explored interactively than in static panels. napari (image + points + shapes layers), Vitessce (web, multimodal), TissUUmaps (large image-plus-marker viewing), and the vendor Xenium Explorer \u002F Xenium Panel viewer all pan-and-zoom over the full-resolution data. The same coordinate-frame discipline applies: points must be transformed into the viewer's pixel space (for spot\u002Fcapture, multiply spatial coordinates by the relevant `tissue_*_scalef`).\n\n```python\nimport napari\nlibrary_id = list(adata.uns['spatial'].keys())[0]\nimg = adata.uns['spatial'][library_id]['images']['hires']\nscalef = adata.uns['spatial'][library_id]['scalefactors']['tissue_hires_scalef']\nviewer = napari.Viewer()\nviewer.add_image(img, name='tissue')\nviewer.add_points(adata.obsm['spatial'] * scalef, size=10, name='spots')   # transform into pixel space\nnapari.run()\n```\n\n## Embedding Caveat\n\n`sc.pl.umap`\u002F`sc.pl.tsne` are legitimate for QC and cluster sanity-checks, but UMAP\u002FtSNE distances are not metric: the size of gaps between clusters and the apparent spacing of points carry no quantitative meaning, and nothing spatial can be concluded from them. Read tissue structure off the spatial plot, never off the embedding (see single-cell\u002Fclustering for the full caveat).\n\n## Common Errors\n\n| Symptom | Cause | Fix |\n|---------|-------|-----|\n| Spots overlap into a solid sheet; sparse signal looks continuous | `spot_size`\u002F`size` set far above the real capture diameter | Size markers from the spot diameter; for imaging keep `size` small (it is the actual dot size when no image) |\n| Points land off the image or in the wrong tissue region | Plotting micron\u002Farray coordinates onto a pixel image without the scalefactor\u002Faffine | Transform coords -> pixels (`* tissue_hires_scalef`, or the platform affine) before overlay |\n| Smooth gradients\u002Fdomains that vanish on the raw points | Field was KDE\u002Fkriged\u002Fcontoured\u002Fimputed; pattern is the kernel, not the tissue | Plot measured points only; show raw alongside any smoothed view and disclose the kernel |\n| Banding\u002Fedges appear in a smooth field; figure unreadable in grayscale | jet\u002Frainbow or other perceptually non-uniform colormap | Use a perceptually uniform map (viridis, or Crameri scientific colour maps via cmcrameri) |\n| Two conditions look very different for the same expression | Inconsistent or silent `vmin`\u002F`vmax` between panels | Fix and disclose the color scale across panels (shared `vmin`\u002F`vmax`) |\n| Imaging cells plotted on a hex\u002Fgrid lattice or with empty image background | Spot plotter (`sc.pl.spatial`) or default `shape` used on imaging point-cloud data | Use `sq.pl.spatial_scatter(shape=None)`; pass the registered image only with a known transform |\n| Conclusions drawn from gaps between UMAP clusters | Treating non-metric embedding distance as spatial\u002Fquantitative | Restrict spatial claims to the spatial plot; use UMAP for QC only |\n| Spot clusters labeled as cell types | A capture spot is a 1-10-cell mixture, not a cell | Label spot clusters as regions\u002Fniches; deconvolve for composition (spatial-deconvolution) |\n| Per-spot proportion\u002Fscatterpie map read as measured composition | Deconvolution output is a model estimate carrying reference and fit uncertainty | Present proportion maps as estimates; rare-type fractions are least reliable, so corroborate before reading them off the map (spatial-deconvolution) |\n\n## Related Skills\n\n- spatial-data-io - load the platform data and the histology image plus scalefactors that plotting depends on\n- spatial-domains - produce the region labels rendered on the section\n- spatial-statistics - compute Moran's I \u002F neighborhood enrichment whose results are plotted here\n- data-visualization\u002Fheatmaps-clustering - general perceptually-uniform colormap and figure conventions\n- single-cell\u002Fclustering - the non-metric UMAP\u002FtSNE distance caveat that applies to embeddings\n\n## References\n\n- Palla G, Spitzer H, Klein M, et al. (2022) Squidpy: a scalable framework for spatial omics analysis. Nature Methods 19(2):171-178. DOI 10.1038\u002Fs41592-021-01358-2\n- Wolf FA, Angerer P, Theis FJ (2018) SCANPY: large-scale single-cell gene expression data analysis. Genome Biology 19:15. DOI 10.1186\u002Fs13059-017-1382-0\n- Marconato L, Palla G, Yamauchi KA, et al. (2025) SpatialData: an open and universal data framework for spatial omics. Nature Methods 22(1):58-62. DOI 10.1038\u002Fs41592-024-02212-x\n- Crameri F, Shephard GE, Heron PJ (2020) The misuse of colour in science communication. Nature Communications 11:5444. DOI 10.1038\u002Fs41467-020-19160-7\n- Chari T, Pachter L (2023) The specious art of single-cell genomics. PLoS Computational Biology 19(8):e1011288. DOI 10.1371\u002Fjournal.pcbi.1011288\n","## Version Compatibility\n\nReference examples tested with: squidpy 1.4+, scanpy 1.10+, anndata 0.10+, matplotlib 3.8+\n\nBefore using code patterns, verify installed versions match. If versions differ:\n- Python: `pip show \u003Cpackage>` then `help(module.function)` to check signatures\n\nIf code throws ImportError, AttributeError, or TypeError, introspect the installed\npackage and adapt the example to match the actual API rather than retrying.\n\n# Spatial Visualization\n\n**\"Plot expression \u002F clusters \u002F a score on my tissue section\"** -> Render per-feature values at their real spatial coordinates, optionally over the histology image, without inventing structure the assay did not measure.\n- Spot\u002Fcapture fork (Visium, Visium HD, Slide-seq): `scanpy.pl.spatial` or `squidpy.pl.spatial_scatter` WITH the dataset's `scalefactors` and a `spot_size`\u002F`size` set to the real capture diameter.\n- Imaging\u002FFOV fork (Xenium, MERFISH\u002FMERSCOPE, CosMx): `squidpy.pl.spatial_scatter` with `shape=None` for the cell\u002Fmolecule point cloud, or polygon shapes for segmentation overlays, or a platform viewer (Xenium Explorer, napari, Vitessce, TissUUmaps).\n\n## Governing Principle\n\nPlotting differs by the platform-class fork, and rendering choices can manufacture pattern that is not in the data.\n\nThe first decision is which side of the fork the data sits on, because it selects the plotter and the meaning of marker size. Spot\u002Fcapture data carries a histology image and a `scalefactors` block that maps array coordinates to image pixels; the plotted spot stands for a real capture spot (a 55 um Visium spot is a 1-10-cell mixture, not a cell) and the marker size should reflect that capture diameter. Imaging\u002FFOV data is a point cloud of segmented cells or individual transcript molecules with no Visium-style hex lattice; forcing it through a spot plotter or oversizing markers paints continuous tissue coverage over what is actually sparse, discrete detections. Using the wrong plotter or an arbitrary spot size silently misrepresents the tissue.\n\nThe deeper trap is that several common rendering choices invent structure. Smoothing, kernel-density, kriging, or contouring a sparse spatial field produces a continuous surface that looks like high-resolution biology but is interpolated -- the apparent gradients and domains can be artifacts of the kernel, and any spatial statistic (Moran's I, domain calls) computed on the smoothed field is partly circular. Oversized markers are rhetorical: in `scanpy.pl.spatial` `size` is a scaling factor on the spot diameter, so inflating it merges neighbors and fakes contiguity the assay never resolved. A perceptually non-uniform colormap (jet\u002Frainbow) invents banding and edges in a smooth gradient and is unreadable under color-vision deficiency, and silent `vmin`\u002F`vmax` clipping can erase or exaggerate differences. Finally, UMAP\u002FtSNE distances are NOT metric (the same caveat as single-cell\u002Fclustering) -- gaps and cluster spacing in an embedding carry no spatial meaning and must not be read as tissue conclusions. Honest spatial visualization shows the raw points, names the transform and any clipping, and never lets a plotting parameter assert biology the measurement did not contain.\n\n## Plot genre by platform fork\n\n| Plot genre | Spot\u002Fcapture fork (Visium, Slide-seq) | Imaging\u002FFOV fork (Xenium, MERFISH, CosMx) | Honesty pitfall to avoid |\n|------------|----------------------------------------|--------------------------------------------|--------------------------|\n| Expression \u002F cluster on tissue | `sc.pl.spatial` (uses `scalefactors`) or `sq.pl.spatial_scatter` | `sq.pl.spatial_scatter(shape=None)` point cloud | Oversized `spot_size`\u002F`size` faking coverage |\n| Histology overlay | `sc.pl.spatial(img_key='hires')`; scalefactor maps coords->pixels | `sq.pl.spatial_scatter(img=True, img_res_key=...)` with the registered image | Wrong coordinate frame (micron vs pixel) -> points off image |\n| Single-molecule \u002F transcript map | not applicable (no molecule table) | scatter the transcript x,y table, or Xenium Explorer \u002F napari | Treating segmented matrix as raw molecules |\n| Segmentation \u002F boundary overlay | not applicable | `sq.pl.spatial_scatter` polygon shapes, or napari\u002FTissUUmaps | Hiding segmentation error behind tidy cell polygons |\n| Continuous field \u002F heatmap | per-spot color, NO interpolation | per-cell color, NO interpolation | KDE\u002Fkriging\u002Fcontour manufacturing gradients |\n| Embedding (UMAP\u002FtSNE) | `sc.pl.umap` for QC only | `sc.pl.umap` for QC only | Reading non-metric embedding distance as spatial |\n\nWhen competing rendering options exist (point cloud vs polygon overlay, sequential vs diverging colormap), verify the current platform viewer and Squidpy plotting docs before committing -- spatial tooling and platform exports change quickly.\n\n## Spot\u002FCapture Plot with Real Scalefactors and Spot Size\n\n**Goal:** Show expression or cluster labels at true spot positions on a spot\u002Fcapture section with a marker size that reflects the capture geometry, not a guess.\n\n**Approach:** Let `sc.pl.spatial` read the `uns['spatial']` `scalefactors` so spot coordinates align to the histology image; size markers from the recorded spot diameter rather than an arbitrary constant.\n\n```python\nimport scanpy as sc\nimport squidpy as sq\n\n# scalefactors live in adata.uns['spatial'][library_id]; sc.pl.spatial reads them automatically.\nsc.pl.spatial(adata, color=['leiden', 'total_counts'], img_key='hires', alpha_img=0.6, ncols=2)\n\n# A spot is a 1-10-cell MIXTURE, not a cell -- do not relabel spot clusters as cell types.\n# squidpy resolves the scalefactor from library_id; size here is relative to the spot diameter.\nsq.pl.spatial_scatter(adata, color='leiden', library_id='V1_Human_Lymph_Node', size=1.0)\n```\n\n## Imaging\u002FFOV Overlay (Point Cloud and Segmentation)\n\n**Goal:** Render imaging-platform cells or molecules in their real micron coordinates without imposing a spot lattice they do not have.\n\n**Approach:** Use `sq.pl.spatial_scatter` with `shape=None` for the segmented-cell point cloud (or polygon shapes when boundaries are stored), and overlay the registered image only when its transform is known.\n\n```python\n# Imaging data is a point cloud, not a hex grid: shape=None plots cells as points in micron space.\n# With no image, `size` is the ACTUAL dot size, not a scaling factor -- keep it small so sparse\n# detections do not visually merge into fake continuous tissue.\nsq.pl.spatial_scatter(adata, color='cell_type', shape=None, size=8, img=False)\n\n# Overlay the registered morphology image only when the coordinate frame is trusted.\nsq.pl.spatial_scatter(adata, color='EPCAM', shape=None, size=8, img=True, img_alpha=0.5)\n```\n\n## Histology Coordinate-Frame Overlay\n\n**Goal:** Place transcripts\u002Fspots on the H&E or DAPI image so each point lands on the histological structure it came from.\n\n**Approach:** Map array\u002Fmicron coordinates into image-pixel space with the correct scalefactor (or platform affine); never plot raw micron coordinates onto a pixel image. Inspect the alignment before trusting any structure read off the overlay.\n\n```python\n# Spot\u002Fcapture: hires-image pixel coords = spatial coords * tissue_hires_scalef.\nlibrary_id = list(adata.uns['spatial'].keys())[0]\nscalef = adata.uns['spatial'][library_id]['scalefactors']['tissue_hires_scalef']\nimg = adata.uns['spatial'][library_id]['images']['hires']\n\nimport matplotlib.pyplot as plt\nfig, ax = plt.subplots(figsize=(8, 8))\nax.imshow(img)                                   # image is in pixel space\ncoords_px = adata.obsm['spatial'] * scalef       # transform microns\u002Farray units -> pixels\nax.scatter(coords_px[:, 0], coords_px[:, 1], s=6, c='red')\nax.set_axis_off()                                # a small misalignment puts expression in the wrong structure\n```\n\n## Honest Continuous Field (Colormap and No Interpolation)\n\n**Goal:** Show a continuous score across the section truthfully -- visible raw points, a perceptually uniform colormap, and disclosed clipping.\n\n**Approach:** Color each measured spot\u002Fcell directly (never interpolate between them), pick a perceptually uniform map, and state any `vmin`\u002F`vmax` clip rather than letting it silently reshape the gradient.\n\n```python\n# Color the MEASURED points only. Do NOT KDE\u002Fkriging\u002Fcontour a sparse field -- that manufactures\n# gradients and any Moran's I \u002F domain call computed on the smoothed surface is partly circular.\nsc.pl.spatial(adata, color='CD3D', cmap='viridis', vmin=0, vmax='p99')   # 'p99' clip is disclosed, not hidden\n\n# Avoid jet\u002Frainbow: perceptually non-uniform maps invent banding and fail color-vision-deficiency\n# readers. Scientific colour maps (Crameri) are perceptually uniform; install cmcrameri to use them.\n# import cmcrameri.cm as cmc; sc.pl.spatial(adata, color='CD3D', cmap=cmc.batlow)\n```\n\n## Interactive Exploration\n\nLarge imaging sections and multi-resolution images are better explored interactively than in static panels. napari (image + points + shapes layers), Vitessce (web, multimodal), TissUUmaps (large image-plus-marker viewing), and the vendor Xenium Explorer \u002F Xenium Panel viewer all pan-and-zoom over the full-resolution data. The same coordinate-frame discipline applies: points must be transformed into the viewer's pixel space (for spot\u002Fcapture, multiply spatial coordinates by the relevant `tissue_*_scalef`).\n\n```python\nimport napari\nlibrary_id = list(adata.uns['spatial'].keys())[0]\nimg = adata.uns['spatial'][library_id]['images']['hires']\nscalef = adata.uns['spatial'][library_id]['scalefactors']['tissue_hires_scalef']\nviewer = napari.Viewer()\nviewer.add_image(img, name='tissue')\nviewer.add_points(adata.obsm['spatial'] * scalef, size=10, name='spots')   # transform into pixel space\nnapari.run()\n```\n\n## Embedding Caveat\n\n`sc.pl.umap`\u002F`sc.pl.tsne` are legitimate for QC and cluster sanity-checks, but UMAP\u002FtSNE distances are not metric: the size of gaps between clusters and the apparent spacing of points carry no quantitative meaning, and nothing spatial can be concluded from them. Read tissue structure off the spatial plot, never off the embedding (see single-cell\u002Fclustering for the full caveat).\n\n## Common Errors\n\n| Symptom | Cause | Fix |\n|---------|-------|-----|\n| Spots overlap into a solid sheet; sparse signal looks continuous | `spot_size`\u002F`size` set far above the real capture diameter | Size markers from the spot diameter; for imaging keep `size` small (it is the actual dot size when no image) |\n| Points land off the image or in the wrong tissue region | Plotting micron\u002Farray coordinates onto a pixel image without the scalefactor\u002Faffine | Transform coords -> pixels (`* tissue_hires_scalef`, or the platform affine) before overlay |\n| Smooth gradients\u002Fdomains that vanish on the raw points | Field was KDE\u002Fkriged\u002Fcontoured\u002Fimputed; pattern is the kernel, not the tissue | Plot measured points only; show raw alongside any smoothed view and disclose the kernel |\n| Banding\u002Fedges appear in a smooth field; figure unreadable in grayscale | jet\u002Frainbow or other perceptually non-uniform colormap | Use a perceptually uniform map (viridis, or Crameri scientific colour maps via cmcrameri) |\n| Two conditions look very different for the same expression | Inconsistent or silent `vmin`\u002F`vmax` between panels | Fix and disclose the color scale across panels (shared `vmin`\u002F`vmax`) |\n| Imaging cells plotted on a hex\u002Fgrid lattice or with empty image background | Spot plotter (`sc.pl.spatial`) or default `shape` used on imaging point-cloud data | Use `sq.pl.spatial_scatter(shape=None)`; pass the registered image only with a known transform |\n| Conclusions drawn from gaps between UMAP clusters | Treating non-metric embedding distance as spatial\u002Fquantitative | Restrict spatial claims to the spatial plot; use UMAP for QC only |\n| Spot clusters labeled as cell types | A capture spot is a 1-10-cell mixture, not a cell | Label spot clusters as regions\u002Fniches; deconvolve for composition (spatial-deconvolution) |\n| Per-spot proportion\u002Fscatterpie map read as measured composition | Deconvolution output is a model estimate carrying reference and fit uncertainty | Present proportion maps as estimates; rare-type fractions are least reliable, so corroborate before reading them off the map (spatial-deconvolution) |\n\n## Related Skills\n\n- spatial-data-io - load the platform data and the histology image plus scalefactors that plotting depends on\n- spatial-domains - produce the region labels rendered on the section\n- spatial-statistics - compute Moran's I \u002F neighborhood enrichment whose results are plotted here\n- data-visualization\u002Fheatmaps-clustering - general perceptually-uniform colormap and figure conventions\n- single-cell\u002Fclustering - the non-metric UMAP\u002FtSNE distance caveat that applies to embeddings\n\n## References\n\n- Palla G, Spitzer H, Klein M, et al. (2022) Squidpy: a scalable framework for spatial omics analysis. Nature Methods 19(2):171-178. DOI 10.1038\u002Fs41592-021-01358-2\n- Wolf FA, Angerer P, Theis FJ (2018) SCANPY: large-scale single-cell gene expression data analysis. Genome Biology 19:15. DOI 10.1186\u002Fs13059-017-1382-0\n- Marconato L, Palla G, Yamauchi KA, et al. (2025) SpatialData: an open and universal data framework for spatial omics. Nature Methods 22(1):58-62. DOI 10.1038\u002Fs41592-024-02212-x\n- Crameri F, Shephard GE, Heron PJ (2020) The misuse of colour in science communication. Nature Communications 11:5444. DOI 10.1038\u002Fs41467-020-19160-7\n- Chari T, Pachter L (2023) The specious art of single-cell genomics. PLoS Computational Biology 19(8):e1011288. DOI 10.1371\u002Fjournal.pcbi.1011288\n",{"name":5,"source":24,"license":15,"tool_type":25,"description":7,"imported_at":26,"source_path":27,"primary_tool":28,"source_repository":29},"https:\u002F\u002Fgithub.com\u002FGPTomics\u002FbioSkills","python","2026-09-20","spatial-transcriptomics\u002Fspatial-visualization\u002FSKILL.md","squidpy","GPTomics\u002FbioSkills","main","2d1750717747097b602acf30bd09a7cbd4b4c6ea","awesome_skills\u002Fbiology\u002Fbio-spatial-transcriptomics-spatial-visualization","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous","2026-11-09 11:45:36",{"source":8,"skillName":5,"commands":37,"prompt":47,"zipAvailable":48},[38,41,44],{"tool":39,"command":40},"npx","npx skills add Mr-Nobody-Anonymous\u002FAll-skills --skill bio-spatial-transcriptomics-spatial-visualization",{"tool":42,"command":43},"bunx","bunx skills add Mr-Nobody-Anonymous\u002FAll-skills --skill bio-spatial-transcriptomics-spatial-visualization",{"tool":45,"command":46},"pnpm","pnpm dlx skills add Mr-Nobody-Anonymous\u002FAll-skills --skill bio-spatial-transcriptomics-spatial-visualization","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fbiology\u002Fbio-spatial-transcriptomics-spatial-visualization\u002FSKILL.md",true,[50,56],{"path":51,"resourceType":52,"resourceTypeDesc":53,"sizeBytes":54,"sourceHtmlUrl":55},"examples\u002Fspatial_plot.py","SCRIPT","脚本",2079,"https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fbiology\u002Fbio-spatial-transcriptomics-spatial-visualization\u002Fexamples\u002Fspatial_plot.py",{"path":57,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":60,"sourceHtmlUrl":61},"usage-guide.md","REFERENCE","参考文档",3789,"https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fbiology\u002Fbio-spatial-transcriptomics-spatial-visualization\u002Fusage-guide.md",[63,71,78,85,92,99],{"skillNo":64,"name":65,"nameZh":6,"description":66,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":67,"categories":68,"keywords":69,"publishedAt":70},"01M7EXRQF9GFM7D9BG6N5HAT34","oath","Auditing regulatory compliance (SOC2\u002FPCI-DSS\u002FHIPAA\u002FISO 27001): maps requirements, checks controls, designs audit trails, implements Policy as Code. Use when compliance auditing is needed.","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fdevsecops\u002Foath\u002FSKILL.md",[],[],"2026-11-15 14:25:24",{"skillNo":72,"name":73,"nameZh":6,"description":74,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":75,"categories":76,"keywords":77,"publishedAt":19},"01M7EXRH7TYTNZJT0BQXEWAMW7","nexus","Orchestrating multi-specialist task chains and scope-adaptive product delivery: classifies intent, selects and executes the minimum viable chain, aggregates results, and verifies acceptance criteria. For multi-domain tasks, build-first delivery, and product lifecycle execution.","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fdevsecops\u002Fnexus\u002FSKILL.md",[],[],{"skillNo":79,"name":80,"nameZh":6,"description":81,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":82,"categories":83,"keywords":84,"publishedAt":19},"01M7EXRCDPFWVEEEFR2ZQGJCYY","nest","Designing LLM-optimized folder structures: audits and restructures directories for context efficiency, progressive disclosure, and prompt cache performance. Not for general repo structure (Grove).","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fdevsecops\u002Fnest\u002FSKILL.md",[],[],{"skillNo":86,"name":87,"nameZh":6,"description":88,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":89,"categories":90,"keywords":91,"publishedAt":19},"01M7EXR7JEER60TH0HD0AH4EE9","native","Implementing production iOS\u002FAndroid\u002FmacOS native features (SwiftUI, Compose) and iterating a screen against a reference design. Not for cross-platform RN\u002FFlutter (Port) or web (Artisan).","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fdevsecops\u002Fnative\u002FSKILL.md",[],[],{"skillNo":93,"name":94,"nameZh":6,"description":95,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":96,"categories":97,"keywords":98,"publishedAt":19},"01M7EXR133J7DD5961R80QTRZY","muse","Defining and managing design tokens, applying token systems to existing codebases, building design system foundations. Use for spacing, color, typography, dark mode, cross-platform output.","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fdevsecops\u002Fmuse\u002FSKILL.md",[],[],{"skillNo":100,"name":101,"nameZh":6,"description":102,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":103,"categories":104,"keywords":105,"publishedAt":19},"01M7EXQWWX7ECQN0J50B41YN5N","morph","Converting document formats (Markdown\u002FWord\u002FExcel\u002FPDF\u002FHTML) and generating reusable conversion scripts. Use for distributable specs, accessibility-compliant PDFs, or Pandoc\u002FLibreOffice pipelines.","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fdevsecops\u002Fmorph\u002FSKILL.md",[],[]]