diff --git a/DESCRIPTION b/DESCRIPTION index 2dfbdd5e..06725ccd 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -28,6 +28,7 @@ Suggests: BiocStyle, knitr, rmarkdown, testthat, + ggrepel, rgl Authors@R: c(person("Kim-Anh", "Le Cao", role = c("aut", "cre"), email = "kimanh.lecao@unimelb.edu.au"), diff --git a/R/internal_graphicModule.R b/R/internal_graphicModule.R index ff383493..df94e792 100644 --- a/R/internal_graphicModule.R +++ b/R/internal_graphicModule.R @@ -57,6 +57,7 @@ internal_graphicModule <- zlim, class.object, display.names, + repel = FALSE, legend, abline, star, @@ -258,11 +259,13 @@ internal_graphicModule <- { if (display.names) { - p = p +geom_point(data = subset(df, col == i & - df$Block == levels(df$Block)[j]),size = 0, shape = 0, + .geom_text <- .get_geom_text(repel = repel, style = style) + + p = p + geom_point(data = subset(df, col == i & + df$Block == levels(df$Block)[j]),size = ifelse(repel, 2, 0), color = unique(df[df$col == i & df$Block == - levels(df$Block)[j], ]$col))+ - geom_text(data = subset(df, col == i & df$Block == + levels(df$Block)[j], ]$col), shape = 16)+ + .geom_text(data = subset(df, col == i & df$Block == levels(df$Block)[j]), aes(label = names), color = df[df$col == i & df$Block == diff --git a/R/plotIndiv.R b/R/plotIndiv.R index 731f8a7c..c67e4a15 100644 --- a/R/plotIndiv.R +++ b/R/plotIndiv.R @@ -66,6 +66,7 @@ #' @param ind.names either a character vector of names for the individuals to #' be plotted, or \code{FALSE} for no names. If \code{TRUE}, the row names of #' the first (or second) data matrix is used as names (see Details). +#' @template arg/repel #' @param group factor indicating the group membership for each sample, useful #' for ellipse plots. Coded as default for the supervised methods \code{PLS-DA, #' SPLS-DA,sGCCDA}, but needs to be input for the unsupervised methods @@ -160,6 +161,7 @@ check.input.plotIndiv <- blocks = NULL, # to choose which block data to plot, when using GCCA module ind.names = TRUE, + repel = repel, style = "ggplot2", # can choose between graphics, 3d, lattice or ggplot2 #study = "global", @@ -192,6 +194,7 @@ check.input.plotIndiv <- if (!style %in% c("ggplot2", "lattice", "graphics", "3d")) stop("'style' must be one of 'ggplot2', 'lattice', 'graphics' or '3d' .", call. = FALSE) + #-- axes.box choices = c("box", "bbox", "both") axes.box = choices[pmatch(axes.box, choices)] diff --git a/R/plotIndiv.pls.R b/R/plotIndiv.pls.R index f42e4f31..20a34d30 100644 --- a/R/plotIndiv.pls.R +++ b/R/plotIndiv.pls.R @@ -9,6 +9,7 @@ plotIndiv.mixo_pls <- comp = NULL, rep.space = NULL, ind.names = TRUE, + repel = FALSE, group, col.per.group, style = "ggplot2", @@ -103,7 +104,7 @@ plotIndiv.mixo_pls <- stop("'background' must have been obtained with the 'background.predict' function") #-- check inputs - check = check.input.plotIndiv(object = object, comp = comp , blocks = blocks, ind.names = ind.names, + check = check.input.plotIndiv(object = object, comp = comp , blocks = blocks, ind.names = ind.names, repel = repel, style = style, ellipse = ellipse, ellipse.level = ellipse.level, centroid = centroid, star = star, legend = legend, X.label = X.label, Y.label = Y.label, Z.label = Z.label, abline = abline, xlim = xlim, ylim = ylim, alpha = alpha, axes.box = axes.box, plot_parameters = plot_parameters) @@ -167,7 +168,7 @@ plotIndiv.mixo_pls <- #call plot module (ggplot2, lattice, graphics, 3d) res = internal_graphicModule(df = df, centroid = centroid, col.per.group = col.per.group, title = title, X.label = X.label, Y.label = Y.label, Z.label = Z.label, xlim = xlim, ylim = ylim, class.object = class(object), - display.names = display.names, legend = legend, abline = abline, star = star, + display.names = display.names, repel = repel, legend = legend, abline = abline, star = star, ellipse = ellipse, df.ellipse = df.ellipse, style = style, layout = layout, #missing.col = missing.col, axes.box = axes.box, plot_parameters = plot_parameters, alpha = alpha, background = background) diff --git a/R/plotVar.R b/R/plotVar.R index 6b1cbead..2e122b64 100644 --- a/R/plotVar.R +++ b/R/plotVar.R @@ -50,6 +50,7 @@ #' @param var.names either a character vector of names for the variables to be #' plotted, or \code{FALSE} for no names. If \code{TRUE}, the col names of the #' first (or second) data matrix is used as names. +#' @template arg/repel #' @param blocks for an object of class \code{"rgcca"} or \code{"sgcca"}, a #' numerical vector indicating the block variables to display. #' @param X.label x axis titles. @@ -109,6 +110,7 @@ plotVar <- comp.select = comp, plot = TRUE, var.names = NULL, + repel = FALSE, blocks = NULL, # to choose which block data to plot, when using GCCA module X.label = NULL, @@ -673,14 +675,23 @@ plotVar <- for (i in levels(df$Block)) p = p + geom_point(data = subset(df, df$Block == i), size = 0, shape = 0) + .geom_text <- .get_geom_text(repel = repel, style = style) + #-- Display sample or var.names for (i in seq_len(length(var.names))){ if (var.names[i]) { - p = p + geom_text(data = df[c((ind.group[i] + 1) : ind.group[i + 1]), ], + p = p + .geom_text(data = df[c((ind.group[i] + 1) : ind.group[i + 1]), ], label = df[c((ind.group[i] + 1) : ind.group[i + 1]), "names"], size = df[c((ind.group[i] + 1) : ind.group[i + 1]), "cex"], color = df[c((ind.group[i] + 1) : ind.group[i + 1]), "col"], fontface = df[c((ind.group[i] + 1) : ind.group[i + 1]), "font"]) + + if (repel) { + p = p + geom_point(data = df[c((ind.group[i] + 1) : ind.group[i + 1]), ], + size = 2, + shape = 16, + color = df[c((ind.group[i] + 1) : ind.group[i + 1]), "col"]) + } } else { p = p + geom_point(data = df[c((ind.group[i] + 1) : ind.group[i + 1]), ], size = df[c((ind.group[i] + 1) : ind.group[i + 1]), "cex"], diff --git a/R/utils.R b/R/utils.R index 02e75921..b592d369 100644 --- a/R/utils.R +++ b/R/utils.R @@ -665,3 +665,37 @@ mixo_gg.theme <- function(cex, x.angle = 90, background.fill = 'grey97', subtitl else sprintf("\033[33m%s\033[39m", char) } + + + +#' get geom_text based on repel arg +#' +#' @param repel Logical repel arg +#' @param style Plot style. See ?plotIndiv +#' @noRd +#' @return geom_text function variation +#' @keywords Internal +.get_geom_text <- function(repel, style = 'ggplot2') +{ + if (isTRUE(repel)) + { + + if (style != 'ggplot2') + message("repel can only be used with style = 'ggplot2'") + + repel <- FALSE + if(repel && requireNamespace("ggrepel", quietly = TRUE) == FALSE) + stop("the 'ggrepel' package is required with repel=TRUE", call. = FALSE) + + } + + if (repel) + { + geom_text_ <- ggplot2::geom_text + } else { + out <- ggrepel::geom_text_repel + formals(out)$max.overlaps <- Inf + } + geom_text_ +} + diff --git a/man-roxygen/arg/repel.R b/man-roxygen/arg/repel.R new file mode 100644 index 00000000..2746bf7c --- /dev/null +++ b/man-roxygen/arg/repel.R @@ -0,0 +1,2 @@ +#' @param repel (if ind.names=TRUE), Logical indicating whether to spread the +#' names away from each other in the plot. diff --git a/man/plotIndiv.Rd b/man/plotIndiv.Rd index eb490f11..c514b957 100644 --- a/man/plotIndiv.Rd +++ b/man/plotIndiv.Rd @@ -208,6 +208,7 @@ plotIndiv(object, ...) comp = NULL, rep.space = NULL, ind.names = TRUE, + repel = FALSE, group, col.per.group, style = "ggplot2", @@ -456,6 +457,9 @@ for the legend.} \item{legend.title.pch}{title of the second legend created by \code{pch}, if any.} +\item{repel}{(if ind.names=TRUE), Logical indicating whether to spread the +names away from each other in the plot.} + \item{background}{color the background by the predicted class, see \code{\link{background.predict}}} diff --git a/man/plotVar.Rd b/man/plotVar.Rd index 8c94ca9f..68bd16c1 100644 --- a/man/plotVar.Rd +++ b/man/plotVar.Rd @@ -19,6 +19,7 @@ plotVar( comp.select = comp, plot = TRUE, var.names = NULL, + repel = FALSE, blocks = NULL, X.label = NULL, Y.label = NULL, @@ -59,6 +60,9 @@ summaries which the plots are based on are returned.} plotted, or \code{FALSE} for no names. If \code{TRUE}, the col names of the first (or second) data matrix is used as names.} +\item{repel}{(if ind.names=TRUE), Logical indicating whether to spread the +names away from each other in the plot.} + \item{blocks}{for an object of class \code{"rgcca"} or \code{"sgcca"}, a numerical vector indicating the block variables to display.}