diff --git a/DESCRIPTION b/DESCRIPTION index 9a2b0e295..8ed545907 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: Seurat -Version: 3.1.3 -Date: 2020-02-07 +Version: 3.1.4 +Date: 2020-02-26 Title: Tools for Single Cell Genomics -Description: A toolkit for quality control, analysis, and exploration of single cell RNA sequencing data. 'Seurat' aims to enable users to identify and interpret sources of heterogeneity from single cell transcriptomic measurements, and to integrate diverse types of single cell data. See Satija R, Farrell J, Gennert D, et al (2015) , Macosko E, Basu A, Satija R, et al (2015) , and Butler A and Satija R (2017) for more details. +Description: A toolkit for quality control, analysis, and exploration of single cell RNA sequencing data. 'Seurat' aims to enable users to identify and interpret sources of heterogeneity from single cell transcriptomic measurements, and to integrate diverse types of single cell data. See Satija R, Farrell J, Gennert D, et al (2015) , Macosko E, Basu A, Satija R, et al (2015) , and Butler A and Satija R (2017) for more details. Please note: SDMTools is available is available from the CRAN archives with install.packages("https://cran.rstudio.com//src/contrib/Archive/SDMTools/SDMTools_1.1-221.2.tar.gz", repos = NULL); it is not in the standard repositories. Authors@R: c( person(given = 'Rahul', family = 'Satija', email = 'rsatija@nygenome.org', role = 'aut', comment = c(ORCID = '0000-0001-9448-8833')), person(given = 'Andrew', family = 'Butler', email = 'abutler@nygenome.org', role = 'aut', comment = c(ORCID = '0000-0003-3608-0463')), @@ -43,6 +43,7 @@ Imports: MASS, Matrix (>= 1.2-14), metap, + patchwork, pbapply, plotly, png, diff --git a/NAMESPACE b/NAMESPACE index a0881cfcc..52dbc5bac 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -482,6 +482,7 @@ importFrom(methods,setOldClass) importFrom(methods,signature) importFrom(methods,slot) importFrom(methods,slotNames) +importFrom(patchwork,wrap_plots) importFrom(pbapply,pbapply) importFrom(pbapply,pblapply) importFrom(pbapply,pbsapply) diff --git a/NEWS.md b/NEWS.md index 89a297dd0..fe5af7825 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,7 +2,12 @@ All notable changes to Seurat will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) -## [3.1.3] = 2020-02-07 +## [3.1.4] - 2020-02-20 +### Changes +- Fixes to `DoHeatmap` to remain compatible with ggplot2 v3.3 +- Adoption of `patchwork` framework to replace `CombinePlots` + +## [3.1.3] - 2020-02-07 ### Added - New system agnostic `Which` function to address problems with FItSNE on Windows diff --git a/R/convenience.R b/R/convenience.R index 914596938..307268d51 100644 --- a/R/convenience.R +++ b/R/convenience.R @@ -19,6 +19,8 @@ PCHeatmap <- function(object, ...) { return(do.call(what = 'DimHeatmap', args = args)) } +#' @param ... Extra parameters passed to \code{DimPlot} +#' #' @rdname DimPlot #' @export #' diff --git a/R/objects.R b/R/objects.R index 6bf659310..0470f935f 100644 --- a/R/objects.R +++ b/R/objects.R @@ -5667,19 +5667,24 @@ merge.Assay <- function( if (all(IsSCT(assay = assays))) { vst.set.new <- list() idx <- 1 + umi.assay.new <- list() for (i in 1:length(x = assays)) { vst.set.old <- Misc(object = assays[[i]], slot = "vst.set") + umi.assay.old <- Misc(object = assays[[i]], slot = "umi.assay") if (!is.null(x = vst.set.old)) { for (j in 1:length(x = vst.set.old)) { vst.set.new[[idx]] <- vst.set.old[[j]] + umi.assay.new[[idx]] <- umi.assay.old[[j]] idx <- idx + 1 } } else if (!is.null(x = Misc(object = assays[[i]], slot = "vst.out"))) { vst.set.new[[idx]] <- Misc(object = assays[[i]], slot = "vst.out") + umi.assay.new[[idx]] <- Misc(object = assays[[i]], slot = "umi.assay") idx <- idx + 1 } } Misc(object = combined.assay, slot = "vst.set") <- vst.set.new + Misc(object = combined.assay, slot = "umi.assay") <- umi.assay.new scale.data <- do.call( what = cbind, args = lapply(X = assays, FUN = function(x) GetAssayData(object = x, slot = "scale.data")) diff --git a/R/preprocessing.R b/R/preprocessing.R index cf44dbca9..2b8631dcb 100644 --- a/R/preprocessing.R +++ b/R/preprocessing.R @@ -453,7 +453,7 @@ GetResidual <- function( object, features, assay = "SCT", - umi.assay = "RNA", + umi.assay = NULL, clip.range = NULL, replace.value = FALSE, verbose = TRUE @@ -461,6 +461,8 @@ GetResidual <- function( if (!IsSCT(assay = object[[assay]])) { stop(assay, " assay was not generated by SCTransform") } + umi.assay <- umi.assay %||% Misc(object = object[[assay]], slot = "umi.assay") + umi.assay <- umi.assay %||% "RNA" # for object created in 3.1.1 or earlier, default to RNA if (replace.value) { new_features <- features } else { @@ -534,7 +536,7 @@ GetResidual <- function( object.v <- GetResidualVstOut( object = object.v, assay = assay, - umi.assay = umi.assay, + umi.assay = umi.assay[[v]], new_features = new_features, vst_out = vst_out, clip.range = clip.range, @@ -1353,6 +1355,7 @@ SCTransform <- function( # save clip.range into vst model vst.out$arguments$sct.clip.range <- clip.range Misc(object = assay.out, slot = 'vst.out') <- vst.out + Misc(object = assay.out, slot = 'umi.assay') <- assay # also put gene attributes in meta.features assay.out[[paste0('sct.', names(x = vst.out$gene_attr))]] <- vst.out$gene_attr assay.out[['sct.variable']] <- rownames(x = assay.out[[]]) %in% top.features diff --git a/R/visualization.R b/R/visualization.R index 3f03da483..4ea30f366 100644 --- a/R/visualization.R +++ b/R/visualization.R @@ -22,9 +22,14 @@ NULL #' @param ncol Number of columns to plot #' @param fast If true, use \code{image} to generate plots; faster than using ggplot2, but not customizable #' @param assays A vector of assays to pull data from +#' @param combine Combine plots into a single \code{\link[patchwork]{patchwork}ed} +#' ggplot object. If \code{FALSE}, return a list of ggplot objects #' -#' @return No return value by default. If using fast = FALSE, will return a ggplot object. +#' @return No return value by default. If using fast = FALSE, will return a +#' \code{\link[patchwork]{patchwork}ed} ggplot object if combine = TRUE, otherwise +#' returns a list of ggplot objects #' +#' @importFrom patchwork wrap_plots #' @export #' #' @seealso \code{\link[graphics]{image}} \code{\link[ggplot2]{geom_raster}} @@ -43,11 +48,11 @@ DimHeatmap <- function( balanced = TRUE, projected = FALSE, ncol = NULL, - combine = TRUE, fast = TRUE, raster = TRUE, slot = 'scale.data', - assays = NULL + assays = NULL, + combine = TRUE ) { ncol <- ncol %||% ifelse(test = length(x = dims) > 2, yes = 3, no = length(x = dims)) plots <- vector(mode = 'list', length = length(x = dims)) @@ -157,11 +162,7 @@ DimHeatmap <- function( return(invisible(x = NULL)) } if (combine) { - plots <- CombinePlots( - plots = plots, - ncol = ncol, - legend = 'right' - ) + plots <- wrap_plots(plots, ncol = ncol, guides = "collect") } return(plots) } @@ -193,15 +194,17 @@ DimHeatmap <- function( #' @param lines.width Integer number to adjust the width of the separating white lines. #' Corresponds to the number of "cells" between each group. #' @param group.bar.height Scale the height of the color bar -#' @param combine Combine plots into a single gg object; note that if TRUE; themeing will not work -#' when plotting multiple dimensions +#' @param combine Combine plots into a single \code{\link[patchwork]{patchwork}ed} +#' ggplot object. If \code{FALSE}, return a list of ggplot objects #' -#' @return A ggplot object +#' @return A \code{\link[patchwork]{patchwork}ed} ggplot object if +#' \code{combine = TRUE}; otherwise, a list of ggplot objects #' #' @importFrom stats median #' @importFrom scales hue_pal #' @importFrom ggplot2 annotation_raster coord_cartesian scale_color_manual #' ggplot_build aes_string +#' @importFrom patchwork wrap_plots #' @export #' #' @examples @@ -355,7 +358,8 @@ DoHeatmap <- function( scale_color_manual(values = cols) if (label) { x.max <- max(pbuild$layout$panel_params[[1]]$x.range) - x.divs <- pbuild$layout$panel_params[[1]]$x.major + # Attempt to pull xdivs from x.major in ggplot2 < 3.3.0; if NULL, pull from the >= 3.3.0 slot + x.divs <- pbuild$layout$panel_params[[1]]$x.major %||% pbuild$layout$panel_params[[1]]$x$break_positions() x <- data.frame(group = sort(x = group.use), x = x.divs) label.x.pos <- tapply(X = x$x, INDEX = x$group, FUN = median) * x.max label.x.pos <- data.frame(group = names(x = label.x.pos), label.x.pos) @@ -378,7 +382,7 @@ DoHeatmap <- function( plots[[i]] <- plot } if (combine) { - plots <- CombinePlots(plots = plots) + plots <- wrap_plots(plots) } return(plots) } @@ -469,11 +473,12 @@ HTOHeatmap <- function( #' @param same.y.lims Set all the y-axis limits to the same values #' @param log plot the feature axis on log scale #' @param ncol Number of columns if multiple plots are displayed -#' @param combine Combine plots into a single gg object; note that if TRUE; themeing will not work when plotting multiple features #' @param slot Use non-normalized counts data for plotting -#' @param ... Extra parameters passed on to \code{\link{CombinePlots}} +#' @param combine Combine plots into a single \code{\link[patchwork]{patchwork}ed} +#' ggplot object. If \code{FALSE}, return a list of ggplot objects #' -#' @return A ggplot object +#' @return A \code{\link[patchwork]{patchwork}ed} ggplot object if +#' \code{combine = TRUE}; otherwise, a list of ggplot objects #' #' @export #' @@ -492,9 +497,8 @@ RidgePlot <- function( same.y.lims = FALSE, log = FALSE, ncol = NULL, - combine = TRUE, slot = 'data', - ... + combine = TRUE ) { return(ExIPlot( object = object, @@ -509,9 +513,8 @@ RidgePlot <- function( cols = cols, group.by = group.by, log = log, - combine = combine, slot = slot, - ... + combine = combine )) } @@ -527,7 +530,8 @@ RidgePlot <- function( #' see \code{\link{FetchData}} for more details #' @param adjust Adjust parameter for geom_violin #' -#' @return A ggplot object +#' @return A \code{\link[patchwork]{patchwork}ed} ggplot object if +#' \code{combine = TRUE}; otherwise, a list of ggplot objects #' #' @export #' @@ -552,10 +556,9 @@ VlnPlot <- function( same.y.lims = FALSE, log = FALSE, ncol = NULL, - combine = TRUE, slot = 'data', multi.group = FALSE, - ... + combine = TRUE ) { return(ExIPlot( object = object, @@ -574,8 +577,7 @@ VlnPlot <- function( split.by = split.by, log = log, slot = slot, - combine = combine, - ... + combine = combine )) } @@ -599,6 +601,8 @@ VlnPlot <- function( #' #' @export #' +#' @seealso \code{\link{DimPlot}} +#' #' @examples #' pbmc_small #' pbmc_small <- BuildClusterTree(object = pbmc_small, verbose = FALSE) @@ -689,14 +693,16 @@ ColorDimSplit <- function( #' @param sizes.highlight Size of highlighted cells; will repeat to the length #' groups in cells.highlight #' @param na.value Color value for NA points when using custom scale -#' @param combine Combine plots into a single gg object; note that if TRUE; themeing will not work when plotting multiple features #' @param ncol Number of columns for display when combining plots -#' @param ... Extra parameters passed on to \code{\link{CombinePlots}} +#' @param combine Combine plots into a single \code{\link[patchwork]{patchwork}ed} +#' ggplot object. If \code{FALSE}, return a list of ggplot objects #' -#' @return A ggplot object +#' @return A \code{\link[patchwork]{patchwork}ed} ggplot object if +#' \code{combine = TRUE}; otherwise, a list of ggplot objects #' #' @importFrom rlang !! #' @importFrom ggplot2 facet_wrap vars sym +#' @importFrom patchwork wrap_plots #' #' @export #' @@ -705,7 +711,7 @@ ColorDimSplit <- function( #' #' @aliases TSNEPlot PCAPlot ICAPlot #' @seealso \code{\link{FeaturePlot}} \code{\link{HoverLocator}} -#' \code{\link{CellSelector}} \code{link{FetchData}} +#' \code{\link{CellSelector}} \code{\link{FetchData}} #' #' @examples #' DimPlot(object = pbmc_small) @@ -729,11 +735,9 @@ DimPlot <- function( cols.highlight = '#DE2D26', sizes.highlight = 1, na.value = 'grey50', - combine = TRUE, ncol = NULL, - ... + combine = TRUE ) { - CheckDots(..., fxns = 'CombinePlots') if (length(x = dims) != 2) { stop("'dims' must be a two-length vector") } @@ -743,6 +747,7 @@ DimPlot <- function( data <- as.data.frame(x = data) dims <- paste0(Key(object = object[[reduction]]), dims) object[['ident']] <- Idents(object = object) + orig.groups <- group.by group.by <- group.by %||% 'ident' data[, group.by] <- object[[group.by]][cells, , drop = FALSE] for (group in group.by) { @@ -796,16 +801,11 @@ DimPlot <- function( return(plot) } ) + if (!is.null(x = split.by)) { + ncol <- 1 + } if (combine) { - plots <- CombinePlots( - plots = plots, - ncol = if (!is.null(x = split.by) && length(x = group.by) > 1) { - 1 - } else { - ncol - }, - ... - ) + plots <- wrap_plots(plots, ncol = orig.groups %iff% ncol) } return(plots) } @@ -842,16 +842,17 @@ DimPlot <- function( #' @param blend Scale and blend expression values to visualize coexpression of two features #' @param blend.threshold The color cutoff from weak signal to strong signal; ranges from 0 to 1. #' @param ncol Number of columns to combine multiple feature plots to, ignored if \code{split.by} is not \code{NULL} -#' @param combine Combine plots into a single gg object; note that if \code{TRUE}; themeing will not work when plotting multiple features #' @param coord.fixed Plot cartesian coordinates with fixed aspect ratio #' @param by.col If splitting by a factor, plot the splits per column with the features as rows; ignored if \code{blend = TRUE} #' @param sort.cell If \code{TRUE}, the positive cells will overlap the negative cells +#' @param combine Combine plots into a single \code{\link[patchwork]{patchwork}ed} +#' ggplot object. If \code{FALSE}, return a list of ggplot objects #' -#' @return Returns a ggplot object if only 1 feature is plotted. -#' If >1 features are plotted and \code{combine=TRUE}, returns a combined ggplot object using \code{cowplot::plot_grid}. -#' If >1 features are plotted and \code{combine=FALSE}, returns a list of ggplot objects. +#' @return A \code{\link[patchwork]{patchwork}ed} ggplot object if +#' \code{combine = TRUE}; otherwise, a list of ggplot objects #' #' @importFrom grDevices rgb +#' @importFrom patchwork wrap_plots #' @importFrom cowplot theme_cowplot #' @importFrom RColorBrewer brewer.pal.info #' @importFrom ggplot2 labs scale_x_continuous scale_y_continuous theme element_rect @@ -894,10 +895,10 @@ FeaturePlot <- function( label.size = 4, repel = FALSE, ncol = NULL, - combine = TRUE, coord.fixed = FALSE, by.col = TRUE, - sort.cell = FALSE + sort.cell = FALSE, + combine = TRUE ) { # Set a theme to remove right-hand Y axis lines # Also sets right-hand Y axis text label formatting @@ -1164,7 +1165,10 @@ FeaturePlot <- function( if (j == length(x = features) && !blend) { suppressMessages( expr = plot <- plot + - scale_y_continuous(sec.axis = dup_axis(name = ident)) + + scale_y_continuous( + sec.axis = dup_axis(name = ident), + limits = ylims + ) + no.right ) } @@ -1258,30 +1262,30 @@ FeaturePlot <- function( # Remove NULL plots plots <- Filter(f = Negate(f = is.null), x = plots) # Combine the plots - if (combine) { - if (is.null(x = ncol)) { - ncol <- 2 - if (length(x = features) == 1) { - ncol <- 1 - } - if (length(x = features) > 6) { - ncol <- 3 - } - if (length(x = features) > 9) { - ncol <- 4 - } + if (is.null(x = ncol)) { + ncol <- 2 + if (length(x = features) == 1) { + ncol <- 1 } - ncol <- ifelse( - test = is.null(x = split.by) || blend, - yes = ncol, - no = length(x = features) - ) - legend <- if (blend) { - 'none' - } else { - split.by %iff% 'none' + if (length(x = features) > 6) { + ncol <- 3 } - # Transpose the FeatureHeatmap matrix (not applicable for blended FeaturePlots) + if (length(x = features) > 9) { + ncol <- 4 + } + } + ncol <- ifelse( + test = is.null(x = split.by) || blend, + yes = ncol, + no = length(x = features) + ) + legend <- if (blend) { + 'none' + } else { + split.by %iff% 'none' + } + # Transpose the FeatureHeatmap matrix (not applicable for blended FeaturePlots) + if (combine) { if (by.col && !is.null(x = split.by) && !blend) { plots <- lapply( X = plots, @@ -1290,7 +1294,7 @@ FeaturePlot <- function( expr = x + theme_cowplot() + ggtitle("") + - scale_y_continuous(sec.axis = dup_axis(name = "")) + + scale_y_continuous(sec.axis = dup_axis(name = ""), limits = ylims) + no.right )) } @@ -1298,37 +1302,49 @@ FeaturePlot <- function( nsplits <- length(x = levels(x = data$split)) idx <- 1 for (i in (length(x = features) * (nsplits - 1) + 1):(length(x = features) * nsplits)) { - plots[[i]] <- suppressMessages(plots[[i]] + scale_y_continuous(sec.axis = dup_axis(name = features[[idx]])) + no.right) + plots[[i]] <- suppressMessages( + expr = plots[[i]] + + scale_y_continuous( + sec.axis = dup_axis(name = features[[idx]]), + limits = ylims + ) + + no.right + ) idx <- idx + 1 } idx <- 1 for (i in which(x = 1:length(x = plots) %% length(x = features) == 1)) { - plots[[i]] <- plots[[i]] + ggtitle(levels(x = data$split)[[idx]]) + theme(plot.title = element_text(hjust = 0.5)) + plots[[i]] <- plots[[i]] + + ggtitle(levels(x = data$split)[[idx]]) + + theme(plot.title = element_text(hjust = 0.5)) idx <- idx + 1 } idx <- 1 if (length(x = features) == 1) { for (i in 1:length(x = plots)) { - plots[[i]] <- plots[[i]] + ggtitle(levels(x = data$split)[[idx]]) + theme(plot.title = element_text(hjust = 0.5)) + plots[[i]] <- plots[[i]] + + ggtitle(levels(x = data$split)[[idx]]) + + theme(plot.title = element_text(hjust = 0.5)) idx <- idx + 1 } + ncol <- nsplits + nrow <- 1 + } else { + nrow <- split.by %iff% length(x = levels(x = data$split)) } plots <- plots[c(do.call( what = rbind, - args = split(x = 1:length(x = plots), f = ceiling(x = seq_along(along.with = 1:length(x = plots))/length(x = features))) + args = split(x = 1:length(x = plots), f = ceiling(x = seq_along(along.with = 1:length(x = plots)) / length(x = features))) ))] - plots <- CombinePlots( - plots = plots, - ncol = nsplits, - legend = legend - ) + plots <- wrap_plots(plots, ncol = ncol, nrow = nrow) + if (!is.null(x = legend) && legend == 'none') { + plots <- plots & NoLegend() + } } else { - plots <- CombinePlots( - plots = plots, - ncol = ncol, - legend = legend, - nrow = split.by %iff% length(x = levels(x = data$split)) - ) + plots <- wrap_plots(plots, ncol = ncol, nrow = split.by %iff% length(x = levels(x = data$split))) + } + if (!is.null(x = legend) && legend == 'none') { + plots <- plots & NoLegend() } } return(plots) @@ -1686,11 +1702,12 @@ PolyFeaturePlot <- function( #' The transition from "signal" to "noise" in the is hard to see because the #' first singular value spacings are so large. Nicer visualizations result from #' skipping the first few. If set to 0 (default) starts from k/2. -#' @param combine Combine plots into a single gg object; note that if TRUE, -#' themeing will not work when plotting multiple features +#' @param combine Combine plots into a single \code{\link[patchwork]{patchwork}ed} +#' ggplot object. If \code{FALSE}, return a list of ggplot objects #' -#' @return A list of 3 ggplot objects splotting the singular values, the -#' spacings of the singular values, and the p-values of the singular values. +#' @return A list of 3 \code{\link[patchwork]{patchwork}ed} ggplot objects +#' splotting the singular values, the spacings of the singular values, and the +#' p-values of the singular values. #' #' @author Jun Zhao, George Linderman #' @seealso \code{\link{RunALRA}} @@ -1698,6 +1715,7 @@ PolyFeaturePlot <- function( #' @importFrom cowplot theme_cowplot #' @importFrom ggplot2 ggplot aes_string geom_point geom_line #' geom_vline scale_x_continuous labs +#' @importFrom patchwork wrap_plots #' @export #' ALRAChooseKPlot <- function(object, start = 0, combine = TRUE) { @@ -1740,7 +1758,7 @@ ALRAChooseKPlot <- function(object, start = 0, combine = TRUE) { labs(x = NULL, y = 's_{i} - s_{i-1}', title = 'Singular value spacings') plots <- list(spectrum = gg1, spacings = gg2) if (combine) { - plots <- CombinePlots(plots = plots) + plots <- wrap_plots(plots) } return(plots) } @@ -2164,11 +2182,13 @@ PlotClusterTree <- function(object, ...) { #' @param balanced Return an equal number of genes with + and - scores. If #' FALSE (default), returns the top genes ranked by the scores absolute values #' @param ncol Number of columns to display -#' @param combine Combine plots into a single gg object; note that if TRUE; -#' themeing will not work when plotting multiple features +#' @param combine Combine plots into a single \code{\link[patchwork]{patchwork}ed} +#' ggplot object. If \code{FALSE}, return a list of ggplot objects #' -#' @return A ggplot object +#' @return A \code{\link[patchwork]{patchwork}ed} ggplot object if +#' \code{combine = TRUE}; otherwise, a list of ggplot objects #' +#' @importFrom patchwork wrap_plots #' @importFrom cowplot theme_cowplot #' @importFrom ggplot2 ggplot aes_string geom_point labs #' @export @@ -2187,17 +2207,15 @@ VizDimLoadings <- function( ncol = NULL, combine = TRUE ) { - if (is.null(x = ncol)) { - ncol <- 2 - if (length(x = dims) == 1) { - ncol <- 1 - } - if (length(x = dims) > 6) { - ncol <- 3 - } - if (length(x = dims) > 9) { - ncol <- 4 - } + ncol <- ncol %||% 2 + if (length(x = dims) == 1) { + ncol <- 1 + } + if (length(x = dims) > 6) { + ncol <- 3 + } + if (length(x = dims) > 9) { + ncol <- 4 } loadings <- Loadings(object = object[[reduction]], projected = projected) features <- lapply( @@ -2231,7 +2249,7 @@ VizDimLoadings <- function( } ) if (combine) { - plots <- CombinePlots(plots = plots, ncol = ncol, legend = NULL) + plots <- wrap_plots(plots, ncol = ncol) } return(plots) } @@ -2461,19 +2479,24 @@ CollapseEmbeddingOutliers <- function( #' size = ncol(x = pbmc_small), #' replace = TRUE #' ) -#' plots <- FeaturePlot( +#' plot1 <- FeaturePlot( +#' object = pbmc_small, +#' features = 'MS4A1', +#' split.by = 'group' +#' ) +#' plot2 <- FeaturePlot( #' object = pbmc_small, -#' features = c('MS4A1', 'FCN1'), -#' split.by = 'group', -#' combine = FALSE +#' features = 'FCN1', +#' split.by = 'group' #' ) #' CombinePlots( -#' plots = plots, +#' plots = list(plot1, plot2), #' legend = 'none', #' nrow = length(x = unique(x = pbmc_small[['group', drop = TRUE]])) #' ) #' CombinePlots <- function(plots, ncol = NULL, legend = NULL, ...) { + .Deprecated(msg = "CombinePlots is being deprecated. Plots should now be combined using the patchwork system.") plots.combined <- if (length(x = plots) > 1) { if (!is.null(x = legend)) { if (legend != 'none') { @@ -3601,12 +3624,16 @@ DefaultDimReduc <- function(object, assay = NULL) { # @param group.by Group (color) cells in different ways (for example, orig.ident) # @param split.by A variable to split the plot by # @param log plot Y axis on log scale -# @param combine Combine plots using cowplot::plot_grid # @param slot Use non-normalized counts data for plotting -# @param ... Extra parameters passed to \code{\link{CombinePlots}} +# @param combine Combine plots into a single \code{\link[patchwork]{patchwork}ed} +# ggplot object. If \code{FALSE}, return a list of ggplot objects +# +# @return A \code{\link[patchwork]{patchwork}ed} ggplot object if +# \code{combine = TRUE}; otherwise, a list of ggplot objects # #' @importFrom scales hue_pal #' @importFrom ggplot2 xlab ylab +#' @importFrom patchwork wrap_plots # ExIPlot <- function( object, @@ -3624,9 +3651,8 @@ ExIPlot <- function( group.by = NULL, split.by = NULL, log = FALSE, - combine = TRUE, slot = 'data', - ... + combine = TRUE ) { assay <- assay %||% DefaultAssay(object = object) DefaultAssay(object = object) <- assay @@ -3689,8 +3715,7 @@ ExIPlot <- function( adjust = adjust, cols = cols, pt.size = pt.size, - log = log, - ... + log = log )) } ) @@ -3718,15 +3743,10 @@ ExIPlot <- function( } } if (combine) { - combine.args <- list( - 'plots' = plots, - 'ncol' = ncol - ) - combine.args <- c(combine.args, list(...)) - if (!'legend' %in% names(x = combine.args)) { - combine.args$legend <- 'none' + plots <- wrap_plots(plots, ncol = ncol) + if (length(x = features) > 1) { + plots <- plots & NoLegend() } - plots <- do.call(what = 'CombinePlots', args = combine.args) } return(plots) } diff --git a/README.md b/README.md index bc7ab8f49..a1f9c8a25 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![CRAN Version](https://www.r-pkg.org/badges/version/Seurat)](https://cran.r-project.org/package=Seurat) [![CRAN Downloads](https://cranlogs.r-pkg.org/badges/Seurat)](https://cran.r-project.org/package=Seurat) -# Seurat v3.1.3 +# Seurat v3.1.4 Seurat is an R toolkit for single cell genomics, developed and maintained by the Satija Lab at NYGC. diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 1dad7f16d..19e5a1c9b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -18,7 +18,7 @@ jobs: pool: Default variables: R_LIBS_USER: '$(Agent.BuildDirectory)/R/library' - container: satijalab/online-workflows:latest + container: satijalab/seurat:develop steps: - script: | R CMD build . diff --git a/cran-comments.md b/cran-comments.md index 6f2c675f8..81a9a0ba4 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,7 +1,8 @@ -# Seurat v3.1.3 +# Seurat v3.1.4 ## Test environments * local Ubuntu 16.04.6 and 18.04.2 installs, R 3.6.1 +* local Windows 10 install, R 3.5.3 * Ubuntu 16.04.6 (on travis-ci), R 3.6.1 * macOS 10.13.3 (on travis-ci), R 3.6.1 * Windows Server 2012 R2 (on AppVeyor), R 3.6.1 Patched @@ -13,30 +14,23 @@ There were no ERRORs or WARNINGs There were 3 NOTEs: * checking CRAN incoming feasibility ... NOTE - Maintainer: ‘Paul Hoffman ’ + Maintainer: ‘Paul Hoffman ’ - New submission + Suggests or Enhances not in mainstream repositories: + loomR, SDMTools + Availability using Additional_repositories specification: + loomR yes https://mojaveazure.github.io/loomR + SDMTools no ? - Package was archived on CRAN - - CRAN repository db overrides: - X-CRAN-Comment: Archived on 2020-02-07 as check issues were not - corrected in time. - - Suggests or Enhances not in mainstream repositories: - loomR - Availability using Additional_repositories specification: - loomR yes https://mojaveazure.github.io/loomR - - This is a patch for an archived package Seurat. We were slow in fixing the errors and would like to get Seurat back on CRAN. In addition. the package we suggest, loomR, is currently under development and not yet available on CRAN. This package is not required for core functionality of Seurat. + One of the packages we suggest, loomR, is currently under development and not yet available on CRAN. This package is not required for core functionality of Seurat. The other package, SDMTools is also not required for core functionality. We are working to replace the function that calls SDMTools with a new function using non-orphaned packages * checking package dependencies ... NOTE Package suggested but not available for checking: 'loomR' - + Suggests orphaned package: ‘SDMTools’ loomR is a suggested package hosted on a custom repository and maintained by us (both the package and repository). - + SDMTools is not required for any essential functionality. We are working to replace the function that calls SDMTools with a new function using non-orphaned packages. * checking Rd cross-references ... NOTE @@ -48,4 +42,4 @@ There were 3 NOTEs: There is one pacakge that imports Seurat: multicross; this update does not impact its functionality -There are five packages that suggest Seurat: BisqueRNA, clustree, diem, iCellR, and Rmagic; this update does not impact their functionality. +There are three packages that suggest Seurat: BisqueRNA, clustree, and Rmagic; this update does not impact their functionality. diff --git a/man/ALRAChooseKPlot.Rd b/man/ALRAChooseKPlot.Rd index 88d1fd048..96893cd74 100644 --- a/man/ALRAChooseKPlot.Rd +++ b/man/ALRAChooseKPlot.Rd @@ -14,12 +14,13 @@ The transition from "signal" to "noise" in the is hard to see because the first singular value spacings are so large. Nicer visualizations result from skipping the first few. If set to 0 (default) starts from k/2.} -\item{combine}{Combine plots into a single gg object; note that if TRUE, -themeing will not work when plotting multiple features} +\item{combine}{Combine plots into a single \code{\link[patchwork]{patchwork}ed} +ggplot object. If \code{FALSE}, return a list of ggplot objects} } \value{ -A list of 3 ggplot objects splotting the singular values, the -spacings of the singular values, and the p-values of the singular values. +A list of 3 \code{\link[patchwork]{patchwork}ed} ggplot objects +splotting the singular values, the spacings of the singular values, and the +p-values of the singular values. } \description{ Plots the results of the approximate rank selection process for ALRA. diff --git a/man/ColorDimSplit.Rd b/man/ColorDimSplit.Rd index 0681c3226..07ee07db5 100644 --- a/man/ColorDimSplit.Rd +++ b/man/ColorDimSplit.Rd @@ -58,8 +58,9 @@ repeat to the length groups in cells.highlight} \item{\code{sizes.highlight}}{Size of highlighted cells; will repeat to the length groups in cells.highlight} \item{\code{na.value}}{Color value for NA points when using custom scale} - \item{\code{combine}}{Combine plots into a single gg object; note that if TRUE; themeing will not work when plotting multiple features} \item{\code{ncol}}{Number of columns for display when combining plots} + \item{\code{combine}}{Combine plots into a single \code{\link[patchwork]{patchwork}ed} +ggplot object. If \code{FALSE}, return a list of ggplot objects} }} } \value{ @@ -76,3 +77,6 @@ PlotClusterTree(pbmc_small) ColorDimSplit(pbmc_small, node = 5) } +\seealso{ +\code{\link{DimPlot}} +} diff --git a/man/CombinePlots.Rd b/man/CombinePlots.Rd index cf9049620..41995bd69 100644 --- a/man/CombinePlots.Rd +++ b/man/CombinePlots.Rd @@ -29,14 +29,18 @@ pbmc_small[['group']] <- sample( size = ncol(x = pbmc_small), replace = TRUE ) -plots <- FeaturePlot( +plot1 <- FeaturePlot( object = pbmc_small, - features = c('MS4A1', 'FCN1'), - split.by = 'group', - combine = FALSE + features = 'MS4A1', + split.by = 'group' +) +plot2 <- FeaturePlot( + object = pbmc_small, + features = 'FCN1', + split.by = 'group' ) CombinePlots( - plots = plots, + plots = list(plot1, plot2), legend = 'none', nrow = length(x = unique(x = pbmc_small[['group', drop = TRUE]])) ) diff --git a/man/DimHeatmap.Rd b/man/DimHeatmap.Rd index c7429b1e7..d126ba7df 100644 --- a/man/DimHeatmap.Rd +++ b/man/DimHeatmap.Rd @@ -16,11 +16,11 @@ DimHeatmap( balanced = TRUE, projected = FALSE, ncol = NULL, - combine = TRUE, fast = TRUE, raster = TRUE, slot = "scale.data", - assays = NULL + assays = NULL, + combine = TRUE ) PCHeatmap(object, ...) @@ -47,9 +47,6 @@ if \code{slot} is 'scale.data', 6 otherwise} \item{ncol}{Number of columns to plot} -\item{combine}{Combine plots into a single gg object; note that if TRUE; themeing will not work -when plotting multiple dimensions} - \item{fast}{If true, use \code{image} to generate plots; faster than using ggplot2, but not customizable} \item{raster}{If true, plot with geom_raster, else use geom_tile. geom_raster may look blurry on @@ -60,10 +57,15 @@ if you are encountering that issue (note that plots may take longer to produce/r \item{assays}{A vector of assays to pull data from} +\item{combine}{Combine plots into a single \code{\link[patchwork]{patchwork}ed} +ggplot object. If \code{FALSE}, return a list of ggplot objects} + \item{...}{Extra parameters passed to \code{DimHeatmap}} } \value{ -No return value by default. If using fast = FALSE, will return a ggplot object. +No return value by default. If using fast = FALSE, will return a +\code{\link[patchwork]{patchwork}ed} ggplot object if combine = TRUE, otherwise +returns a list of ggplot objects } \description{ Draws a heatmap focusing on a principal component. Both cells and genes are sorted by their diff --git a/man/DimPlot.Rd b/man/DimPlot.Rd index c3766abcd..a67940df6 100644 --- a/man/DimPlot.Rd +++ b/man/DimPlot.Rd @@ -26,9 +26,8 @@ DimPlot( cols.highlight = "#DE2D26", sizes.highlight = 1, na.value = "grey50", - combine = TRUE, ncol = NULL, - ... + combine = TRUE ) PCAPlot(object, ...) @@ -87,14 +86,16 @@ groups in cells.highlight} \item{na.value}{Color value for NA points when using custom scale} -\item{combine}{Combine plots into a single gg object; note that if TRUE; themeing will not work when plotting multiple features} - \item{ncol}{Number of columns for display when combining plots} -\item{...}{Extra parameters passed on to \code{\link{CombinePlots}}} +\item{combine}{Combine plots into a single \code{\link[patchwork]{patchwork}ed} +ggplot object. If \code{FALSE}, return a list of ggplot objects} + +\item{...}{Extra parameters passed to \code{DimPlot}} } \value{ -A ggplot object +A \code{\link[patchwork]{patchwork}ed} ggplot object if +\code{combine = TRUE}; otherwise, a list of ggplot objects } \description{ Graphs the output of a dimensional reduction technique on a 2D scatter plot where each point is a @@ -112,5 +113,5 @@ DimPlot(object = pbmc_small, split.by = 'ident') } \seealso{ \code{\link{FeaturePlot}} \code{\link{HoverLocator}} -\code{\link{CellSelector}} \code{link{FetchData}} +\code{\link{CellSelector}} \code{\link{FetchData}} } diff --git a/man/DoHeatmap.Rd b/man/DoHeatmap.Rd index 8c5c711bd..347ad243f 100644 --- a/man/DoHeatmap.Rd +++ b/man/DoHeatmap.Rd @@ -67,11 +67,12 @@ Corresponds to the number of "cells" between each group.} \item{group.bar.height}{Scale the height of the color bar} -\item{combine}{Combine plots into a single gg object; note that if TRUE; themeing will not work -when plotting multiple dimensions} +\item{combine}{Combine plots into a single \code{\link[patchwork]{patchwork}ed} +ggplot object. If \code{FALSE}, return a list of ggplot objects} } \value{ -A ggplot object +A \code{\link[patchwork]{patchwork}ed} ggplot object if +\code{combine = TRUE}; otherwise, a list of ggplot objects } \description{ Draws a heatmap of single cell feature expression. diff --git a/man/FeaturePlot.Rd b/man/FeaturePlot.Rd index 3e202b085..c67e85e8b 100644 --- a/man/FeaturePlot.Rd +++ b/man/FeaturePlot.Rd @@ -26,10 +26,10 @@ FeaturePlot( label.size = 4, repel = FALSE, ncol = NULL, - combine = TRUE, coord.fixed = FALSE, by.col = TRUE, - sort.cell = FALSE + sort.cell = FALSE, + combine = TRUE ) } \arguments{ @@ -88,18 +88,18 @@ different colors and different shapes on cells} \item{ncol}{Number of columns to combine multiple feature plots to, ignored if \code{split.by} is not \code{NULL}} -\item{combine}{Combine plots into a single gg object; note that if \code{TRUE}; themeing will not work when plotting multiple features} - \item{coord.fixed}{Plot cartesian coordinates with fixed aspect ratio} \item{by.col}{If splitting by a factor, plot the splits per column with the features as rows; ignored if \code{blend = TRUE}} \item{sort.cell}{If \code{TRUE}, the positive cells will overlap the negative cells} + +\item{combine}{Combine plots into a single \code{\link[patchwork]{patchwork}ed} +ggplot object. If \code{FALSE}, return a list of ggplot objects} } \value{ -Returns a ggplot object if only 1 feature is plotted. -If >1 features are plotted and \code{combine=TRUE}, returns a combined ggplot object using \code{cowplot::plot_grid}. -If >1 features are plotted and \code{combine=FALSE}, returns a list of ggplot objects. +A \code{\link[patchwork]{patchwork}ed} ggplot object if +\code{combine = TRUE}; otherwise, a list of ggplot objects } \description{ Colors single cells on a dimensional reduction plot according to a 'feature' diff --git a/man/GetResidual.Rd b/man/GetResidual.Rd index 13ef55616..d83fee3a7 100644 --- a/man/GetResidual.Rd +++ b/man/GetResidual.Rd @@ -8,7 +8,7 @@ GetResidual( object, features, assay = "SCT", - umi.assay = "RNA", + umi.assay = NULL, clip.range = NULL, replace.value = FALSE, verbose = TRUE diff --git a/man/RidgePlot.Rd b/man/RidgePlot.Rd index 2bba82d6c..063cda6c2 100644 --- a/man/RidgePlot.Rd +++ b/man/RidgePlot.Rd @@ -16,9 +16,8 @@ RidgePlot( same.y.lims = FALSE, log = FALSE, ncol = NULL, - combine = TRUE, slot = "data", - ... + combine = TRUE ) } \arguments{ @@ -46,14 +45,14 @@ expression of the attribute being potted, can also pass 'increasing' or 'decreas \item{ncol}{Number of columns if multiple plots are displayed} -\item{combine}{Combine plots into a single gg object; note that if TRUE; themeing will not work when plotting multiple features} - \item{slot}{Use non-normalized counts data for plotting} -\item{...}{Extra parameters passed on to \code{\link{CombinePlots}}} +\item{combine}{Combine plots into a single \code{\link[patchwork]{patchwork}ed} +ggplot object. If \code{FALSE}, return a list of ggplot objects} } \value{ -A ggplot object +A \code{\link[patchwork]{patchwork}ed} ggplot object if +\code{combine = TRUE}; otherwise, a list of ggplot objects } \description{ Draws a ridge plot of single cell data (gene expression, metrics, PC diff --git a/man/VizDimLoadings.Rd b/man/VizDimLoadings.Rd index e8111c48d..6c9ceb2a9 100644 --- a/man/VizDimLoadings.Rd +++ b/man/VizDimLoadings.Rd @@ -35,11 +35,12 @@ FALSE (default), returns the top genes ranked by the scores absolute values} \item{ncol}{Number of columns to display} -\item{combine}{Combine plots into a single gg object; note that if TRUE; -themeing will not work when plotting multiple features} +\item{combine}{Combine plots into a single \code{\link[patchwork]{patchwork}ed} +ggplot object. If \code{FALSE}, return a list of ggplot objects} } \value{ -A ggplot object +A \code{\link[patchwork]{patchwork}ed} ggplot object if +\code{combine = TRUE}; otherwise, a list of ggplot objects } \description{ Visualize top genes associated with reduction components diff --git a/man/VlnPlot.Rd b/man/VlnPlot.Rd index bed718b90..56f9848ab 100644 --- a/man/VlnPlot.Rd +++ b/man/VlnPlot.Rd @@ -19,10 +19,9 @@ VlnPlot( same.y.lims = FALSE, log = FALSE, ncol = NULL, - combine = TRUE, slot = "data", multi.group = FALSE, - ... + combine = TRUE ) } \arguments{ @@ -56,17 +55,17 @@ expression of the attribute being potted, can also pass 'increasing' or 'decreas \item{ncol}{Number of columns if multiple plots are displayed} -\item{combine}{Combine plots into a single gg object; note that if TRUE; themeing will not work when plotting multiple features} - \item{slot}{Use non-normalized counts data for plotting} \item{multi.group}{plot each group of the split violin plots by multiple or single violin shapes see \code{\link{FetchData}} for more details} -\item{...}{Extra parameters passed on to \code{\link{CombinePlots}}} +\item{combine}{Combine plots into a single \code{\link[patchwork]{patchwork}ed} +ggplot object. If \code{FALSE}, return a list of ggplot objects} } \value{ -A ggplot object +A \code{\link[patchwork]{patchwork}ed} ggplot object if +\code{combine = TRUE}; otherwise, a list of ggplot objects } \description{ Draws a violin plot of single cell data (gene expression, metrics, PC diff --git a/src/data_manipulation.cpp b/src/data_manipulation.cpp index 547dd67dc..94c68e539 100644 --- a/src/data_manipulation.cpp +++ b/src/data_manipulation.cpp @@ -76,11 +76,11 @@ Eigen::SparseMatrix RowMergeMatrices(Eigen::SparseMatrix mat1_map; - for(int i = 0; i < mat1_rownames.size(); i++){ + for(unsigned int i = 0; i < mat1_rownames.size(); i++){ mat1_map[mat1_rownames[i]] = i; } std::unordered_map mat2_map; - for(int i = 0; i < mat2_rownames.size(); i++){ + for(unsigned int i = 0; i < mat2_rownames.size(); i++){ mat2_map[mat2_rownames[i]] = i; }