From 9a934d217294410f2e4890d585a5b7281d21b7ff Mon Sep 17 00:00:00 2001 From: nfrerebeau Date: Thu, 21 Nov 2024 19:01:36 +0100 Subject: [PATCH] Add functions to compute tile colors --- R/ternary_density.R | 10 +- R/ternary_image.R | 77 +- inst/tinytest/_tinysnapshot/image_density.svg | 662 +++++ .../tinytest/_tinysnapshot/image_function.svg | 2367 ----------------- .../_tinysnapshot/image_interpolate.svg | 245 ++ inst/tinytest/test_geometry.R | 14 - inst/tinytest/test_statistics.R | 56 +- inst/tinytest/test_tiles.R | 35 + 8 files changed, 1041 insertions(+), 2425 deletions(-) create mode 100644 inst/tinytest/_tinysnapshot/image_density.svg delete mode 100644 inst/tinytest/_tinysnapshot/image_function.svg create mode 100644 inst/tinytest/_tinysnapshot/image_interpolate.svg create mode 100644 inst/tinytest/test_tiles.R diff --git a/R/ternary_density.R b/R/ternary_density.R index 7ac40a4..d4c6eac 100644 --- a/R/ternary_density.R +++ b/R/ternary_density.R @@ -92,7 +92,8 @@ coordinates_kde <- function(x, y, z, h = NULL, n = 25, y = ratio[, 2], h = h, n = n, - lims = c(lims, lims) # x and y range should be same + xlim = lims, # x and y range should be same + ylim = lims ) ## Compute contours @@ -106,10 +107,11 @@ coordinates_kde <- function(x, y, z, h = NULL, n = 25, } ## Adapted from MASS::kde2d -kde <- function(x, y, h = NULL, n = 25, lims = c(range(x), range(y))) { +kde <- function(x, y, h = NULL, n = 25, gx = NULL, gy = NULL, + xlim = range(x), ylim = range(y)) { n <- rep(n, length.out = 2L) - gx <- seq(lims[1L], lims[2L], length.out = n[1L]) - gy <- seq(lims[3L], lims[4L], length.out = n[2L]) + if (is.null(gx)) gx <- seq(xlim[1L], xlim[2L], length.out = n[1L]) + if (is.null(gy)) gy <- seq(ylim[1L], ylim[2L], length.out = n[2L]) if (is.null(h)) { h <- c(bandwidth(x), bandwidth(y)) diff --git a/R/ternary_image.R b/R/ternary_image.R index 291b7ea..ef50950 100644 --- a/R/ternary_image.R +++ b/R/ternary_image.R @@ -13,31 +13,90 @@ setMethod( tri <- .triangle_center(n) xyz <- coordinates_cartesian(tri$x, tri$y) val <- f(xyz$x, xyz$y, xyz$z, ...) + ok <- seq_along(tri$x) if (isFALSE(palette)) { color <- val } if (is.null(palette)) { - palette <- function(x) { - x <- (x - min(x)) / (max(x) - min(x)) # Rescale to [0,1] - col <- grDevices::hcl.colors(256L, palette = "viridis") - grDevices::rgb(grDevices::colorRamp(col)(x), maxColorValue = 255) - } + palette <- function(x) { + x <- (x - min(x)) / (max(x) - min(x)) # Rescale to [0,1] + col <- grDevices::hcl.colors(256L, palette = "viridis") + grDevices::rgb(grDevices::colorRamp(col)(x), maxColorValue = 255) + } } if (is.function(palette)) { - color <- palette(val) + ok <- is.finite(val) # Remove NA/Inf (if any) + color <- palette(val[ok]) } .triangle_tile( - x = tri$x, - y = tri$y, - direction = tri$direction, + x = tri$x[ok], + y = tri$y[ok], + direction = tri$direction[ok], resolution = tri$resolution, col = color ) } ) +xyz_density <- function(x, y, z) { + ## ILR + coda <- cbind(x, y, z) + ratio <- ilr(coda) + + ## Compute KDE + function(x, y, z) { + xyz <- cbind(x, y, z) + xy <- ilr(xyz) + dens <- kde( + x = ratio[, 1], + y = ratio[, 2], + gx = sort(unique(xy[, 1])), + gy = sort(unique(xy[, 2])) + ) + + i <- as.numeric(as.factor(rank(xy[, 1]))) + j <- as.numeric(as.factor(rank(xy[, 2]))) + + dens$z[cbind(i, j)] + } +} + +xyz_interpolate <- function(x, y, z, value, method = "linear", ...) { + ## Validation + if (!requireNamespace("interp", quietly = TRUE)) { + msg <- "The interp package is required. Please install it." + stop(msg, call. = FALSE) + } + assert_length(value, length(x)) + + ## ILR + coda <- cbind(x, y, z) + ratio <- ilr(coda) + + ## Compute KDE + function(x, y, z) { + xyz <- cbind(x, y, z) + xy <- ilr(xyz) + + interp <- interp::interp( + x = ratio[, 1], + y = ratio[, 2], + z = value, + xo = sort(unique(xy[, 1])), + yo = sort(unique(xy[, 2])), + method = method, + ... + ) + + i <- as.numeric(as.factor(rank(xy[, 1]))) + j <- as.numeric(as.factor(rank(xy[, 2]))) + + interp$z[cbind(i, j)] + } +} + .triangle_center <- function(resolution) { offset <- 1 / resolution / 2L diff --git a/inst/tinytest/_tinysnapshot/image_density.svg b/inst/tinytest/_tinysnapshot/image_density.svg new file mode 100644 index 0000000..43d4311 --- /dev/null +++ b/inst/tinytest/_tinysnapshot/image_density.svg @@ -0,0 +1,662 @@ + + + + + + + + + + + + + + + + + + + +20 +40 +60 +80 + + + + + +20 +40 +60 +80 + + + + + +20 +40 +60 +80 + + + + + + +x +y +z + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inst/tinytest/_tinysnapshot/image_function.svg b/inst/tinytest/_tinysnapshot/image_function.svg deleted file mode 100644 index 0f2ce6e..0000000 --- a/inst/tinytest/_tinysnapshot/image_function.svg +++ /dev/null @@ -1,2367 +0,0 @@ - - - - - - - - - - - - - - - - - - - -20 -40 -60 -80 - - - - - -20 -40 -60 -80 - - - - - -20 -40 -60 -80 - - - - - - -x -y -z - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/inst/tinytest/_tinysnapshot/image_interpolate.svg b/inst/tinytest/_tinysnapshot/image_interpolate.svg new file mode 100644 index 0000000..47de9ba --- /dev/null +++ b/inst/tinytest/_tinysnapshot/image_interpolate.svg @@ -0,0 +1,245 @@ + + + + + + + + + + + + + + + + + + + +20 +40 +60 +80 + + + + + +20 +40 +60 +80 + + + + + +20 +40 +60 +80 + + + + + + +x +y +z + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inst/tinytest/test_geometry.R b/inst/tinytest/test_geometry.R index ca46c8b..d2b3330 100644 --- a/inst/tinytest/test_geometry.R +++ b/inst/tinytest/test_geometry.R @@ -74,18 +74,4 @@ if (at_home()) { ternary_text(coda, col = "red") } expect_snapshot_plot(geom_text, "geom_text") - - # Image ====================================================================== - f <- function(x, y, z) x - z + (3 * x * y) + (50 * x * y * z) - image_function <- function() { - ternary_plot(NULL) - ternary_image(f = f, n = 48) - } - expect_snapshot_plot(image_function, "image_function") - - image_rgb <- function() { - ternary_plot(NULL, xlab = "Red", ylab = "Green", zlab = "Blue") - ternary_image(f = grDevices::rgb, n = 20, palette = FALSE) - } - expect_snapshot_plot(image_rgb, "image_rgb") } diff --git a/inst/tinytest/test_statistics.R b/inst/tinytest/test_statistics.R index 342a506..a4ff19f 100644 --- a/inst/tinytest/test_statistics.R +++ b/inst/tinytest/test_statistics.R @@ -64,41 +64,35 @@ if (at_home()) { ternary_pca(lava, axis = 1) } expect_snapshot_plot(pca_1, "pca_1") -} -if (at_home() && requireNamespace("interp", quietly = TRUE)) { - using("tinysnapshot") - options(tinysnapshot_device = "svglite") - options(tinysnapshot_height = 7) # inches - options(tinysnapshot_width = 7) - options(tinysnapshot_tol = 200) # pixels - options(tinysnapshot_os = "Linux") # Contour ==================================================================== - a <- matrix(rep(seq(0, 1, length = 50), each = 50), nrow = 50, byrow = TRUE) - b <- matrix(rep(seq(0, 1, length = 50), each = 50), nrow = 50, byrow = FALSE) - mask <- a + b <= 1 - a <- a[mask] - b <- b[mask] - coords <- cbind(b, 1 - a - b, a) - value <- sin(3.2 * pi * (a + b)) + sin(3 * pi * (a - b)) + if (requireNamespace("interp", quietly = TRUE)) { + a <- matrix(rep(seq(0, 1, length = 50), each = 50), nrow = 50, byrow = TRUE) + b <- matrix(rep(seq(0, 1, length = 50), each = 50), nrow = 50, byrow = FALSE) + mask <- a + b <= 1 + a <- a[mask] + b <- b[mask] + coords <- cbind(b, 1 - a - b, a) + value <- sin(3.2 * pi * (a + b)) + sin(3 * pi * (a - b)) - # col <- colorRamp(c("blue", "red"))(scales::rescale_mid(value)) - # col <- rgb(col[, 1], col[, 2], col[, 3], maxColorValue = 255) - # ternary_plot(coords, panel.first = ternary_grid(), pch = 16, col = col) + # col <- colorRamp(c("blue", "red"))(scales::rescale_mid(value)) + # col <- rgb(col[, 1], col[, 2], col[, 3], maxColorValue = 255) + # ternary_plot(coords, panel.first = ternary_grid(), pch = 16, col = col) - ## Contour ILR - contour_ilr <- function() { - ternary_plot(NULL) - ternary_contour(coords, value = value, n = 100, nlevels = 10, ilr = TRUE) - } - expect_snapshot_plot(contour_ilr, "contour_ilr") + ## Contour ILR + contour_ilr <- function() { + ternary_plot(NULL) + ternary_contour(coords, value = value, n = 100, nlevels = 10, ilr = TRUE) + } + expect_snapshot_plot(contour_ilr, "contour_ilr") - ## Contour Cartesian - contour_cartesian <- function() { - ternary_plot(NULL) - suppressWarnings( # Remove warnings (collinear points) - ternary_contour(coords, value = value, n = 100, nlevels = 10, ilr = FALSE) - ) + ## Contour Cartesian + contour_cartesian <- function() { + ternary_plot(NULL) + suppressWarnings( # Remove warnings (collinear points) + ternary_contour(coords, value = value, n = 100, nlevels = 10, ilr = FALSE) + ) + } + expect_snapshot_plot(contour_cartesian, "contour_cartesian") } - expect_snapshot_plot(contour_cartesian, "contour_cartesian") } diff --git a/inst/tinytest/test_tiles.R b/inst/tinytest/test_tiles.R new file mode 100644 index 0000000..57ffaba --- /dev/null +++ b/inst/tinytest/test_tiles.R @@ -0,0 +1,35 @@ +if (at_home()) { + using("tinysnapshot") + options(tinysnapshot_device = "svglite") + options(tinysnapshot_height = 7) # inches + options(tinysnapshot_width = 7) + options(tinysnapshot_tol = 200) # pixels + options(tinysnapshot_os = "Linux") + + # Image ====================================================================== + image_rgb <- function() { + ternary_plot(NULL, xlab = "Red", ylab = "Green", zlab = "Blue") + ternary_image(f = grDevices::rgb, n = 20, palette = FALSE) + } + expect_snapshot_plot(image_rgb, "image_rgb") + + # Density ==================================================================== + f <- isopleuros:::xyz_density(lava[, 1], lava[, 2], lava[, 3]) + image_density <- function() { + ternary_plot(NULL) + ternary_image(f = f, n = 24) + ternary_points(lava, col = "red", pch = 16) + } + expect_snapshot_plot(image_density, "image_density") + + # Interpolation ============================================================== + if (requireNamespace("interp", quietly = TRUE)) { + f <- isopleuros:::xyz_interpolate(arctic[, 1], arctic[, 2], arctic[, 3], value = arctic$depth) + image_interpolate <- function() { + ternary_plot(NULL) + ternary_image(f = f, n = 24) + ternary_points(arctic, col = "red", pch = 16) + } + expect_snapshot_plot(image_interpolate, "image_interpolate") + } +}