--- title: "Visualization Guide" author: "Zaoqu Liu" date: "`r Sys.Date()`" output: rmarkdown::html_vignette: toc: true toc_depth: 3 vignette: > %\VignetteIndexEntry{Visualization Guide} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include=FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 8, fig.height = 6, message = FALSE, warning = FALSE ) ``` ## Introduction Effective visualization is crucial for understanding and communicating scGate results. This guide covers various visualization techniques for exploring gating results, signature scores, and model structures. ```{r load-packages} library(scGate) library(Seurat) library(ggplot2) library(patchwork) ``` ## Preparing Example Data ```{r prepare-data, eval=FALSE} # Load example data data(query.seurat) # Create a multi-level model model <- gating_model(level = 1, name = "Immune", signature = c("PTPRC")) model <- gating_model(model = model, level = 2, name = "Tcell", signature = c("CD3D", "CD3E")) # Apply scGate with level saving query.seurat <- scGate( data = query.seurat, model = model, reduction = "pca", save.levels = TRUE ) ``` ## Basic Visualizations ### Gating Results on UMAP The most common visualization shows Pure vs Impure cells: ```{r basic-dimplot, eval=FALSE, fig.width=10, fig.height=4} # Side-by-side comparison p1 <- DimPlot(query.seurat, group.by = "cell_type", label = TRUE, repel = TRUE) + ggtitle("Original Cell Types") + NoLegend() p2 <- DimPlot(query.seurat, group.by = "is.pure", cols = c("Pure" = "#00ae60", "Impure" = "#e0e0e0")) + ggtitle("scGate Classification") + theme(legend.position = "bottom") p1 + p2 ``` ### Signature Score Visualization Visualize UCell scores as a continuous gradient: ```{r score-featureplot, eval=FALSE, fig.width=10, fig.height=4} # Find UCell score columns ucell_cols <- grep("_UCell$", colnames(query.seurat@meta.data), value = TRUE) print(paste("Available UCell scores:", paste(ucell_cols, collapse = ", "))) # Plot signature scores if (length(ucell_cols) > 0) { p1 <- FeaturePlot(query.seurat, features = ucell_cols[1], cols = c("gray95", "navy")) + ggtitle(paste(ucell_cols[1], "Score")) p2 <- DimPlot(query.seurat, group.by = "is.pure", cols = c("Pure" = "#00ae60", "Impure" = "gray80")) print(p1 + p2) } ``` ## Level-by-Level Visualization ### Using plot_levels() scGate provides a built-in function to visualize results at each gating level: ```{r plot-levels, eval=FALSE, fig.width=10, fig.height=4} # Get plots for each level level_plots <- plot_levels(query.seurat) # Combine plots if (length(level_plots) > 0) { wrap_plots(level_plots, ncol = length(level_plots)) } ``` ### Custom Level Visualization ```{r custom-levels, eval=FALSE, fig.width=12, fig.height=4} # Find level columns level_cols <- grep("^is.pure\\.level", colnames(query.seurat@meta.data), value = TRUE) if (length(level_cols) >= 1) { plots <- list() for (i in seq_along(level_cols)) { col <- level_cols[i] level_name <- gsub("is.pure\\.", "", col) plots[[i]] <- DimPlot(query.seurat, group.by = col, cols = c("Pure" = "#00ae60", "Impure" = "#e0e0e0")) + ggtitle(paste("Level:", level_name)) + theme(legend.position = "bottom") } # Add final result plots[[length(plots) + 1]] <- DimPlot(query.seurat, group.by = "is.pure", cols = c("Pure" = "#00ae60", "Impure" = "#e0e0e0")) + ggtitle("Final Result") + theme(legend.position = "bottom") wrap_plots(plots, ncol = min(3, length(plots))) } ``` ## Score Distribution Analysis ### Violin Plots ```{r violin-plots, eval=FALSE, fig.width=8, fig.height=5} if (length(ucell_cols) > 0) { # Prepare data plot_data <- data.frame( score = query.seurat@meta.data[[ucell_cols[1]]], classification = query.seurat$is.pure, cell_type = query.seurat$cell_type ) # Violin plot by classification ggplot(plot_data, aes(x = classification, y = score, fill = classification)) + geom_violin(alpha = 0.7, scale = "width") + geom_boxplot(width = 0.15, fill = "white", alpha = 0.9) + scale_fill_manual(values = c("Pure" = "#00ae60", "Impure" = "#808080")) + labs(title = paste("Distribution of", ucell_cols[1]), x = "Classification", y = "UCell Score") + theme_minimal() + theme(legend.position = "none", plot.title = element_text(hjust = 0.5, face = "bold")) } ``` ### Density Plots by Cell Type ```{r density-celltype, eval=FALSE, fig.width=10, fig.height=5} if (length(ucell_cols) > 0) { ggplot(plot_data, aes(x = score, fill = cell_type)) + geom_density(alpha = 0.5) + geom_vline(xintercept = 0.2, linetype = "dashed", color = "red", linewidth = 1) + labs(title = paste("Score Distribution by Cell Type"), subtitle = "Red dashed line = default threshold (0.2)", x = "UCell Score", y = "Density") + theme_minimal() + theme(legend.position = "right") } ``` ## UCell Score Ridge Plots ### Using plot_UCell_scores() scGate provides a built-in function for ridge plots: ```{r ridge-plots, eval=FALSE, fig.width=8, fig.height=5} # Plot UCell score distributions tryCatch({ plot_UCell_scores(query.seurat, model, combine = TRUE) }, error = function(e) { message("Ridge plot requires ggridges package") }) ``` ## Confusion Matrix Visualization ### Creating a Confusion Matrix ```{r confusion-matrix, eval=FALSE, fig.width=7, fig.height=6} # Compare scGate results with original annotations confusion_data <- table( Original = query.seurat$cell_type, scGate = query.seurat$is.pure ) # Convert to data frame for plotting conf_df <- as.data.frame(confusion_data) names(conf_df) <- c("Original", "scGate", "Count") # Calculate percentages within each original cell type conf_df <- conf_df %>% dplyr::group_by(Original) %>% dplyr::mutate(Percentage = Count / sum(Count) * 100) %>% dplyr::ungroup() # Create heatmap ggplot(conf_df, aes(x = scGate, y = Original, fill = Percentage)) + geom_tile(color = "white", linewidth = 0.5) + geom_text(aes(label = sprintf("%.0f%%\n(n=%d)", Percentage, Count)), color = "black", size = 3) + scale_fill_gradient2(low = "white", mid = "#a8d5ba", high = "#00ae60", midpoint = 50, limits = c(0, 100)) + labs(title = "scGate Classification by Cell Type", x = "scGate Result", y = "Original Annotation", fill = "Percentage") + theme_minimal() + theme(axis.text.x = element_text(angle = 0), plot.title = element_text(hjust = 0.5, face = "bold"), panel.grid = element_blank()) ``` ## Publication-Ready Figures ### Combined Summary Figure ```{r publication-figure, eval=FALSE, fig.width=12, fig.height=10} # Create a comprehensive figure if (length(ucell_cols) > 0) { # Panel A: UMAP with cell types pA <- DimPlot(query.seurat, group.by = "cell_type", label = TRUE, repel = TRUE, label.size = 3) + ggtitle("A. Original Annotation") + NoLegend() + theme(plot.title = element_text(face = "bold")) # Panel B: UMAP with scGate result pB <- DimPlot(query.seurat, group.by = "is.pure", cols = c("Pure" = "#00ae60", "Impure" = "#e0e0e0")) + ggtitle("B. scGate Classification") + theme(plot.title = element_text(face = "bold"), legend.position = "bottom") # Panel C: UCell scores pC <- FeaturePlot(query.seurat, features = ucell_cols[1], cols = c("gray95", "navy")) + ggtitle("C. Signature Score") + theme(plot.title = element_text(face = "bold")) # Panel D: Score distribution pD <- ggplot(plot_data, aes(x = classification, y = score, fill = classification)) + geom_violin(alpha = 0.7) + geom_boxplot(width = 0.15, fill = "white") + scale_fill_manual(values = c("Pure" = "#00ae60", "Impure" = "#808080")) + labs(title = "D. Score Distribution", x = "", y = "UCell Score") + theme_minimal() + theme(legend.position = "none", plot.title = element_text(face = "bold")) # Combine (pA | pB) / (pC | pD) } ``` ## Color Palettes ### Recommended Color Schemes ```{r color-palettes, fig.width=8, fig.height=3} # Define color palettes palettes <- list( "Default" = c("Pure" = "#00ae60", "Impure" = "#e0e0e0"), "Vibrant" = c("Pure" = "#2ecc71", "Impure" = "#95a5a6"), "Professional" = c("Pure" = "#27ae60", "Impure" = "#bdc3c7"), "High Contrast" = c("Pure" = "#00ff00", "Impure" = "#808080") ) # Display palettes par(mfrow = c(1, 4), mar = c(2, 1, 2, 1)) for (name in names(palettes)) { barplot(c(1, 1), col = palettes[[name]], main = name, names.arg = c("Pure", "Impure"), border = NA) } ``` ## Exporting Figures ### High-Resolution Export ```{r export-example, eval=FALSE} # Save as PDF (vector format, best for publications) ggsave("scgate_results.pdf", width = 10, height = 8, dpi = 300) # Save as PNG (raster format, good for presentations) ggsave("scgate_results.png", width = 10, height = 8, dpi = 300) # Save as TIFF (required by some journals) ggsave("scgate_results.tiff", width = 10, height = 8, dpi = 300, compression = "lzw") ``` ## Tips for Effective Visualization 1. **Use consistent colors** across all figures 2. **Include scale bars** and legends 3. **Show both overview and detail** views 4. **Compare with ground truth** when available 5. **Use appropriate figure sizes** for your target medium ## Session Info ```{r session-info} sessionInfo() ```