Skip to content

Commit 1f58937

Browse files
authored
Merge pull request #53 from fmicompbio/add-scattermore
Add scattermore
2 parents 043bd4e + 80885f3 commit 1f58937

File tree

7 files changed

+178
-30
lines changed

7 files changed

+178
-30
lines changed

DESCRIPTION

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: mutscan
22
Title: Preprocessing and Analysis of Deep Mutational Scanning Data
3-
Version: 0.3.3
3+
Version: 0.3.4
44
Authors@R:
55
c(person(given = "Charlotte",
66
family = "Soneson",
@@ -55,7 +55,8 @@ Suggests:
5555
knitr,
5656
Biostrings,
5757
pwalign,
58-
plotly
58+
plotly,
59+
scattermore
5960
SystemRequirements: GNU make
6061
biocViews: GeneticVariability, GenomicVariation, Preprocessing
6162
License: MIT + file LICENSE

NEWS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# mutscan 0.3.4
2+
3+
* Allow use of scattermore/scattermost in plotPairs
4+
15
# mutscan 0.3.3
26

37
* Bugfix in mergeReadPairPartial for situation where specified minMergedLength/maxMergedLength is larger than the total length of the two merged sequences

R/plotPairs.R

Lines changed: 84 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@
2323
#' to calculate.
2424
#' @param histBreaks Numeric scalar, the number of breaks in the histograms
2525
#' to put in the diagonal panels.
26-
#' @param pointsType Either "points" or "smoothscatter", determining the
27-
#' type of plots that will be made.
26+
#' @param pointsType Either "points", "smoothscatter", "scattermore" or
27+
#' "scattermost" (the latter two require the "scattermore" package to be
28+
#' installed), determining the type of plots that will be made.
2829
#' @param corSizeMult,corSizeAdd Numeric scalars determining how the
2930
#' absolute correlation value is transformed into a font size. The
3031
#' transformation is corSizeMult * abs(corr) + corSizeAdd.
@@ -71,7 +72,8 @@ plotPairs <- function(se, selAssay = "counts", doLog = TRUE, pseudocount = 1,
7172
validValues = c("pearson", "spearman"))
7273
.assertScalar(x = histBreaks, type = "numeric", rngExcl = c(0, Inf))
7374
.assertScalar(x = pointsType, type = "character",
74-
validValues = c("smoothscatter", "points"))
75+
validValues = c("smoothscatter", "points", "scattermore",
76+
"scattermost"))
7577
.assertScalar(x = corSizeMult, type = "numeric", rngExcl = c(0, Inf))
7678
.assertScalar(x = corSizeAdd, type = "numeric", rngIncl = c(0, Inf))
7779
.assertScalar(x = pointSize, type = "numeric", rngExcl = c(0, Inf))
@@ -83,6 +85,9 @@ plotPairs <- function(se, selAssay = "counts", doLog = TRUE, pseudocount = 1,
8385
stopifnot(corrColorRange[2] >= corrColorRange[1])
8486
}
8587
.assertScalar(x = addIdentityLine, type = "logical")
88+
if (pointsType %in% c("scattermore", "scattermost")) {
89+
.assertPackagesAvailable("scattermore")
90+
}
8691

8792
## ----------------------------------------------------------------------- ##
8893
## Define shared theme elements
@@ -140,31 +145,80 @@ plotPairs <- function(se, selAssay = "counts", doLog = TRUE, pseudocount = 1,
140145
## ----------------------------------------------------------------------- ##
141146
## Scatter plots
142147
## ----------------------------------------------------------------------- ##
143-
## Define function to create smoothscatter-like plot (for use with ggpairs)
144-
smoothscat <- function(data, mapping, ...) {
145-
ggplot2::ggplot(data = data, mapping = mapping) +
146-
ggplot2::stat_density2d(ggplot2::aes(fill = ggplot2::after_stat(.data$density)^0.25), geom = "tile",
147-
contour = FALSE, n = 200) +
148-
ggplot2::scale_fill_continuous(low = "white", high = "darkgreen") +
149-
ggtheme +
150-
ggplot2::scale_x_continuous(expand = c(0, 0)) +
151-
ggplot2::scale_y_continuous(expand = c(0, 0))
152-
}
153-
154-
## Define function to create scatter plot (for use with ggpairs)
155-
if (addIdentityLine) {
156-
plotpoints <- function(data, mapping, ...) {
148+
if (pointsType == "smoothscatter") {
149+
## Define function to create smoothscatter-like plot (for use with ggpairs)
150+
smoothscat <- function(data, mapping, ...) {
157151
ggplot2::ggplot(data = data, mapping = mapping) +
158-
ggplot2::geom_abline(slope = 1, intercept = 0,
159-
linetype = "dashed", color = "grey") +
160-
ggplot2::geom_point(alpha = pointAlpha, size = pointSize) +
161-
ggtheme
152+
ggplot2::stat_density2d(
153+
ggplot2::aes(fill = ggplot2::after_stat(.data$density)^0.25), geom = "tile",
154+
contour = FALSE, n = 200) +
155+
ggplot2::scale_fill_continuous(low = "white", high = "darkgreen") +
156+
ggtheme +
157+
ggplot2::scale_x_continuous(expand = c(0, 0)) +
158+
ggplot2::scale_y_continuous(expand = c(0, 0))
162159
}
163-
} else {
164-
plotpoints <- function(data, mapping, ...) {
165-
ggplot2::ggplot(data = data, mapping = mapping) +
166-
ggplot2::geom_point(alpha = pointAlpha, size = pointSize) +
167-
ggtheme
160+
} else if (pointsType == "points") {
161+
## Define function to create scatter plot (for use with ggpairs)
162+
if (addIdentityLine) {
163+
plotpoints <- function(data, mapping, ...) {
164+
ggplot2::ggplot(data = data, mapping = mapping) +
165+
ggplot2::geom_abline(slope = 1, intercept = 0,
166+
linetype = "dashed", color = "grey") +
167+
ggplot2::geom_point(alpha = pointAlpha, size = pointSize) +
168+
ggtheme
169+
}
170+
} else {
171+
plotpoints <- function(data, mapping, ...) {
172+
ggplot2::ggplot(data = data, mapping = mapping) +
173+
ggplot2::geom_point(alpha = pointAlpha, size = pointSize) +
174+
ggtheme
175+
}
176+
}
177+
} else if (pointsType == "scattermore") {
178+
## Define function to create scattermore plot (for use with ggpairs)
179+
if (addIdentityLine) {
180+
plotscattermore <- function(data, mapping, ...) {
181+
ggplot2::ggplot(data = data, mapping = mapping) +
182+
ggplot2::geom_abline(slope = 1, intercept = 0,
183+
linetype = "dashed", color = "grey") +
184+
scattermore::geom_scattermore(alpha = pointAlpha,
185+
pointsize = pointSize) +
186+
ggtheme
187+
}
188+
} else {
189+
plotscattermore <- function(data, mapping, ...) {
190+
ggplot2::ggplot(data = data, mapping = mapping) +
191+
scattermore::geom_scattermore(alpha = pointAlpha,
192+
pointsize = pointSize) +
193+
ggtheme
194+
}
195+
}
196+
} else if (pointsType == "scattermost") {
197+
## Define function to create scattermost plot (for use with ggpairs)
198+
if (addIdentityLine) {
199+
plotscattermost <- function(data, mapping, ...) {
200+
## Get data
201+
xData <- GGally::eval_data_col(data, mapping$x)
202+
yData <- GGally::eval_data_col(data, mapping$y)
203+
204+
ggplot2::ggplot(data = data, mapping = mapping) +
205+
ggplot2::geom_abline(slope = 1, intercept = 0,
206+
linetype = "dashed", color = "grey") +
207+
scattermore::geom_scattermost(xy = cbind(xData, yData),
208+
pointsize = pointSize) +
209+
ggtheme
210+
}
211+
} else {
212+
plotscattermost <- function(data, mapping, ...) {
213+
## Get data
214+
xData <- GGally::eval_data_col(data, mapping$x)
215+
yData <- GGally::eval_data_col(data, mapping$y)
216+
217+
ggplot2::ggplot(data = data, mapping = mapping) +
218+
scattermore::geom_scattermost(xy = cbind(xData, yData),
219+
pointsize = pointSize) +
220+
ggtheme
221+
}
168222
}
169223
}
170224

@@ -173,6 +227,10 @@ plotPairs <- function(se, selAssay = "counts", doLog = TRUE, pseudocount = 1,
173227
lower <- list(continuous = smoothscat)
174228
} else if (pointsType == "points") {
175229
lower <- list(continuous = plotpoints)
230+
} else if (pointsType == "scattermore") {
231+
lower <- list(continuous = plotscattermore)
232+
} else if (pointsType == "scattermost") {
233+
lower <- list(continuous = plotscattermost)
176234
}
177235

178236
## ----------------------------------------------------------------------- ##

R/utils.R

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,54 @@
156156

157157
return(invisible(TRUE))
158158
}
159+
160+
#' Utility function that makes sure that packages are available
161+
#'
162+
#' The function tries loading the namespaces of the packages given in
163+
#' \code{pkgs}, and throws an exception with an informative error message if
164+
#' that is not the case.
165+
#'
166+
#' @param pkgs Character vector with package names. Can be either just a
167+
#' package name or a string of the form \code{"githubuser/packagename"} for
168+
#' packages hosted on GitHub.
169+
#' @param suggestInstallation Logical scalar. If \code{TRUE}, include an
170+
#' expression to install the missing package(s) as part of the generated
171+
#' error message.
172+
#'
173+
#' @author Michael Stadler, Charlotte Soneson
174+
#'
175+
#' @noRd
176+
#' @keywords internal
177+
.assertPackagesAvailable <- function(pkgs, suggestInstallation = TRUE) {
178+
stopifnot(exprs = {
179+
is.character(pkgs)
180+
is.logical(suggestInstallation)
181+
length(suggestInstallation) == 1L
182+
})
183+
184+
avail <- unlist(lapply(sub("^[^/]+/", "", pkgs),
185+
function(pkg) {
186+
requireNamespace(pkg, quietly = TRUE)
187+
}))
188+
189+
if (any(!avail)) {
190+
caller <- deparse(sys.calls()[[sys.nframe() - 1]])
191+
callerfunc <- sub("\\(.+$", "", caller)
192+
haveBioc <- requireNamespace("BiocManager", quietly = TRUE)
193+
msg <- paste0("The package", ifelse(sum(!avail) > 1, "s '", " '"),
194+
paste(sub("^[^/]+/", "", pkgs[!avail]), collapse = "', '"),
195+
"' ",
196+
ifelse(sum(!avail) > 1, "are", "is"), " required for ",
197+
callerfunc, "(), but not installed.\n")
198+
if (suggestInstallation) {
199+
msg <- paste0(msg,
200+
"Install ", ifelse(sum(!avail) > 1, "them", "it"), " using:\n",
201+
ifelse(haveBioc, "", "install.packages(\"BiocManager\")\n"),
202+
"BiocManager::install(c(\"",
203+
paste(pkgs[!avail], collapse = "\", \""), "\"))")
204+
}
205+
stop(msg, call. = FALSE)
206+
}
207+
208+
invisible(TRUE)
209+
}

man/plotPairs.Rd

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test_plotPairs.R

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,22 @@ test_that("plotPairs works with correct arguments", {
111111
corSizeAdd = 2, pointSize = 0.1, pointAlpha = 0.3,
112112
colorByCorrelation = TRUE, corrColorRange = NULL,
113113
addIdentityLine = FALSE), "ggmatrix")
114+
115+
## scattermore
116+
expect_s3_class(plotPairs(se = se, selAssay = "counts", doLog = TRUE,
117+
pseudocount = 1, corMethod = "pearson",
118+
histBreaks = 40, pointsType = "scattermore", corSizeMult = 5,
119+
corSizeAdd = 2, pointSize = 3.5, pointAlpha = 0.3,
120+
colorByCorrelation = TRUE, corrColorRange = NULL,
121+
addIdentityLine = FALSE), "ggmatrix")
122+
123+
## scattermost
124+
expect_s3_class(plotPairs(se = se, selAssay = "counts", doLog = TRUE,
125+
pseudocount = 1, corMethod = "pearson",
126+
histBreaks = 40, pointsType = "scattermost", corSizeMult = 5,
127+
corSizeAdd = 2, pointSize = 3.5, pointAlpha = 0.3,
128+
colorByCorrelation = TRUE, corrColorRange = NULL,
129+
addIdentityLine = FALSE), "ggmatrix")
114130

115131
## Change font size to correlation relation
116132
expect_s3_class(plotPairs(se = se, selAssay = "counts", doLog = TRUE,

tests/testthat/tests-utils.R

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,20 @@ expect_true(.assertVector(LETTERS[1:2], type = "character", validValues = LETTER
9292
test <- "text"
9393
expect_error(.assertVector(x = test, type = "numeric"),
9494
"'test' must be of class 'numeric")
95+
96+
## -------------------------------------------------------------------------- ##
97+
## Checks, .assertPackagesAvailable
98+
## -------------------------------------------------------------------------- ##
99+
test_that(".assertPackagesAvailable works", {
100+
testfunc <- function(...) .assertPackagesAvailable(...)
101+
expect_error(testfunc(1L))
102+
expect_error(testfunc("test", "error"))
103+
expect_error(testfunc("test", c(TRUE, FALSE)))
104+
105+
expect_true(testfunc("base"))
106+
expect_true(testfunc("githubuser/base"))
107+
expect_true(testfunc(c("base", "methods")))
108+
expect_error(testfunc(c("error", "error2")), "BiocManager")
109+
expect_error(testfunc("error1", suggestInstallation = FALSE), "installed.\n$")
110+
rm(testfunc)
111+
})

0 commit comments

Comments
 (0)