From 1f74e3dcae4b3bcc818bad0214fcfa2aee90595d Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Tue, 28 Apr 2026 18:16:55 +0200 Subject: [PATCH 01/12] Use faster matrix->long df conversion --- R/plotLabel.R | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/R/plotLabel.R b/R/plotLabel.R index 4718a46..4cef4c5 100644 --- a/R/plotLabel.R +++ b/R/plotLabel.R @@ -59,8 +59,10 @@ setMethod("plotLabel", "SpatialData", \(x, i=1, j=1, k=NULL, c=NULL, if (is.numeric(i)) i <- labelNames(x)[i] i <- match.arg(i, labelNames(x)) y <- label(x, i) - ym <- as.matrix(.get_multiscale_data(label(x, i), k)) - df <- data.frame(x=c(col(ym)), y=c(row(ym)), z=c(ym)) + ym <- .get_multiscale_data(label(x, i), k) + # Keep only indices != 0 since labels might be sparse and thus save memory by not plotting all pixels + idx <- BiocGenerics::which(ym != 0L, arr.ind=TRUE) + df <- data.frame(x=idx[,1L], y=idx[,2L], z=ym[idx]) # transformation if (is.numeric(j)) j <- CTname(y)[j] From cb5452366d69ef0f1859760dcdf3bdda0900b22b Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Tue, 28 Apr 2026 18:17:19 +0200 Subject: [PATCH 02/12] Use system.file() directly in example --- R/plotLabel.R | 3 +-- man/plotLabel.Rd | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/R/plotLabel.R b/R/plotLabel.R index 4cef4c5..17a5578 100644 --- a/R/plotLabel.R +++ b/R/plotLabel.R @@ -18,8 +18,7 @@ #' @param nan character string; color for missing values (hidden by default). #' #' @examples -#' x <- file.path("extdata", "blobs.zarr") -#' x <- system.file(x, package="SpatialData") +#' x <- system.file("extdata", "blobs.zarr", package="SpatialData") #' x <- readSpatialData(x) #' #' i <- "blobs_labels" diff --git a/man/plotLabel.Rd b/man/plotLabel.Rd index 02bc7cf..3dc738e 100644 --- a/man/plotLabel.Rd +++ b/man/plotLabel.Rd @@ -46,8 +46,7 @@ specifies which \code{assay} data to use (see \code{\link{valTable}}).} \code{SpatialData} label viz. } \examples{ -x <- file.path("extdata", "blobs.zarr") -x <- system.file(x, package="SpatialData") +x <- system.file("extdata", "blobs.zarr", package="SpatialData") x <- readSpatialData(x) i <- "blobs_labels" From a865793201707f5ffa9a72454f3b5571dd26ca9d Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Tue, 28 Apr 2026 18:17:46 +0200 Subject: [PATCH 03/12] Avoid unnecessary setdiff() --- R/plotLabel.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/plotLabel.R b/R/plotLabel.R index 17a5578..34bba4a 100644 --- a/R/plotLabel.R +++ b/R/plotLabel.R @@ -86,7 +86,7 @@ setMethod("plotLabel", "SpatialData", \(x, i=1, j=1, k=NULL, c=NULL, aes$fill <- aes(.data[["z"]])[[1]] switch(scale_type(df$z), discrete={ - val <- sort(setdiff(unique(df$z), NA)) + val <- sort(unique(df$z), na.last=NA)) pal <- colorRampPalette(pal)(length(val)) thm <- list( theme(legend.key.size=unit(0.5, "lines")), From b0a9339259754e55a8635e4d28bbc5b295495edd Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Tue, 28 Apr 2026 18:18:11 +0200 Subject: [PATCH 04/12] Use geom_tile() to avoid warning() --- NAMESPACE | 2 +- R/plotLabel.R | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 0520092..daf80cb 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -25,8 +25,8 @@ importFrom(ggplot2,element_line) importFrom(ggplot2,element_text) importFrom(ggplot2,geom_blank) importFrom(ggplot2,geom_point) -importFrom(ggplot2,geom_raster) importFrom(ggplot2,geom_sf) +importFrom(ggplot2,geom_tile) importFrom(ggplot2,ggplot) importFrom(ggplot2,guide_legend) importFrom(ggplot2,guides) diff --git a/R/plotLabel.R b/R/plotLabel.R index 34bba4a..b6339a1 100644 --- a/R/plotLabel.R +++ b/R/plotLabel.R @@ -50,7 +50,7 @@ NULL #' @importFrom methods as #' @importFrom ggplot2 #' scale_fill_manual scale_fill_gradientn -#' aes geom_raster theme unit guides guide_legend +#' aes geom_tile theme unit guides guide_legend #' @importFrom SingleCellExperiment colData #' @export setMethod("plotLabel", "SpatialData", \(x, i=1, j=1, k=NULL, c=NULL, @@ -103,5 +103,5 @@ setMethod("plotLabel", "SpatialData", \(x, i=1, j=1, k=NULL, c=NULL, theme(legend.position="none"), scale_fill_manual(NULL, values=pal)) } - list(thm, do.call(geom_raster, list(data=df, mapping=aes, alpha=a))) + list(thm, do.call(geom_tile, list(data=df, mapping=aes, alpha=a))) }) \ No newline at end of file From 71c5492c7fddd1fc7cbcc51ffbcd902c8a3a3f26 Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Tue, 28 Apr 2026 18:18:20 +0200 Subject: [PATCH 05/12] Avoid repeating thm<- --- R/plotLabel.R | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/R/plotLabel.R b/R/plotLabel.R index b6339a1..0fc2c63 100644 --- a/R/plotLabel.R +++ b/R/plotLabel.R @@ -84,16 +84,16 @@ setMethod("plotLabel", "SpatialData", \(x, i=1, j=1, k=NULL, c=NULL, df$z <- getTable(x, i, c, assay=assay)[idx] if (c == ik) df$z <- factor(df$z) aes$fill <- aes(.data[["z"]])[[1]] - switch(scale_type(df$z), + thm <- switch(scale_type(df$z), discrete={ - val <- sort(unique(df$z), na.last=NA)) + val <- sort(unique(df$z), na.last=NA) pal <- colorRampPalette(pal)(length(val)) - thm <- list( + list( theme(legend.key.size=unit(0.5, "lines")), guides(fill=guide_legend(override.aes=list(alpha=1))), scale_fill_manual(c, values=pal, breaks=val, na.value=nan)) }, - continuous=thm <- list( + continuous=list( theme(legend.key.size=unit(0.5, "lines")), scale_fill_gradientn(c, colors=pal, na.value=nan))) } else { From cbdcbff3980c8dc6e7a683d480a4f3c7fc1f846f Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Tue, 28 Apr 2026 18:33:56 +0200 Subject: [PATCH 06/12] Reuse 'y' var --- R/plotLabel.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/plotLabel.R b/R/plotLabel.R index 0fc2c63..e52e296 100644 --- a/R/plotLabel.R +++ b/R/plotLabel.R @@ -58,7 +58,7 @@ setMethod("plotLabel", "SpatialData", \(x, i=1, j=1, k=NULL, c=NULL, if (is.numeric(i)) i <- labelNames(x)[i] i <- match.arg(i, labelNames(x)) y <- label(x, i) - ym <- .get_multiscale_data(label(x, i), k) + ym <- .get_multiscale_data(y, k) # Keep only indices != 0 since labels might be sparse and thus save memory by not plotting all pixels idx <- BiocGenerics::which(ym != 0L, arr.ind=TRUE) df <- data.frame(x=idx[,1L], y=idx[,2L], z=ym[idx]) From 8d9936ad719a0c1cc883454d497a296bd5f17f0f Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Tue, 28 Apr 2026 18:36:37 +0200 Subject: [PATCH 07/12] Remove unused thm var It is immediately overwritten --- R/plotLabel.R | 1 - 1 file changed, 1 deletion(-) diff --git a/R/plotLabel.R b/R/plotLabel.R index e52e296..dc285e7 100644 --- a/R/plotLabel.R +++ b/R/plotLabel.R @@ -97,7 +97,6 @@ setMethod("plotLabel", "SpatialData", \(x, i=1, j=1, k=NULL, c=NULL, theme(legend.key.size=unit(0.5, "lines")), scale_fill_gradientn(c, colors=pal, na.value=nan))) } else { - thm <- guides(fill="none") aes$fill <- aes(.data$z != 0)[[1]] thm <- list( theme(legend.position="none"), From d2b36ccc3eefc31e8a28a326c7176d2067d47c21 Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Thu, 7 May 2026 13:17:53 +0200 Subject: [PATCH 08/12] Use new workflow for transformations --- R/plotLabel.R | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/R/plotLabel.R b/R/plotLabel.R index dc285e7..b9a8de5 100644 --- a/R/plotLabel.R +++ b/R/plotLabel.R @@ -58,15 +58,15 @@ setMethod("plotLabel", "SpatialData", \(x, i=1, j=1, k=NULL, c=NULL, if (is.numeric(i)) i <- labelNames(x)[i] i <- match.arg(i, labelNames(x)) y <- label(x, i) + # transformation + if (is.numeric(j)) + j <- CTname(y)[j] + y <- transform(y, j) ym <- .get_multiscale_data(y, k) + # Keep only indices != 0 since labels might be sparse and thus save memory by not plotting all pixels idx <- BiocGenerics::which(ym != 0L, arr.ind=TRUE) df <- data.frame(x=idx[,1L], y=idx[,2L], z=ym[idx]) - # transformation - if (is.numeric(j)) - j <- CTname(y)[j] - ts <- CTpath(x, i, j) - df[,c("x", "y")] <- .trans_xy(df[,c("x", "y")], ts) aes <- aes(.data[["x"]], .data[["y"]]) if (!is.null(c)) { stopifnot(length(c) == 1, is.character(c)) From 28db4da1b58a1474ce69ce7e25722870ef42b8b2 Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Thu, 7 May 2026 13:22:19 +0200 Subject: [PATCH 09/12] Remove now unused trans.R file --- R/trans.R | 39 --------------------------------------- 1 file changed, 39 deletions(-) delete mode 100644 R/trans.R diff --git a/R/trans.R b/R/trans.R deleted file mode 100644 index 0ee4f31..0000000 --- a/R/trans.R +++ /dev/null @@ -1,39 +0,0 @@ -# TODO: deprecate this; all should be handled by SD - -# count occurrences of each coordinate space; -# return most frequent (in order of appearance) -.guess_space <- \(x) { - nms <- lapply(rownames(x), \(l) - lapply(colnames(x)[[l]], \(e) - CTname(x[[l]][[e]]))) - cnt <- table(nms <- unlist(nms)) - cnt <- cnt[unique(nms)] - names(which.max(cnt)) -} - -.trans_xy <- \(xy, ts, rev=FALSE) { - if (rev) ts <- rev(ts) - for (. in seq_along(ts)) { - t <- ts[[.]]$type - d <- ts[[.]]$data - d <- unlist(d) - if (length(d) == 3) - d <- d[-1] - switch(t, - identity={}, - scale={ - op <- ifelse(rev, `/`, `*`) - xy$x <- op(xy$x, d[2]) - xy$y <- op(xy$y, d[1]) - }, - rotate={ - xy <- xy %*% .R(d*pi/180) - }, - translation={ - op <- ifelse(rev, `-`, `+`) - xy$x <- op(xy$x, d[2]) - xy$y <- op(xy$y, d[1]) - }) - } - return(xy) -} From 4be54a70a2f8205bf4c00ed20bf3539ad2e715f1 Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Thu, 7 May 2026 13:26:15 +0200 Subject: [PATCH 10/12] Flip labels --- R/plotLabel.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/R/plotLabel.R b/R/plotLabel.R index b9a8de5..fe4601b 100644 --- a/R/plotLabel.R +++ b/R/plotLabel.R @@ -66,7 +66,8 @@ setMethod("plotLabel", "SpatialData", \(x, i=1, j=1, k=NULL, c=NULL, # Keep only indices != 0 since labels might be sparse and thus save memory by not plotting all pixels idx <- BiocGenerics::which(ym != 0L, arr.ind=TRUE) - df <- data.frame(x=idx[,1L], y=idx[,2L], z=ym[idx]) + # All other SD elements are flipped when plotted. Let's keep the same convention here. + df <- data.frame(x=idx[,2L], y=idx[,1L], z=ym[idx]) aes <- aes(.data[["x"]], .data[["y"]]) if (!is.null(c)) { stopifnot(length(c) == 1, is.character(c)) From 57ff56422f4e233bb02309eade5694675f5e5028 Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Thu, 7 May 2026 14:22:58 +0200 Subject: [PATCH 11/12] Fix imports --- DESCRIPTION | 2 +- R/plotImage.R | 7 ++----- R/plotLabel.R | 6 +++--- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index b7f19f1..2e0439c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -67,8 +67,8 @@ biocViews: GeneExpression, Transcriptomics License: Artistic-2.0 -RoxygenNote: 7.3.3 Encoding: UTF-8 VignetteBuilder: knitr URL: https://github.com/HelenaLC/SpatialData.plot BugReports: https://github.com/HelenaLC/SpatialData.plot/issues +Config/roxygen2/version: 8.0.0 diff --git a/R/plotImage.R b/R/plotImage.R index af979e4..3718db1 100644 --- a/R/plotImage.R +++ b/R/plotImage.R @@ -178,11 +178,8 @@ NULL list(w=df[, 1], h=df[, 2]) } -#' @importFrom ggplot2 guides geom_point -#' geom_blank annotation_raster -#' scale_color_identity -#' scale_x_continuous -#' scale_y_reverse +#' @importFrom ggplot2 guides geom_point geom_blank annotation_raster +#' @importFrom ggplot2 scale_color_identity scale_x_continuous scale_y_reverse .gg_i <- \(x, w, h, pal=NULL) { l <- if (!is.null(names(pal))) list( guides(col=guide_legend(override.aes=list(alpha=1, size=2))), diff --git a/R/plotLabel.R b/R/plotLabel.R index fe4601b..ad56a29 100644 --- a/R/plotLabel.R +++ b/R/plotLabel.R @@ -48,9 +48,9 @@ NULL #' @importFrom S4Vectors metadata #' @importFrom rlang .data #' @importFrom methods as -#' @importFrom ggplot2 -#' scale_fill_manual scale_fill_gradientn -#' aes geom_tile theme unit guides guide_legend +#' @importFrom ggplot2 scale_fill_manual scale_fill_gradientn +#' @importFrom ggplot2 aes theme unit guides guide_legend geom_tile +#' #' @importFrom SingleCellExperiment colData #' @export setMethod("plotLabel", "SpatialData", \(x, i=1, j=1, k=NULL, c=NULL, From bc244e71a0b9599b4a5da6b0a42a7c82da5b0b94 Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Thu, 7 May 2026 14:24:01 +0200 Subject: [PATCH 12/12] Ensure labels are shifted correctly when plotted --- R/plotLabel.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/R/plotLabel.R b/R/plotLabel.R index ad56a29..9b7b13e 100644 --- a/R/plotLabel.R +++ b/R/plotLabel.R @@ -63,11 +63,12 @@ setMethod("plotLabel", "SpatialData", \(x, i=1, j=1, k=NULL, c=NULL, j <- CTname(y)[j] y <- transform(y, j) ym <- .get_multiscale_data(y, k) + wh <- .get_wh(y) # Keep only indices != 0 since labels might be sparse and thus save memory by not plotting all pixels idx <- BiocGenerics::which(ym != 0L, arr.ind=TRUE) # All other SD elements are flipped when plotted. Let's keep the same convention here. - df <- data.frame(x=idx[,2L], y=idx[,1L], z=ym[idx]) + df <- data.frame(x=idx[,2L]+wh$w[1], y=idx[,1L]+wh$h[1], z=ym[idx]) aes <- aes(.data[["x"]], .data[["y"]]) if (!is.null(c)) { stopifnot(length(c) == 1, is.character(c))