Skip to content

Commit 9199ed2

Browse files
committed
scalebar code cleaning & unit tests
1 parent 88a6c0b commit 9199ed2

2 files changed

Lines changed: 108 additions & 0 deletions

File tree

R/scalebar.R

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#' @title \code{SpatialDataArray} scalebar
2+
#'
3+
#' @param x a \code{SpatialDataArray} object (i.e.,
4+
#' image or label element from a \code{SpatialData} object).
5+
#' @param len scalar numeric giving the length of the scalebar
6+
#' in physical coordinate space; the unit will be extracted
7+
#' from the data's Zarr specifications (see \code{axes(x)}).
8+
#' @param col string indicating the color to use for the scalebar.
9+
#' @param lwd scalar numeric indicating the linewidth to use for the scalebar.
10+
#' @param xrel,yrel scalar numeric in [0,1] indicating
11+
#' the relative x- and y-position of the scalebar.
12+
#'
13+
#' @examples
14+
#' zs <- file.path("extdata", "blobs.zarr")
15+
#' zs <- system.file(zs, package="spatialdataR")
16+
#' sd <- readSpatialData(zs, tables=FALSE)
17+
#'
18+
#' # mock unit (data misses specification!)
19+
#' md <- meta(image(sd, 2))
20+
#' md$multiscales[[1]]$axes[[3]]$unit <- "micron"
21+
#' sd$images[[2]]@meta <- md
22+
#'
23+
#' plotSpatialData() +
24+
#' plotImage(sd, i=2) +
25+
#' scalebar(image(sd, i=2), len=10)
26+
#'
27+
#' @importFrom ggplot2 annotate
28+
#' @importFrom methods is
29+
#' @export
30+
scalebar <- function(x, len, col="red", lwd=1, xrel=0.05, yrel=0.05) {
31+
if (!is(x, "SpatialDataArray"))
32+
stop("'x' should be a 'SpatialDataArray' object, i.e., an",
33+
" image or label element from a 'SpatialData' object")
34+
35+
xi <- which(axes(x, "name") == "x")
36+
unit <- axes(x)[[xi]]$unit
37+
if (is.null(unit))
38+
stop("'axes(x)' list element ", xi,
39+
" (X dimension) missing 'unit'")
40+
if (unit %in% names(.unit_map))
41+
unit <- .unit_map[unit]
42+
43+
wh <- .get_wh(x)
44+
if (xrel <= 0.5) {
45+
xmin <- diff(wh$w) * xrel + wh$w[1]
46+
xmax <- diff(wh$w) * xrel + wh$w[1] + len
47+
} else {
48+
xmin <- wh$w[2] - diff(wh$w) * (1 - xrel) - len
49+
xmax <- wh$w[2] - diff(wh$w) * (1 - xrel)
50+
}
51+
y <- wh$h[2] - diff(wh$h) * yrel
52+
53+
line <- annotate(
54+
geom="segment",
55+
color=col, linewidth=lwd,
56+
x=xmin, xend=xmax, y=y, yend=y)
57+
text <- annotate(
58+
geom="text",
59+
x=(xmin+xmax)/2, y=y,
60+
color=col, label=paste0(len, unit),
61+
vjust=ifelse(yrel > 0.5, 1.5, -0.5))
62+
return(list(line, text))
63+
}

tests/testthat/test-scalebar.R

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
require(ggplot2, quietly=TRUE)
2+
x <- file.path("extdata", "blobs.zarr")
3+
x <- system.file(x, package="spatialdataR")
4+
x <- readSpatialData(x, tables=FALSE)
5+
6+
set_unit <- \(x, dim="x", val="micron") {
7+
y <- meta(x)
8+
i <- which(axes(x, "name") == dim)
9+
y$multiscales[[1]]$axes[[i]]$unit <- val
10+
x@meta <- y
11+
return(x)
12+
}
13+
14+
test_that("scalebar()", {
15+
# not an image/label
16+
expect_error(scalebar(point(x)))
17+
expect_error(scalebar(shape(x)))
18+
19+
# missing 'unit'
20+
expect_error(scalebar(image(x)))
21+
y <- set_unit(image(x), "y")
22+
expect_error(scalebar(image(y), 1))
23+
24+
# valid specification
25+
y <- set_unit(image(x))
26+
l <- scalebar(y,
27+
len=len <- 5.1234,
28+
xrel=xrel <- 0.05,
29+
yrel=yrel <- 0.11,
30+
col=col <- "pink",
31+
lwd=lwd <- 7)
32+
expect_is(l, "list")
33+
expect_length(l, 2)
34+
35+
# check data
36+
p <- ggplot() + l
37+
df <- layer_data(p, 1)
38+
expect_equal(df$colour, col)
39+
expect_equal(df$linewidth, lwd)
40+
41+
expect_equal(df$x, dim(y)[3]*xrel)
42+
expect_equal(df$xend, dim(y)[3]*xrel+len)
43+
expect_equal(df$y, dim(y)[2]*(1-yrel))
44+
expect_equal(df$yend, df$y)
45+
})

0 commit comments

Comments
 (0)