Skip to contents

Overview

fastCNV provides comprehensive visualization tools for CNV analysis results. This vignette covers:

  1. CNV Heatmaps - Genome-wide CNV profiles
  2. Phylogenetic Trees - Clonal evolution visualization
  3. Chromosome Arm Plots - Arm-level CNV summary
  4. Spatial CNV Maps - CNV patterns in tissue context

CNV Heatmaps

Example CNV Heatmap

CNV heatmap showing chromosomal alterations. Rows represent cells, columns represent genomic windows. Blue = deletion, Red = amplification.

CNV heatmap showing chromosomal alterations. Rows represent cells, columns represent genomic windows. Blue = deletion, Red = amplification.

Basic Heatmap

The plotCNVResults() function generates publication-ready heatmaps:

library(fastCNV)

# Generate CNV heatmap
plotCNVResults(
  seuratObj = result,
  referenceVar = "cell_type",
  tumorLabel = "Tumor"
)

Customizing Heatmaps

Split by Cell Type

plotCNVResults(
  seuratObj = result,
  referenceVar = "cell_type",
  tumorLabel = "Tumor",
  splitPlotOnVar = "cell_subtype"  # Split rows by subtype
)

Split by CNV Clusters

plotCNVResults(
  seuratObj = result,
  referenceVar = "cell_type",
  tumorLabel = "Tumor",
  splitPlotOnVar = "cnv_clusters"  # Group by CNV clusters
)

Custom Color Scheme

The heatmap uses a diverging color scale: - Blue: Deletions (negative CNV scores) - White: Neutral (no alteration) - Red: Amplifications (positive CNV scores)

# The default color scheme is optimized for CNV visualization
# Colors are scaled to the data range with balanced mapping

Heatmap Components

A typical CNV heatmap includes:

┌─────────────────────────────────────────────────────────────┐
│                    Chromosome Labels (1-22, X)              │
├─────────────────────────────────────────────────────────────┤
│  Row      │                                                 │
│  Anno-    │          CNV Score Matrix                       │
│  tations  │          (cells × genomic windows)              │
│           │                                                 │
│  - Cell   │  Blue = Deletion                                │
│    type   │  White = Neutral                                │
│  - Clone  │  Red = Amplification                            │
│           │                                                 │
├─────────────────────────────────────────────────────────────┤
│                    Color Legend                             │
└─────────────────────────────────────────────────────────────┘

Phylogenetic Trees

Example Dendrogram

Hierarchical clustering dendrogram based on CNV profiles, showing the relationship between different clones.

Hierarchical clustering dendrogram based on CNV profiles, showing the relationship between different clones.

Building CNV Trees

CNV profiles can be used to reconstruct clonal phylogenies:

# Build phylogenetic tree from CNV clusters
tree <- CNVTree(
  seuratObj = result,
  referenceVar = "cell_type",
  tumorLabel = "Tumor",
  cnv_thresh = 0.15
)

Visualizing Trees

# Plot the phylogenetic tree
plotCNVTree(
  tree = tree,
  seuratObj = result,
  referenceVar = "cell_type",
  tumorLabel = "Tumor"
)

Annotated Trees

Add CNV event annotations to tree branches:

# Annotate tree with CNV events
annotated_tree <- annotateCNVTree(
  tree = tree,
  seuratObj = result,
  cnv_thresh = 0.15
)

# Plot with annotations
plotCNVTree(
  tree = annotated_tree,
  seuratObj = result,
  referenceVar = "cell_type",
  tumorLabel = "Tumor",
  show_annotations = TRUE
)

Tree Interpretation

                    ┌─── Clone A (chr7+, chr10-)
            ┌───────┤
            │       └─── Clone B (chr7+, chr10-, chr19+)
    ────────┤
            │       ┌─── Clone C (chr1q+)
            └───────┤
                    └─── Clone D (chr1q+, chr8-)
    
    Legend:
    + = Amplification
    - = Deletion

Chromosome Arm-Level Analysis

Example: CNV Fraction per Chromosome Arm

Bar plot showing mean CNV scores per chromosome arm for different clones.

Bar plot showing mean CNV scores per chromosome arm for different clones.

Computing Arm-Level CNVs

# Calculate CNV fraction per chromosome arm
result <- CNVPerChromosomeArm(
  seuratObj = result,
  referenceVar = "cell_type",
  tumorLabel = "Tumor"
)

# View arm-level data
head(result$cnv_per_arm)

Visualizing Arm-Level CNVs

library(ggplot2)

# Extract arm-level data
arm_data <- result$cnv_per_arm

# Create bar plot
ggplot(arm_data, aes(x = arm, y = cnv_fraction, fill = cnv_type)) +
  geom_bar(stat = "identity") +
  facet_wrap(~cluster, ncol = 1) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(
    title = "CNV Fraction per Chromosome Arm",
    x = "Chromosome Arm",
    y = "Fraction of Cells with CNV"
  )

Spatial CNV Visualization

Visium Data

library(Seurat)

# Plot CNV clusters on tissue
SpatialDimPlot(
  result,
  group.by = "cnv_clusters",
  pt.size.factor = 1.6
)

Visium HD Data

# For Visium HD, use the specialized function
plotCNVResultsHD(
  seuratObj = result,
  referenceVar = "region",
  tumorLabel = "Tumor"
)

Combining Spatial and CNV Information

# Create a multi-panel figure
library(patchwork)

# Panel 1: Cell type annotation
p1 <- SpatialDimPlot(result, group.by = "cell_type")

# Panel 2: CNV clusters
p2 <- SpatialDimPlot(result, group.by = "cnv_clusters")

# Panel 3: CNV score for specific chromosome
p3 <- SpatialFeaturePlot(result, features = "chr7_cnv_score")

# Combine
p1 | p2 | p3

Custom Visualizations

Extracting CNV Data

# Get raw CNV scores matrix
cnv_scores <- as.matrix(result@assays$CNVScores@data)

# Get trimmed (thresholded) scores
cnv_trimmed <- as.matrix(result@assays$CNVScoresTrimmed@data)

# Get window annotations
window_info <- result@assays$CNVScores@meta.features

Creating Custom Plots

library(ggplot2)
library(tidyr)

# Example: Plot CNV profile for a single cell
cell_profile <- cnv_scores[, "cell_1"]
window_positions <- 1:length(cell_profile)

ggplot(data.frame(pos = window_positions, cnv = cell_profile)) +

  geom_line(aes(x = pos, y = cnv), color = "steelblue") +
  geom_hline(yintercept = 0, linetype = "dashed", color = "gray50") +
  theme_minimal() +
  labs(
    title = "CNV Profile: Cell 1",
    x = "Genomic Position (window)",
    y = "CNV Score"
  )

Comparing Clusters

# Compare average CNV profiles between clusters
library(dplyr)

# Calculate mean CNV per cluster
cluster_means <- result@meta.data %>%
  group_by(cnv_clusters) %>%
  summarise(
    mean_cnv_fraction = mean(cnv_fraction),
    n_cells = n()
  )

# Plot
ggplot(cluster_means, aes(x = cnv_clusters, y = mean_cnv_fraction, fill = cnv_clusters)) +
  geom_bar(stat = "identity") +
  theme_minimal() +
  labs(
    title = "Mean CNV Fraction by Cluster",
    x = "CNV Cluster",
    y = "Mean CNV Fraction"
  )

Publication-Ready Figures

High-Resolution Export

# Save heatmap as PDF
pdf("cnv_heatmap.pdf", width = 12, height = 8)
plotCNVResults(
  seuratObj = result,
  referenceVar = "cell_type",
  tumorLabel = "Tumor"
)
dev.off()

# Save tree as PDF
pdf("cnv_tree.pdf", width = 8, height = 6)
plotCNVTree(
  tree = tree,
  seuratObj = result,
  referenceVar = "cell_type",
  tumorLabel = "Tumor"
)
dev.off()

Figure Panel Assembly

library(patchwork)
library(ggplot2)

# Create individual panels
p_umap <- DimPlot(result, group.by = "cnv_clusters")
p_spatial <- SpatialDimPlot(result, group.by = "cnv_clusters")

# Assemble figure
figure <- (p_umap | p_spatial) / 
          plot_spacer() +
          plot_layout(heights = c(2, 1))

# Save
ggsave("figure_panel.pdf", figure, width = 14, height = 10)

Color Palettes

Default Palettes

fastCNV uses carefully selected color palettes:

# CNV score colors (diverging)
# Blue (-) → White (0) → Red (+)

# Cluster colors (qualitative)
# Uses paletteer for distinct, colorblind-friendly colors
library(paletteer)
cluster_colors <- paletteer_d("ggsci::default_nejm")

Custom Palettes

# Define custom cluster colors
custom_colors <- c(
  "Clone_A" = "#E64B35",
  "Clone_B" = "#4DBBD5",
  "Clone_C" = "#00A087",
  "Clone_D" = "#3C5488"
)

# Apply to plot
DimPlot(result, group.by = "cnv_clusters", cols = custom_colors)

Tips and Best Practices

1. Heatmap Ordering

  • Order cells by cluster, then by similarity within cluster
  • Use dendrograms to show hierarchical relationships

2. Color Scaling

  • Center the color scale at zero
  • Use symmetric limits for amplifications and deletions

3. Resolution Selection

  • For overview: show all chromosomes
  • For detail: focus on specific regions of interest

4. Figure Legends

  • Always include color scale bar
  • Label chromosome boundaries clearly
  • Annotate key CNV events

Session Info

sessionInfo()
#> R version 4.4.0 (2024-04-24)
#> Platform: aarch64-apple-darwin20
#> Running under: macOS 15.6.1
#> 
#> Matrix products: default
#> BLAS:   /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRblas.0.dylib 
#> LAPACK: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.12.0
#> 
#> locale:
#> [1] C
#> 
#> time zone: Asia/Shanghai
#> tzcode source: internal
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> loaded via a namespace (and not attached):
#>  [1] digest_0.6.39     desc_1.4.3        R6_2.6.1          fastmap_1.2.0    
#>  [5] xfun_0.56         cachem_1.1.0      knitr_1.51        htmltools_0.5.9  
#>  [9] rmarkdown_2.30    lifecycle_1.0.5   cli_3.6.5         sass_0.4.10      
#> [13] pkgdown_2.1.3     textshaping_1.0.4 jquerylib_0.1.4   systemfonts_1.3.1
#> [17] compiler_4.4.0    tools_4.4.0       ragg_1.5.0        bslib_0.9.0      
#> [21] evaluate_1.0.5    yaml_2.3.12       otel_0.2.0        jsonlite_2.0.0   
#> [25] rlang_1.1.7       fs_1.6.6          htmlwidgets_1.6.4