Nothing
# Tests for aesthetic specification equivalence in tf_ggplot
# Verifies that aesthetics can be specified in constructor or geom layer with identical results
test_that("tf aesthetics in constructor vs geom layer are equivalent - basic case", {
skip_if_not_installed("ggplot2")
skip_if_no_tf_ggplot()
data <- create_test_tf_data(n_funcs = 3, n_points = 5)
# Method 1: tf aesthetic in constructor
p1 <- tf_ggplot(data, aes(tf = func)) + geom_line()
# Method 2: tf aesthetic in geom layer
p2 <- tf_ggplot(data) + geom_line(aes(tf = func))
# Build both plots
built1 <- ggplot_build(p1)
built2 <- ggplot_build(p2)
# Should have identical data structure
expect_equal(nrow(built1$data[[1]]), nrow(built2$data[[1]]))
expect_equal(ncol(built1$data[[1]]), ncol(built2$data[[1]]))
expect_equal(names(built1$data[[1]]), names(built2$data[[1]]))
# Should have same number of groups
expect_equal(
length(unique(built1$data[[1]]$group)),
length(unique(built2$data[[1]]$group))
)
# x and y values should be identical (allowing for floating point differences)
expect_equal(sort(built1$data[[1]]$x), sort(built2$data[[1]]$x))
expect_equal(
sort(built1$data[[1]]$y),
sort(built2$data[[1]]$y),
tolerance = 1e-10
)
})
test_that("tf aesthetics with color mapping are equivalent", {
skip_if_not_installed("ggplot2")
skip_if_no_tf_ggplot()
data <- create_test_tf_data(n_funcs = 4, n_points = 6)
# Method 1: aesthetics in constructor
p1 <- tf_ggplot(data, aes(tf = func, color = group)) + geom_line()
# Method 2: aesthetics in geom layer
p2 <- tf_ggplot(data) +
geom_line(aes(tf = func, color = group))
built1 <- ggplot_build(p1)
built2 <- ggplot_build(p2)
# Should have identical structure
expect_equal(dim(built1$data[[1]]), dim(built2$data[[1]]))
# Color mappings should be identical
expect_equal(sort(built1$data[[1]]$colour), sort(built2$data[[1]]$colour))
# Groups should be identical
expect_equal(sort(built1$data[[1]]$group), sort(built2$data[[1]]$group))
# Check that color is consistent within groups for both methods
check_color_consistency <- function(plot_data) {
color_by_group <- split(plot_data$colour, plot_data$group)
all(sapply(color_by_group, function(x) length(unique(x)) == 1))
}
expect_true(check_color_consistency(built1$data[[1]]))
expect_true(check_color_consistency(built2$data[[1]]))
})
test_that("mixed tf and regular aesthetics are equivalent", {
skip_if_not_installed("ggplot2")
skip_if_no_tf_ggplot()
data <- create_test_tf_data(n_funcs = 3, n_points = 5)
data$lw_var <- c(1, 2, 3)
data$alpha_var <- c(0.3, 0.7, 0.9)
# Method 1: mixed aesthetics in constructor
p1 <- tf_ggplot(
data,
aes(tf = func, color = group, linewidth = lw_var, alpha = alpha_var)
) +
geom_line()
# Method 2: mixed aesthetics in geom layer
p2 <- tf_ggplot(data) +
geom_line(aes(
tf = func,
color = group,
linewidth = lw_var,
alpha = alpha_var
))
built1 <- ggplot_build(p1)
built2 <- ggplot_build(p2)
# Should have identical dimensions and structure
expect_equal(dim(built1$data[[1]]), dim(built2$data[[1]]))
expect_setequal(names(built1$data[[1]]), names(built2$data[[1]]))
# All aesthetic mappings should be identical
aesthetic_cols <- c("colour", "linewidth", "alpha")
for (col in aesthetic_cols) {
expect_equal(
sort(built1$data[[1]][[col]]),
sort(built2$data[[1]][[col]]),
info = paste("Mismatch in", col, "aesthetic")
)
}
})
test_that("multiple tf aesthetics are equivalent", {
skip_if_not_installed("ggplot2")
skip_if_no_tf_ggplot()
data <- create_multi_tf_data(n_funcs = 2, n_points = 4)
# Method 1: multiple tf aesthetics in constructor
p1 <- tf_ggplot(data, aes(tf_x = func1, tf_y = func2)) + geom_point()
# Method 2: multiple tf aesthetics in geom layer
p2 <- tf_ggplot(data) +
geom_point(aes(tf_x = func1, tf_y = func2))
built1 <- ggplot_build(p1)
built2 <- ggplot_build(p2)
# Should have identical structure
expect_equal(dim(built1$data[[1]]), dim(built2$data[[1]]))
# x and y coordinates should be identical
expect_equal(sort(built1$data[[1]]$x), sort(built2$data[[1]]$x))
expect_equal(sort(built1$data[[1]]$y), sort(built2$data[[1]]$y))
# Groups should be identical
expect_equal(sort(built1$data[[1]]$group), sort(built2$data[[1]]$group))
})
test_that("ribbon tf aesthetics are equivalent", {
skip_if_not_installed("ggplot2")
skip_if_no_tf_ggplot()
data <- create_band_tf_data(n_funcs = 2, n_points = 5)
# Method 1: ribbon aesthetics in constructor
p1 <- tf_ggplot(data, aes(tf_ymin = lower_func, tf_ymax = upper_func)) +
geom_ribbon(alpha = 0.3)
# Method 2: ribbon aesthetics in geom layer
p2 <- tf_ggplot(data) +
geom_ribbon(
aes(tf_ymin = lower_func, tf_ymax = upper_func),
alpha = 0.3
)
built1 <- ggplot_build(p1)
built2 <- ggplot_build(p2)
# Should have identical structure
expect_equal(dim(built1$data[[1]]), dim(built2$data[[1]]))
# ymin and ymax should be identical
expect_equal(sort(built1$data[[1]]$ymin), sort(built2$data[[1]]$ymin))
expect_equal(sort(built1$data[[1]]$ymax), sort(built2$data[[1]]$ymax))
# Alpha should be identical
expect_equal(built1$data[[1]]$alpha, built2$data[[1]]$alpha)
})
test_that("aesthetic inheritance and override work correctly", {
skip_if_not_installed("ggplot2")
skip_if_no_tf_ggplot()
data <- create_test_tf_data(n_funcs = 3, n_points = 5)
# Base aesthetics in constructor, additional in geom
p1 <- tf_ggplot(data, aes(tf = func)) +
geom_line(aes(color = group))
# All aesthetics in geom layer
p2 <- tf_ggplot(data) +
geom_line(aes(tf = func, color = group))
built1 <- ggplot_build(p1)
built2 <- ggplot_build(p2)
# Should produce identical results
expect_equal(dim(built1$data[[1]]), dim(built2$data[[1]]))
expect_equal(sort(built1$data[[1]]$colour), sort(built2$data[[1]]$colour))
expect_equal(sort(built1$data[[1]]$x), sort(built2$data[[1]]$x))
expect_equal(sort(built1$data[[1]]$y), sort(built2$data[[1]]$y))
})
test_that("aesthetic override in geom layer works", {
skip_if_not_installed("ggplot2")
skip_if_no_tf_ggplot()
data <- create_test_tf_data(n_funcs = 3, n_points = 5)
data$alt_group <- factor(c("X", "Y", "Z"))
# Constructor aesthetic overridden in geom
p1 <- tf_ggplot(data, aes(tf = func, color = group)) +
geom_line(aes(color = alt_group)) # Override color aesthetic
# Direct specification in geom
p2 <- tf_ggplot(data, aes(tf = func)) +
geom_line(aes(color = alt_group))
built1 <- ggplot_build(p1)
built2 <- ggplot_build(p2)
# Should use alt_group for coloring in both cases
expect_equal(sort(built1$data[[1]]$colour), sort(built2$data[[1]]$colour))
# Should have 3 unique colors (X, Y, Z)
expect_equal(length(unique(built1$data[[1]]$colour)), 3)
expect_equal(length(unique(built2$data[[1]]$colour)), 3)
})
test_that("faceting works equivalently with different aesthetic specifications", {
skip_if_not_installed("ggplot2")
skip_if_no_tf_ggplot()
data <- create_test_tf_data(n_funcs = 6, n_points = 4)
data$treatment <- factor(rep(c("A", "B"), each = 3))
# Method 1: aesthetics in constructor
p1 <- tf_ggplot(data, aes(tf = func)) +
geom_line() +
facet_wrap(~treatment)
# Method 2: aesthetics in geom layer
p2 <- tf_ggplot(data) +
geom_line(aes(tf = func)) +
facet_wrap(~treatment)
built1 <- ggplot_build(p1)
built2 <- ggplot_build(p2)
# Should have identical panel structure
expect_equal(dim(built1$layout$layout), dim(built2$layout$layout))
expect_equal(built1$layout$layout$PANEL, built2$layout$layout$PANEL)
# Plot data should be identical
expect_equal(dim(built1$data[[1]]), dim(built2$data[[1]]))
expect_equal(sort(built1$data[[1]]$PANEL), sort(built2$data[[1]]$PANEL))
})
test_that("custom arg parameter works equivalently", {
skip_if_not_installed("ggplot2")
skip_if_no_tf_ggplot()
data <- create_test_tf_data(n_funcs = 2, n_points = 11)
custom_arg <- seq(0, 1, length.out = 6)
# Method 1: aesthetics in constructor with custom arg
p1 <- tf_ggplot(data, aes(tf = func), arg = custom_arg) + geom_line()
# Method 2: aesthetics in geom layer with custom arg
p2 <- tf_ggplot(data, arg = custom_arg) +
geom_line(aes(tf = func))
built1 <- ggplot_build(p1)
built2 <- ggplot_build(p2)
# Should use custom arg in both cases
expect_equal(sort(unique(built1$data[[1]]$x)), custom_arg)
expect_equal(sort(unique(built2$data[[1]]$x)), custom_arg)
# Should have identical structure
expect_equal(dim(built1$data[[1]]), dim(built2$data[[1]]))
expect_equal(sort(built1$data[[1]]$x), sort(built2$data[[1]]$x))
expect_equal(sort(built1$data[[1]]$y), sort(built2$data[[1]]$y))
})
test_that("multiple layers with different aesthetic specifications work", {
skip_if_not_installed("ggplot2")
skip_if_no_tf_ggplot()
data <- create_test_tf_data(n_funcs = 2, n_points = 5)
# Mix of constructor and geom-level aesthetics across multiple layers
p1 <- tf_ggplot(data, aes(tf = func)) +
geom_line(aes(color = group)) +
geom_point(aes(color = group), size = 2)
# All aesthetics specified at geom level
p2 <- tf_ggplot(data) +
geom_line(aes(tf = func, color = group)) +
geom_point(aes(tf = func, color = group), size = 2)
built1 <- ggplot_build(p1)
built2 <- ggplot_build(p2)
# Should have same number of layers
expect_equal(length(built1$data), length(built2$data))
# Each layer should be identical
for (i in seq_along(built1$data)) {
expect_equal(
dim(built1$data[[i]]),
dim(built2$data[[i]]),
info = paste("Layer", i, "dimensions differ")
)
expect_equal(
sort(built1$data[[i]]$x),
sort(built2$data[[i]]$x),
info = paste("Layer", i, "x values differ")
)
expect_equal(
sort(built1$data[[i]]$y),
sort(built2$data[[i]]$y),
info = paste("Layer", i, "y values differ")
)
expect_equal(
sort(built1$data[[i]]$colour),
sort(built2$data[[i]]$colour),
info = paste("Layer", i, "color values differ")
)
}
})
test_that("data transformation is identical regardless of aesthetic specification method", {
skip_if_not_installed("ggplot2")
skip_if_no_tf_ggplot()
data <- create_test_tf_data(n_funcs = 3, n_points = 7)
data$extra_var <- letters[1:3]
# Complex aesthetic mapping
aesthetic_mapping <- aes(tf = func, color = group, linetype = extra_var)
# Method 1: in constructor
p1 <- tf_ggplot(data, aesthetic_mapping) + geom_line()
# Method 2: in geom layer
p2 <- tf_ggplot(data) + geom_line(aesthetic_mapping)
built1 <- ggplot_build(p1)
built2 <- ggplot_build(p2)
# Extract and sort all data for comparison
data1 <- built1$data[[1]][order(built1$data[[1]]$group, built1$data[[1]]$x), ]
data2 <- built2$data[[1]][order(built2$data[[1]]$group, built2$data[[1]]$x), ]
# Reset row names for comparison
rownames(data1) <- NULL
rownames(data2) <- NULL
# Should be completely identical
common_cols <- sort(intersect(names(data1), names(data2)))
expect_equal(data1[common_cols], data2[common_cols])
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.