From 24ef9b11d1f69c2643291fc6a865f6a7cb67b959 Mon Sep 17 00:00:00 2001 From: danoguevara Date: Sun, 22 Jun 2025 00:47:29 -0400 Subject: [PATCH 1/3] Rename to VSB function, upload nice_Volcano --- NAMESPACE | 3 +- R/{nice_BSV.R => nice_VSB.R} | 10 +-- R/nice_Volcano.R | 127 +++++++++++++++++++++++++++++++ man/{nice_BSV.Rd => nice_VSB.Rd} | 10 +-- man/volcano_plot.Rd | 57 ++++++++++++++ 5 files changed, 196 insertions(+), 11 deletions(-) rename R/{nice_BSV.R => nice_VSB.R} (95%) create mode 100644 R/nice_Volcano.R rename man/{nice_BSV.Rd => nice_VSB.Rd} (93%) create mode 100644 man/volcano_plot.Rd diff --git a/NAMESPACE b/NAMESPACE index d8ad75f..2b3d5a8 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -5,15 +5,16 @@ export(detect_filter) export(get_annotations) export(get_stars) export(gsea_barplot) -export(nice_BSV) export(nice_KM) export(nice_PCA) export(nice_UMAP) +export(nice_VSB) export(nice_tSNE) export(power_analysis) export(save_results) export(split_cases) export(tpm) +export(volcano_plot) import(ggplot2) importFrom(magrittr,"%>%") importFrom(rlang,.data) diff --git a/R/nice_BSV.R b/R/nice_VSB.R similarity index 95% rename from R/nice_BSV.R rename to R/nice_VSB.R index 0b80c81..97be5c6 100644 --- a/R/nice_BSV.R +++ b/R/nice_VSB.R @@ -1,8 +1,8 @@ -####################### -# Function nice_BSV.R # -####################### +##################### +# Function nice_VSB # +##################### -#' Function to make Box-Scatter-Violin plots. +#' Function to make Violin-Scatter-Box plots. #' #' This function will make a Boxplot, using a DEseq object. #' It will show the data points on top with a small deviation (jitter) for a better visualization. @@ -27,7 +27,7 @@ #' @importFrom rlang .data #' @export -nice_BSV <- function (object = NULL, annotations, variables = c(fill = "VarFill", shape = "VarShape"), +nice_VSB <- function (object = NULL, annotations, variables = c(fill = "VarFill", shape = "VarShape"), genename = NULL, symbol = NULL, labels = c("N", "P", "R", "M"), categories = c("normal", "primary", "recurrence", "metastasis"), colors = NULL, shapes = NULL, markersize = NULL, alpha = 0.8, jitter = 0.2, diff --git a/R/nice_Volcano.R b/R/nice_Volcano.R new file mode 100644 index 0000000..5652ff3 --- /dev/null +++ b/R/nice_Volcano.R @@ -0,0 +1,127 @@ +######################### +# Function nice_Volcano # +######################### + +#' Function to draw Volcano plots. +#' +#' Volcano plot with configurable point shapes and threshold annotations: +#' * Automatic triangle shapes for points above a user-defined y-axis limit (and a matching legend entry). +#' * Horizontal dashed line at one or more significance thresholds, annotated with its value. +#' * Vertical dashed lines at log-fold-change cutoffs, shown as custom x-axis ticks. +#' +#' @param results A data frame containing at least one column of effect sizes (e.g. log₂FC) and one column of significance (e.g. FDR). +#' @param x_var Name of the column in `results` to plot on the x-axis (e.g. log₂FC). +#' @param y_var Name of the column in `results` to plot on the y-axis (e.g. FDR). +#' @param label_var to be defined. +#' @param title title. +#' @param colors colors. +#' @param x_range X-axis range of values. +#' @param y_max Maximum values of y-axis. +#' @param cutoff_x to be defined. +#' @param cutoff_y to be defined. +#' @param nice_x to be defined. +#' @param nice_y to be defined. +#' @param genes Vector of genes to label in the plot. Default: NULL. +#' @import ggplot2 +#' @importFrom rlang .data +#' @export + +volcano_plot <- function(results, x_range = 9, y_max = 8, cutoff_y = 0.05, cutoff_x = 1, + nice_y = NULL, nice_x = NULL, y_var, x_var, label_var, + title, colors = c("red", "grey70", "blue"), genes = NULL) +{ + if (!requireNamespace("ggrepel", quietly = TRUE)) { + stop( + "Package \"ggrepel\" must be installed to use this function.", + call. = FALSE + ) + } + + # Fixed variables + if (is.null(nice_y)) sig_nice <- cutoff_y*0.2 else sig_nice <- nice_y + + if (is.null(nice_x)) chg_nice <- cutoff_x*4 else chg_nice <- nice_x + + # Manage data + d.volcano <- data.frame(results) + d.volcano <- d.volcano[!is.na(d.volcano[, y_var]), ] + d.volcano[d.volcano[, y_var] < 10**-y_max, y_var] <- 10**-y_max + + d.volcano$colors <- rep("other", nrow(d.volcano)) + d.volcano$colors[(d.volcano[, x_var] >= cutoff_x & d.volcano[, y_var] < cutoff_y)] <- "over" + d.volcano$colors[(d.volcano[, x_var] <= -cutoff_x & d.volcano[, y_var] < cutoff_y)] <- "under" + + d.volcano$shapes <- rep("nohits", nrow(d.volcano)) + d.volcano$shapes[d.volcano[, y_var] <= 10**-y_max] <- "hits" + + # Condition for labeling + if (is.null(genes)) { + cond <- d.volcano[, y_var] < sig_nice & abs(d.volcano[, x_var]) > chg_nice + } else { + cond <- d.volcano[, label_var] %in% genes + } + + y_min <- min(-log10(d.volcano[[y_var]])) + + # Plot + p.volcano <- ggplot() + theme_bw() + + scale_y_continuous(expand = c(0, 0.2), + limits = c(y_min, y_max), + breaks = seq(round(y_min, digits = 0), y_max, by = 1), + minor_breaks = seq(round(y_min, digits = 0), y_max, by = 0.5)) + + scale_x_continuous(expand = c(0, 0), + limits = c(-x_range, x_range), + breaks = seq(-x_range, x_range, by = x_range*0.5), + minor_breaks = seq(-x_range, x_range, by = x_range*0.1)) + + + # Datapoints, in different colors: + geom_point(data = d.volcano, + aes(x = .data[[x_var]], y = -log10(.data[[y_var]]), fill = colors, shape = .data[["shapes"]]), + size = 5.5, color = "gray10", alpha = 0.4, show.legend = TRUE) + + + # Vertical lines and labels: + geom_vline(xintercept = c(-cutoff_x, cutoff_x), color = "grey20", alpha = 0.9, linetype = 2, linewidth = 1.2) + + + # Horizontal line and label: + geom_hline(yintercept = -log10(cutoff_y), color = "grey20", alpha = 0.9, linetype = 2, linewidth = 1.2) + + geom_text(aes(x = -6, y = -log10(cutoff_y) + 0.5, label = paste("q =", cutoff_y)), color = "grey20", size = 6.2) + + + # Color settings + scale_fill_manual(name = "Expression", + values = c("over" = colors[1], "other" = colors[2], "under" = colors[3]), + breaks = c("over", "other", "under"), + labels = c("Up-regulated", "No difference", "Down-regulated"), + guide = guide_legend(override.aes = aes(shape = 21, size = 5, alpha = 1))) + + + # Change outliers shapes + scale_shape_manual(name = "Shape", + values = c("hits" = 24, "nohits" = 21), + guide = guide_legend(override.aes = list(fill = "white", size = 5, alpha = 1)), + labels = c(bquote(FDR <= 10^-.(y_max)), bquote(FDR > 10^-.(y_max)))) + + + # Labels for detectable genes + ggrepel::geom_label_repel(data = d.volcano[cond, ], + aes(x = .data[[x_var]], y = -log10(.data[[y_var]]), label = .data[[label_var]]), + inherit.aes = FALSE, parse = FALSE, max.iter = 5000, color = "black", size = 5, + segment.alpha = 1.5, box.padding = unit(0.8, "lines"), min.segment.length = unit(0.01, "lines")) + + + # Axis labels: + labs(x = expression("log"[2]*"(Fold Change)"), + y = expression("-log"[10]*"(FDR)"), + title = title) + + + # Labels size + theme(plot.title = element_text(size = 22, hjust = 0.5), + axis.text.x = element_text(size = 18), + axis.text.y = element_text(size = 18), + axis.title.x = element_text(size = 22), + axis.title.y = element_text(size = 22), + legend.text = element_text(size = 14), + legend.title = element_text(size= 16), + legend.box.background = element_rect(color = "black"), + legend.background = element_blank(), + legend.position = "inside", + legend.position.inside = c(0.15, 0.75)) + + return(p.volcano) +} diff --git a/man/nice_BSV.Rd b/man/nice_VSB.Rd similarity index 93% rename from man/nice_BSV.Rd rename to man/nice_VSB.Rd index ba5a925..c7ad3c4 100644 --- a/man/nice_BSV.Rd +++ b/man/nice_VSB.Rd @@ -1,10 +1,10 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/nice_BSV.R -\name{nice_BSV} -\alias{nice_BSV} -\title{Function to make Box-Scatter-Violin plots.} +% Please edit documentation in R/nice_VSB.R +\name{nice_VSB} +\alias{nice_VSB} +\title{Function to make Violin-Scatter-Box plots.} \usage{ -nice_BSV( +nice_VSB( object = NULL, annotations, variables = c(fill = "VarFill", shape = "VarShape"), diff --git a/man/volcano_plot.Rd b/man/volcano_plot.Rd new file mode 100644 index 0000000..b61c39e --- /dev/null +++ b/man/volcano_plot.Rd @@ -0,0 +1,57 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/nice_Volcano.R +\name{volcano_plot} +\alias{volcano_plot} +\title{Function to draw Volcano plots.} +\usage{ +volcano_plot( + results, + x_range = 9, + y_max = 8, + cutoff_y = 0.05, + cutoff_x = 1, + nice_y = NULL, + nice_x = NULL, + y_var, + x_var, + label_var, + title, + colors = c("red", "grey70", "blue"), + genes = NULL +) +} +\arguments{ +\item{results}{A data frame containing at least one column of effect sizes (e.g. log₂FC) and one column of significance (e.g. FDR).} + +\item{x_range}{X-axis range of values.} + +\item{y_max}{Maximum values of y-axis.} + +\item{cutoff_y}{to be defined.} + +\item{cutoff_x}{to be defined.} + +\item{nice_y}{to be defined.} + +\item{nice_x}{to be defined.} + +\item{y_var}{Name of the column in \code{results} to plot on the y-axis (e.g. FDR).} + +\item{x_var}{Name of the column in \code{results} to plot on the x-axis (e.g. log₂FC).} + +\item{label_var}{to be defined.} + +\item{title}{title.} + +\item{colors}{colors.} + +\item{genes}{Vector of genes to label in the plot. Default: NULL.} +} +\description{ +Volcano plot with configurable point shapes and threshold annotations: +\itemize{ +\item Automatic triangle shapes for points above a user-defined y-axis limit (and a matching legend entry). +\item Horizontal dashed line at one or more significance thresholds, annotated with its value. +\item Vertical dashed lines at log-fold-change cutoffs, shown as custom x-axis ticks. +} +} From b33cf55898cbd1f2f67b7a7f2fcd03955cc1a04b Mon Sep 17 00:00:00 2001 From: danoguevara Date: Sun, 27 Jul 2025 10:18:53 -0500 Subject: [PATCH 2/3] First version of nice_Volcano --- R/nice_Volcano.R | 10 +++++----- man/volcano_plot.Rd | 3 +++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/R/nice_Volcano.R b/R/nice_Volcano.R index 5652ff3..b3e3919 100644 --- a/R/nice_Volcano.R +++ b/R/nice_Volcano.R @@ -13,6 +13,7 @@ #' @param x_var Name of the column in `results` to plot on the x-axis (e.g. log₂FC). #' @param y_var Name of the column in `results` to plot on the y-axis (e.g. FDR). #' @param label_var to be defined. +#' @param legend Logical. Control legend display. Default: TRUE. #' @param title title. #' @param colors colors. #' @param x_range X-axis range of values. @@ -27,7 +28,7 @@ #' @export volcano_plot <- function(results, x_range = 9, y_max = 8, cutoff_y = 0.05, cutoff_x = 1, - nice_y = NULL, nice_x = NULL, y_var, x_var, label_var, + nice_y = NULL, nice_x = NULL, y_var, x_var, label_var, legend = TRUE, title, colors = c("red", "grey70", "blue"), genes = NULL) { if (!requireNamespace("ggrepel", quietly = TRUE)) { @@ -74,17 +75,16 @@ volcano_plot <- function(results, x_range = 9, y_max = 8, cutoff_y = 0.05, cutof breaks = seq(-x_range, x_range, by = x_range*0.5), minor_breaks = seq(-x_range, x_range, by = x_range*0.1)) + - # Datapoints, in different colors: geom_point(data = d.volcano, aes(x = .data[[x_var]], y = -log10(.data[[y_var]]), fill = colors, shape = .data[["shapes"]]), - size = 5.5, color = "gray10", alpha = 0.4, show.legend = TRUE) + + size = 5.5, color = "gray10", alpha = 0.4, show.legend = legend) + # Vertical lines and labels: geom_vline(xintercept = c(-cutoff_x, cutoff_x), color = "grey20", alpha = 0.9, linetype = 2, linewidth = 1.2) + # Horizontal line and label: geom_hline(yintercept = -log10(cutoff_y), color = "grey20", alpha = 0.9, linetype = 2, linewidth = 1.2) + - geom_text(aes(x = -6, y = -log10(cutoff_y) + 0.5, label = paste("q =", cutoff_y)), color = "grey20", size = 6.2) + + geom_text(aes(x = -x_range*0.7, y = -log10(cutoff_y) + 0.5, label = paste("q =", cutoff_y)), color = "grey20", size = 6.2) + # Color settings scale_fill_manual(name = "Expression", @@ -103,7 +103,7 @@ volcano_plot <- function(results, x_range = 9, y_max = 8, cutoff_y = 0.05, cutof ggrepel::geom_label_repel(data = d.volcano[cond, ], aes(x = .data[[x_var]], y = -log10(.data[[y_var]]), label = .data[[label_var]]), inherit.aes = FALSE, parse = FALSE, max.iter = 5000, color = "black", size = 5, - segment.alpha = 1.5, box.padding = unit(0.8, "lines"), min.segment.length = unit(0.01, "lines")) + + segment.alpha = 1.5, box.padding = grid::unit(0.8, "lines"), min.segment.length = grid::unit(0.01, "lines")) + # Axis labels: labs(x = expression("log"[2]*"(Fold Change)"), diff --git a/man/volcano_plot.Rd b/man/volcano_plot.Rd index b61c39e..4c8a313 100644 --- a/man/volcano_plot.Rd +++ b/man/volcano_plot.Rd @@ -15,6 +15,7 @@ volcano_plot( y_var, x_var, label_var, + legend = TRUE, title, colors = c("red", "grey70", "blue"), genes = NULL @@ -41,6 +42,8 @@ volcano_plot( \item{label_var}{to be defined.} +\item{legend}{Logical. Control legend display. Default: TRUE.} + \item{title}{title.} \item{colors}{colors.} From 7180fd12ce52a73f9007b8e07a08b4d6c9032da7 Mon Sep 17 00:00:00 2001 From: danoguevara Date: Sun, 27 Jul 2025 10:37:04 -0500 Subject: [PATCH 3/3] Rename export nice_Volcano --- NAMESPACE | 2 +- R/nice_Volcano.R | 2 +- man/{volcano_plot.Rd => nice_Volcano.Rd} | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) rename man/{volcano_plot.Rd => nice_Volcano.Rd} (96%) diff --git a/NAMESPACE b/NAMESPACE index 2b3d5a8..7b96c99 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -9,12 +9,12 @@ export(nice_KM) export(nice_PCA) export(nice_UMAP) export(nice_VSB) +export(nice_Volcano) export(nice_tSNE) export(power_analysis) export(save_results) export(split_cases) export(tpm) -export(volcano_plot) import(ggplot2) importFrom(magrittr,"%>%") importFrom(rlang,.data) diff --git a/R/nice_Volcano.R b/R/nice_Volcano.R index b3e3919..cd8d4b6 100644 --- a/R/nice_Volcano.R +++ b/R/nice_Volcano.R @@ -27,7 +27,7 @@ #' @importFrom rlang .data #' @export -volcano_plot <- function(results, x_range = 9, y_max = 8, cutoff_y = 0.05, cutoff_x = 1, +nice_Volcano <- function(results, x_range = 9, y_max = 8, cutoff_y = 0.05, cutoff_x = 1, nice_y = NULL, nice_x = NULL, y_var, x_var, label_var, legend = TRUE, title, colors = c("red", "grey70", "blue"), genes = NULL) { diff --git a/man/volcano_plot.Rd b/man/nice_Volcano.Rd similarity index 96% rename from man/volcano_plot.Rd rename to man/nice_Volcano.Rd index 4c8a313..b40a3db 100644 --- a/man/volcano_plot.Rd +++ b/man/nice_Volcano.Rd @@ -1,10 +1,10 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/nice_Volcano.R -\name{volcano_plot} -\alias{volcano_plot} +\name{nice_Volcano} +\alias{nice_Volcano} \title{Function to draw Volcano plots.} \usage{ -volcano_plot( +nice_Volcano( results, x_range = 9, y_max = 8,