From 209d6b372d898e9cea159bc1f26c2b56d238aa54 Mon Sep 17 00:00:00 2001 From: dereckdemezquita Date: Sun, 9 Apr 2023 10:46:40 -0500 Subject: [PATCH 01/16] Vlines and Hlines might sometimes be inexistant; ggplot2 allows this but plotly fails on merging empty data.frame. --- R/layers2traces.R | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/R/layers2traces.R b/R/layers2traces.R index 5b110cd56e..f42ca2f599 100644 --- a/R/layers2traces.R +++ b/R/layers2traces.R @@ -445,7 +445,9 @@ to_basic.GeomHline <- function(data, prestats_data, layout, params, p, ...) { data = layout$layout, cols = paste0(x, c("_min", "_max")), values_to = x, names_to = "variable" ) lay <- as.data.frame(lay) - data <- merge(lay[c("PANEL", x)], data, by = "PANEL") + if (nrow(data) != 0) { + data <- merge(lay[c("PANEL", x)], data, by = "PANEL") + } data[["x"]] <- data[[x]] data[["y"]] <- data$yintercept prefix_class(data, c("GeomHline", "GeomPath")) @@ -462,7 +464,10 @@ to_basic.GeomVline <- function(data, prestats_data, layout, params, p, ...) { data = layout$layout, cols = paste0(y, c("_min", "_max")), values_to = y, names_to = "variable" ) lay <- as.data.frame(lay) - data <- merge(lay[c("PANEL", y)], data, by = "PANEL") + # fix for #1947; applied to Hline as well + if (nrow(data) != 0) { + data <- merge(lay[c("PANEL", y)], data, by = "PANEL") + } data[["y"]] <- data[[y]] data[["x"]] <- data$xintercept prefix_class(data, c("GeomVline", "GeomPath")) From dfd9835c07cb874efe71c9606a4e8546bb038320 Mon Sep 17 00:00:00 2001 From: dereckdemezquita Date: Sun, 9 Apr 2023 11:13:35 -0500 Subject: [PATCH 02/16] Unit test for allowing empty vlines. --- .../test-geom-vline-hline-allow-none-1947.R | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 tests/testthat/test-geom-vline-hline-allow-none-1947.R diff --git a/tests/testthat/test-geom-vline-hline-allow-none-1947.R b/tests/testthat/test-geom-vline-hline-allow-none-1947.R new file mode 100644 index 0000000000..e9f9e919fc --- /dev/null +++ b/tests/testthat/test-geom-vline-hline-allow-none-1947.R @@ -0,0 +1,39 @@ + +test_that("geom_vline/geom_hline does not throw an error with ggplotly when no lines are found", { + # Prepare data + data <- data.table::data.table(gapminder::gapminder) + # Add year of interest for vertical lines + data[year == 2002, year_of_interest := "yoi"] + + # Case 1: Vertical line by feeding data to it; this allows for programmatically setting many lines at different years + p1 <- ggplot2::ggplot(data, ggplot2::aes(x = year, y = lifeExp, colour = country)) + + ggplot2::geom_line() + + ggplot2::geom_vline( + ggplot2::aes(xintercept = year), + data = data[year_of_interest == "yoi", ], + colour = "yellow", + alpha = 0.75, + linewidth = 1.25, + linetype = "dashed" + ) + + ggplot2::theme(legend.position = "none") + + # Case 2: No lines are found, ggplot2 accepts it and no error is thrown + p2 <- ggplot2::ggplot(data, ggplot2::aes(x = year, y = lifeExp, colour = country)) + + ggplot2::geom_line() + + ggplot2::geom_vline( + ggplot2::aes(xintercept = year), + data = data[year_of_interest == "some_not_found", ], + colour = "yellow", + alpha = 0.75, + linewidth = 1.25, + linetype = "dashed" + ) + + ggplot2::theme(legend.position = "none") + + # Test that ggplotly does not throw an error for both cases + expect_error(plotly::ggplotly(p1), NA) # lines are found no error is thrown + # error: + # "Error in fix.by(by.y, y) : 'by' must specify a uniquely valid column" + expect_error(plotly::ggplotly(p2), "Error in fix.by") # no lines are found no error is thrown +}) From 27bba16c0c4c79c7492f24d80a9018054b74607d Mon Sep 17 00:00:00 2001 From: dereckdemezquita Date: Sun, 9 Apr 2023 11:21:19 -0500 Subject: [PATCH 03/16] Added horizontal line test. --- .../test-geom-vline-hline-allow-none-1947.R | 42 ++++++++++++++++++- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/tests/testthat/test-geom-vline-hline-allow-none-1947.R b/tests/testthat/test-geom-vline-hline-allow-none-1947.R index e9f9e919fc..ddb52dc1b9 100644 --- a/tests/testthat/test-geom-vline-hline-allow-none-1947.R +++ b/tests/testthat/test-geom-vline-hline-allow-none-1947.R @@ -18,6 +18,9 @@ test_that("geom_vline/geom_hline does not throw an error with ggplotly when no l ) + ggplot2::theme(legend.position = "none") + # Test that ggplotly does not throw an error for both cases + expect_error(plotly::ggplotly(p1), NA) # lines are found no error is thrown + # Case 2: No lines are found, ggplot2 accepts it and no error is thrown p2 <- ggplot2::ggplot(data, ggplot2::aes(x = year, y = lifeExp, colour = country)) + ggplot2::geom_line() + @@ -31,9 +34,44 @@ test_that("geom_vline/geom_hline does not throw an error with ggplotly when no l ) + ggplot2::theme(legend.position = "none") - # Test that ggplotly does not throw an error for both cases - expect_error(plotly::ggplotly(p1), NA) # lines are found no error is thrown # error: # "Error in fix.by(by.y, y) : 'by' must specify a uniquely valid column" expect_error(plotly::ggplotly(p2), "Error in fix.by") # no lines are found no error is thrown + + ## -------------------------------- + # testing horizontal line + data[round(lifeExp, 0) == 50, val_of_interest := "voi"] + + # horizontal line no error + p3 <- ggplot2::ggplot(data, ggplot2::aes(x = year, y = lifeExp, colour = country)) + + ggplot2::geom_line() + + ggplot2::geom_hline( + ggplot2::aes(yintercept = lifeExp), + data = data[val_of_interest == "voi", ], + colour = "pink", + alpha = 0.75, + linewidth = 1.25, + linetype = "dashed" + ) + + ggplot2::theme(legend.position = "none") + + expect_error(plotly::ggplotly(p3), NA) # lines are found no error is thrown + + # horizontal line not set; error + p4 <- ggplot2::ggplot(data, ggplot2::aes(x = year, y = lifeExp, colour = country)) + + ggplot2::geom_line() + + ggplot2::geom_hline( + ggplot2::aes(yintercept = lifeExp), + data = data[val_of_interest == "some_val_not_found", ], + colour = "pink", + alpha = 0.75, + linewidth = 1.25, + linetype = "dashed" + ) + + ggplot2::theme(legend.position = "none") + + # ggplot2 allows this no error + # print(p4) + # "Error in fix.by(by.y, y) : 'by' must specify a uniquely valid column" + expect_error(plotly::ggplotly(p4), "Error in fix.by") # no lines are found no error is thrown }) From 609085500028784a7813afd880754cbc441f0d1d Mon Sep 17 00:00:00 2001 From: dereckdemezquita Date: Mon, 10 Apr 2023 21:54:45 -0500 Subject: [PATCH 04/16] If data is greater than nrow 0; better data check. --- R/layers2traces.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/layers2traces.R b/R/layers2traces.R index f42ca2f599..2a7c7dd4a4 100644 --- a/R/layers2traces.R +++ b/R/layers2traces.R @@ -445,7 +445,7 @@ to_basic.GeomHline <- function(data, prestats_data, layout, params, p, ...) { data = layout$layout, cols = paste0(x, c("_min", "_max")), values_to = x, names_to = "variable" ) lay <- as.data.frame(lay) - if (nrow(data) != 0) { + if (nrow(data) > 0) { data <- merge(lay[c("PANEL", x)], data, by = "PANEL") } data[["x"]] <- data[[x]] @@ -465,7 +465,7 @@ to_basic.GeomVline <- function(data, prestats_data, layout, params, p, ...) { ) lay <- as.data.frame(lay) # fix for #1947; applied to Hline as well - if (nrow(data) != 0) { + if (nrow(data) > 0) { data <- merge(lay[c("PANEL", y)], data, by = "PANEL") } data[["y"]] <- data[[y]] From d254419765b6b42d15d5459b057fc7691acc96b9 Mon Sep 17 00:00:00 2001 From: dereckdemezquita Date: Mon, 10 Apr 2023 22:16:04 -0500 Subject: [PATCH 05/16] Simplified example data and corrected expected result in expect_error; will move code to test-ggplot-hline.R. --- .../test-geom-vline-hline-allow-none-1947.R | 87 ++++++++----------- 1 file changed, 37 insertions(+), 50 deletions(-) diff --git a/tests/testthat/test-geom-vline-hline-allow-none-1947.R b/tests/testthat/test-geom-vline-hline-allow-none-1947.R index ddb52dc1b9..1d4fa0cc44 100644 --- a/tests/testthat/test-geom-vline-hline-allow-none-1947.R +++ b/tests/testthat/test-geom-vline-hline-allow-none-1947.R @@ -1,77 +1,64 @@ test_that("geom_vline/geom_hline does not throw an error with ggplotly when no lines are found", { - # Prepare data - data <- data.table::data.table(gapminder::gapminder) - # Add year of interest for vertical lines - data[year == 2002, year_of_interest := "yoi"] + set.seed(123) + x <- seq(0, 10, by = 1) + # random walk + y <- cumsum(rnorm(length(x), mean = 0, sd = 1)) + df <- data.frame(x, y) + df$point_of_interest <- "not_poi" + df[df$x == 2, ]$point_of_interest <- "poi" # point of interest # Case 1: Vertical line by feeding data to it; this allows for programmatically setting many lines at different years - p1 <- ggplot2::ggplot(data, ggplot2::aes(x = year, y = lifeExp, colour = country)) + - ggplot2::geom_line() + + p1 <- ggplot2::ggplot(df) + + ggplot2::geom_line(ggplot2::aes(x = x, y = y)) + ggplot2::geom_vline( - ggplot2::aes(xintercept = year), - data = data[year_of_interest == "yoi", ], - colour = "yellow", - alpha = 0.75, - linewidth = 1.25, - linetype = "dashed" - ) + - ggplot2::theme(legend.position = "none") + ggplot2::aes(xintercept = x), + data = df[df$point_of_interest == "poi", ], + colour = "yellow" + ) # Test that ggplotly does not throw an error for both cases expect_error(plotly::ggplotly(p1), NA) # lines are found no error is thrown # Case 2: No lines are found, ggplot2 accepts it and no error is thrown - p2 <- ggplot2::ggplot(data, ggplot2::aes(x = year, y = lifeExp, colour = country)) + - ggplot2::geom_line() + + p2 <- ggplot2::ggplot(df) + + ggplot2::geom_line(ggplot2::aes(x = x, y = y)) + ggplot2::geom_vline( - ggplot2::aes(xintercept = year), - data = data[year_of_interest == "some_not_found", ], - colour = "yellow", - alpha = 0.75, - linewidth = 1.25, - linetype = "dashed" - ) + - ggplot2::theme(legend.position = "none") + ggplot2::aes(xintercept = x), + data = df[df$point_of_interest == "something_not_matched", ], + colour = "yellow" + ) - # error: + # error given without fix: # "Error in fix.by(by.y, y) : 'by' must specify a uniquely valid column" - expect_error(plotly::ggplotly(p2), "Error in fix.by") # no lines are found no error is thrown + expect_error(plotly::ggplotly(p2), NA) # no lines are found no error is thrown ## -------------------------------- # testing horizontal line - data[round(lifeExp, 0) == 50, val_of_interest := "voi"] + df$value_of_interest <- "not_voi" + df[round(df$x, 0) == 2, ]$value_of_interest <- "voi" # value of interest # horizontal line no error - p3 <- ggplot2::ggplot(data, ggplot2::aes(x = year, y = lifeExp, colour = country)) + - ggplot2::geom_line() + + p3 <- ggplot2::ggplot(df) + + ggplot2::geom_line(ggplot2::aes(x = x, y = y)) + ggplot2::geom_hline( - ggplot2::aes(yintercept = lifeExp), - data = data[val_of_interest == "voi", ], - colour = "pink", - alpha = 0.75, - linewidth = 1.25, - linetype = "dashed" - ) + - ggplot2::theme(legend.position = "none") + ggplot2::aes(yintercept = x), + data = df[df$value_of_interest == "voi", ], + colour = "pink" + ) expect_error(plotly::ggplotly(p3), NA) # lines are found no error is thrown # horizontal line not set; error - p4 <- ggplot2::ggplot(data, ggplot2::aes(x = year, y = lifeExp, colour = country)) + - ggplot2::geom_line() + + p4 <- ggplot2::ggplot(df) + + ggplot2::geom_line(ggplot2::aes(x = x, y = y)) + ggplot2::geom_hline( - ggplot2::aes(yintercept = lifeExp), - data = data[val_of_interest == "some_val_not_found", ], - colour = "pink", - alpha = 0.75, - linewidth = 1.25, - linetype = "dashed" - ) + - ggplot2::theme(legend.position = "none") + ggplot2::aes(yintercept = x), + data = df[df$value_of_interest == "something_not_matched", ], + colour = "pink" + ) - # ggplot2 allows this no error - # print(p4) + # error given without fix: # "Error in fix.by(by.y, y) : 'by' must specify a uniquely valid column" - expect_error(plotly::ggplotly(p4), "Error in fix.by") # no lines are found no error is thrown + expect_error(plotly::ggplotly(p4), NA) # no lines are found no error is thrown }) From 9ca4b74284baf2600c7b57bcb1be8027be491d8d Mon Sep 17 00:00:00 2001 From: dereckdemezquita Date: Mon, 10 Apr 2023 22:16:55 -0500 Subject: [PATCH 06/16] Tests with simplified data; did both cases succesful plot and what was previously failing. --- .../test-geom-vline-hline-allow-none-1947.R | 64 ------------------ tests/testthat/test-ggplot-hline.R | 65 +++++++++++++++++++ 2 files changed, 65 insertions(+), 64 deletions(-) delete mode 100644 tests/testthat/test-geom-vline-hline-allow-none-1947.R diff --git a/tests/testthat/test-geom-vline-hline-allow-none-1947.R b/tests/testthat/test-geom-vline-hline-allow-none-1947.R deleted file mode 100644 index 1d4fa0cc44..0000000000 --- a/tests/testthat/test-geom-vline-hline-allow-none-1947.R +++ /dev/null @@ -1,64 +0,0 @@ - -test_that("geom_vline/geom_hline does not throw an error with ggplotly when no lines are found", { - set.seed(123) - x <- seq(0, 10, by = 1) - # random walk - y <- cumsum(rnorm(length(x), mean = 0, sd = 1)) - df <- data.frame(x, y) - df$point_of_interest <- "not_poi" - df[df$x == 2, ]$point_of_interest <- "poi" # point of interest - - # Case 1: Vertical line by feeding data to it; this allows for programmatically setting many lines at different years - p1 <- ggplot2::ggplot(df) + - ggplot2::geom_line(ggplot2::aes(x = x, y = y)) + - ggplot2::geom_vline( - ggplot2::aes(xintercept = x), - data = df[df$point_of_interest == "poi", ], - colour = "yellow" - ) - - # Test that ggplotly does not throw an error for both cases - expect_error(plotly::ggplotly(p1), NA) # lines are found no error is thrown - - # Case 2: No lines are found, ggplot2 accepts it and no error is thrown - p2 <- ggplot2::ggplot(df) + - ggplot2::geom_line(ggplot2::aes(x = x, y = y)) + - ggplot2::geom_vline( - ggplot2::aes(xintercept = x), - data = df[df$point_of_interest == "something_not_matched", ], - colour = "yellow" - ) - - # error given without fix: - # "Error in fix.by(by.y, y) : 'by' must specify a uniquely valid column" - expect_error(plotly::ggplotly(p2), NA) # no lines are found no error is thrown - - ## -------------------------------- - # testing horizontal line - df$value_of_interest <- "not_voi" - df[round(df$x, 0) == 2, ]$value_of_interest <- "voi" # value of interest - - # horizontal line no error - p3 <- ggplot2::ggplot(df) + - ggplot2::geom_line(ggplot2::aes(x = x, y = y)) + - ggplot2::geom_hline( - ggplot2::aes(yintercept = x), - data = df[df$value_of_interest == "voi", ], - colour = "pink" - ) - - expect_error(plotly::ggplotly(p3), NA) # lines are found no error is thrown - - # horizontal line not set; error - p4 <- ggplot2::ggplot(df) + - ggplot2::geom_line(ggplot2::aes(x = x, y = y)) + - ggplot2::geom_hline( - ggplot2::aes(yintercept = x), - data = df[df$value_of_interest == "something_not_matched", ], - colour = "pink" - ) - - # error given without fix: - # "Error in fix.by(by.y, y) : 'by' must specify a uniquely valid column" - expect_error(plotly::ggplotly(p4), NA) # no lines are found no error is thrown -}) diff --git a/tests/testthat/test-ggplot-hline.R b/tests/testthat/test-ggplot-hline.R index 9ed7af92a6..4bf34290f2 100644 --- a/tests/testthat/test-ggplot-hline.R +++ b/tests/testthat/test-ggplot-hline.R @@ -97,3 +97,68 @@ test_that("hline works with coord_flip", { expect_equivalent(l$data[[2]]$x, c(5, 5)) expect_equivalent(l$data[[2]]$y, c(5.95, 6.05)) }) + +# fix for issue #1974 pull request #2252 +test_that("geom_vline/geom_hline does not throw an error with ggplotly when no lines are found", { + set.seed(123) + x <- seq(0, 10, by = 1) + # random walk + y <- cumsum(rnorm(length(x), mean = 0, sd = 1)) + df <- data.frame(x, y) + df$point_of_interest <- "not_poi" + df[df$x == 2, ]$point_of_interest <- "poi" # point of interest + + # Case 1: Vertical line by feeding data to it; this allows for programmatically setting many lines at different years + p1 <- ggplot2::ggplot(df) + + ggplot2::geom_line(ggplot2::aes(x = x, y = y)) + + ggplot2::geom_vline( + ggplot2::aes(xintercept = x), + data = df[df$point_of_interest == "poi", ], + colour = "yellow" + ) + + # Test that ggplotly does not throw an error for both cases + expect_error(plotly::ggplotly(p1), NA) # lines are found no error is thrown + + # Case 2: No lines are found, ggplot2 accepts it and no error is thrown + p2 <- ggplot2::ggplot(df) + + ggplot2::geom_line(ggplot2::aes(x = x, y = y)) + + ggplot2::geom_vline( + ggplot2::aes(xintercept = x), + data = df[df$point_of_interest == "something_not_matched", ], + colour = "yellow" + ) + + # error given without fix: + # "Error in fix.by(by.y, y) : 'by' must specify a uniquely valid column" + expect_error(plotly::ggplotly(p2), NA) # no lines are found no error is thrown + + ## -------------------------------- + # testing horizontal line + df$value_of_interest <- "not_voi" + df[round(df$x, 0) == 2, ]$value_of_interest <- "voi" # value of interest + + # horizontal line no error + p3 <- ggplot2::ggplot(df) + + ggplot2::geom_line(ggplot2::aes(x = x, y = y)) + + ggplot2::geom_hline( + ggplot2::aes(yintercept = x), + data = df[df$value_of_interest == "voi", ], + colour = "pink" + ) + + expect_error(plotly::ggplotly(p3), NA) # lines are found no error is thrown + + # horizontal line not set; error + p4 <- ggplot2::ggplot(df) + + ggplot2::geom_line(ggplot2::aes(x = x, y = y)) + + ggplot2::geom_hline( + ggplot2::aes(yintercept = x), + data = df[df$value_of_interest == "something_not_matched", ], + colour = "pink" + ) + + # error given without fix: + # "Error in fix.by(by.y, y) : 'by' must specify a uniquely valid column" + expect_error(plotly::ggplotly(p4), NA) # no lines are found no error is thrown +}) From 28bbbc4ee7879d392684b3c48b8de0c8991fac16 Mon Sep 17 00:00:00 2001 From: dereckdemezquita Date: Sat, 15 Apr 2023 08:58:08 -0500 Subject: [PATCH 07/16] Separated tests into respective files; horizontal/vertical. --- tests/testthat/test-ggplot-hline.R | 30 ------------------------ tests/testthat/test-ggplot-vline.R | 37 ++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 30 deletions(-) diff --git a/tests/testthat/test-ggplot-hline.R b/tests/testthat/test-ggplot-hline.R index 4bf34290f2..6a57c301d8 100644 --- a/tests/testthat/test-ggplot-hline.R +++ b/tests/testthat/test-ggplot-hline.R @@ -105,36 +105,6 @@ test_that("geom_vline/geom_hline does not throw an error with ggplotly when no l # random walk y <- cumsum(rnorm(length(x), mean = 0, sd = 1)) df <- data.frame(x, y) - df$point_of_interest <- "not_poi" - df[df$x == 2, ]$point_of_interest <- "poi" # point of interest - - # Case 1: Vertical line by feeding data to it; this allows for programmatically setting many lines at different years - p1 <- ggplot2::ggplot(df) + - ggplot2::geom_line(ggplot2::aes(x = x, y = y)) + - ggplot2::geom_vline( - ggplot2::aes(xintercept = x), - data = df[df$point_of_interest == "poi", ], - colour = "yellow" - ) - - # Test that ggplotly does not throw an error for both cases - expect_error(plotly::ggplotly(p1), NA) # lines are found no error is thrown - - # Case 2: No lines are found, ggplot2 accepts it and no error is thrown - p2 <- ggplot2::ggplot(df) + - ggplot2::geom_line(ggplot2::aes(x = x, y = y)) + - ggplot2::geom_vline( - ggplot2::aes(xintercept = x), - data = df[df$point_of_interest == "something_not_matched", ], - colour = "yellow" - ) - - # error given without fix: - # "Error in fix.by(by.y, y) : 'by' must specify a uniquely valid column" - expect_error(plotly::ggplotly(p2), NA) # no lines are found no error is thrown - - ## -------------------------------- - # testing horizontal line df$value_of_interest <- "not_voi" df[round(df$x, 0) == 2, ]$value_of_interest <- "voi" # value of interest diff --git a/tests/testthat/test-ggplot-vline.R b/tests/testthat/test-ggplot-vline.R index ceda7e1dfa..406b957956 100644 --- a/tests/testthat/test-ggplot-vline.R +++ b/tests/testthat/test-ggplot-vline.R @@ -46,3 +46,40 @@ test_that("vline works with coord_flip", { expect_equivalent(l$data[[2]]$x, c(5.95, 6.05)) expect_equivalent(l$data[[2]]$y, c(5, 5)) }) + + +# fix for issue #1974 pull request #2252 +test_that("geom_vline/geom_hline does not throw an error with ggplotly when no lines are found", { + set.seed(123) + x <- seq(0, 10, by = 1) + # random walk + y <- cumsum(rnorm(length(x), mean = 0, sd = 1)) + df <- data.frame(x, y) + df$point_of_interest <- "not_poi" + df[df$x == 2, ]$point_of_interest <- "poi" # point of interest + + # Case 1: Vertical line by feeding data to it; this allows for programmatically setting many lines at different years + p1 <- ggplot2::ggplot(df) + + ggplot2::geom_line(ggplot2::aes(x = x, y = y)) + + ggplot2::geom_vline( + ggplot2::aes(xintercept = x), + data = df[df$point_of_interest == "poi", ], + colour = "yellow" + ) + + # Test that ggplotly does not throw an error for both cases + expect_error(plotly::ggplotly(p1), NA) # lines are found no error is thrown + + # Case 2: No lines are found, ggplot2 accepts it and no error is thrown + p2 <- ggplot2::ggplot(df) + + ggplot2::geom_line(ggplot2::aes(x = x, y = y)) + + ggplot2::geom_vline( + ggplot2::aes(xintercept = x), + data = df[df$point_of_interest == "something_not_matched", ], + colour = "yellow" + ) + + # error given without fix: + # "Error in fix.by(by.y, y) : 'by' must specify a uniquely valid column" + expect_error(plotly::ggplotly(p2), NA) # no lines are found no error is thrown +}) From 4be8e7f5d3f2e1cc425489a30bc5880885645db7 Mon Sep 17 00:00:00 2001 From: Dereck Mezquita <44912288+dereckdemezquita@users.noreply.github.com> Date: Sat, 3 Jun 2023 09:35:07 -0500 Subject: [PATCH 08/16] Seed for reproducibility. Co-authored-by: Carson Sievert --- tests/testthat/test-ggplot-vline.R | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/testthat/test-ggplot-vline.R b/tests/testthat/test-ggplot-vline.R index 406b957956..1685aca9af 100644 --- a/tests/testthat/test-ggplot-vline.R +++ b/tests/testthat/test-ggplot-vline.R @@ -50,7 +50,6 @@ test_that("vline works with coord_flip", { # fix for issue #1974 pull request #2252 test_that("geom_vline/geom_hline does not throw an error with ggplotly when no lines are found", { - set.seed(123) x <- seq(0, 10, by = 1) # random walk y <- cumsum(rnorm(length(x), mean = 0, sd = 1)) From bbf07fe8152bb231a8600953e4198dd3bcbd30e9 Mon Sep 17 00:00:00 2001 From: Dereck Mezquita <44912288+dereckdemezquita@users.noreply.github.com> Date: Sat, 3 Jun 2023 09:35:16 -0500 Subject: [PATCH 09/16] Seed for reproducibility. Co-authored-by: Carson Sievert --- tests/testthat/test-ggplot-hline.R | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/testthat/test-ggplot-hline.R b/tests/testthat/test-ggplot-hline.R index 6a57c301d8..147a1bc928 100644 --- a/tests/testthat/test-ggplot-hline.R +++ b/tests/testthat/test-ggplot-hline.R @@ -100,7 +100,6 @@ test_that("hline works with coord_flip", { # fix for issue #1974 pull request #2252 test_that("geom_vline/geom_hline does not throw an error with ggplotly when no lines are found", { - set.seed(123) x <- seq(0, 10, by = 1) # random walk y <- cumsum(rnorm(length(x), mean = 0, sd = 1)) From 333d311d3b22d638c6d030c2edcde737abc3ba84 Mon Sep 17 00:00:00 2001 From: Dereck Mezquita <44912288+dereckdemezquita@users.noreply.github.com> Date: Sat, 3 Jun 2023 09:55:17 -0500 Subject: [PATCH 10/16] Simplify tests. Co-authored-by: Carson Sievert --- tests/testthat/test-ggplot-hline.R | 33 ++---------------------------- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/tests/testthat/test-ggplot-hline.R b/tests/testthat/test-ggplot-hline.R index 147a1bc928..ba41144e50 100644 --- a/tests/testthat/test-ggplot-hline.R +++ b/tests/testthat/test-ggplot-hline.R @@ -98,36 +98,7 @@ test_that("hline works with coord_flip", { expect_equivalent(l$data[[2]]$y, c(5.95, 6.05)) }) -# fix for issue #1974 pull request #2252 test_that("geom_vline/geom_hline does not throw an error with ggplotly when no lines are found", { - x <- seq(0, 10, by = 1) - # random walk - y <- cumsum(rnorm(length(x), mean = 0, sd = 1)) - df <- data.frame(x, y) - df$value_of_interest <- "not_voi" - df[round(df$x, 0) == 2, ]$value_of_interest <- "voi" # value of interest - - # horizontal line no error - p3 <- ggplot2::ggplot(df) + - ggplot2::geom_line(ggplot2::aes(x = x, y = y)) + - ggplot2::geom_hline( - ggplot2::aes(yintercept = x), - data = df[df$value_of_interest == "voi", ], - colour = "pink" - ) - - expect_error(plotly::ggplotly(p3), NA) # lines are found no error is thrown - - # horizontal line not set; error - p4 <- ggplot2::ggplot(df) + - ggplot2::geom_line(ggplot2::aes(x = x, y = y)) + - ggplot2::geom_hline( - ggplot2::aes(yintercept = x), - data = df[df$value_of_interest == "something_not_matched", ], - colour = "pink" - ) - - # error given without fix: - # "Error in fix.by(by.y, y) : 'by' must specify a uniquely valid column" - expect_error(plotly::ggplotly(p4), NA) # no lines are found no error is thrown + p3 <- ggplot(df) + geom_hline(aes(yintercept = x), data = data.frame(x = 1)[F, , drop = FALSE]) + expect_error(plotly::ggplotly(p3), NA) }) From 5bb68a904166f8d0769de71415f27900654692af Mon Sep 17 00:00:00 2001 From: dereckdemezquita Date: Sat, 3 Jun 2023 10:03:06 -0500 Subject: [PATCH 11/16] Simplified test. --- tests/testthat/test-ggplot-vline.R | 35 ++---------------------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/tests/testthat/test-ggplot-vline.R b/tests/testthat/test-ggplot-vline.R index 1685aca9af..0829974f1f 100644 --- a/tests/testthat/test-ggplot-vline.R +++ b/tests/testthat/test-ggplot-vline.R @@ -47,38 +47,7 @@ test_that("vline works with coord_flip", { expect_equivalent(l$data[[2]]$y, c(5, 5)) }) - -# fix for issue #1974 pull request #2252 test_that("geom_vline/geom_hline does not throw an error with ggplotly when no lines are found", { - x <- seq(0, 10, by = 1) - # random walk - y <- cumsum(rnorm(length(x), mean = 0, sd = 1)) - df <- data.frame(x, y) - df$point_of_interest <- "not_poi" - df[df$x == 2, ]$point_of_interest <- "poi" # point of interest - - # Case 1: Vertical line by feeding data to it; this allows for programmatically setting many lines at different years - p1 <- ggplot2::ggplot(df) + - ggplot2::geom_line(ggplot2::aes(x = x, y = y)) + - ggplot2::geom_vline( - ggplot2::aes(xintercept = x), - data = df[df$point_of_interest == "poi", ], - colour = "yellow" - ) - - # Test that ggplotly does not throw an error for both cases - expect_error(plotly::ggplotly(p1), NA) # lines are found no error is thrown - - # Case 2: No lines are found, ggplot2 accepts it and no error is thrown - p2 <- ggplot2::ggplot(df) + - ggplot2::geom_line(ggplot2::aes(x = x, y = y)) + - ggplot2::geom_vline( - ggplot2::aes(xintercept = x), - data = df[df$point_of_interest == "something_not_matched", ], - colour = "yellow" - ) - - # error given without fix: - # "Error in fix.by(by.y, y) : 'by' must specify a uniquely valid column" - expect_error(plotly::ggplotly(p2), NA) # no lines are found no error is thrown + p <- ggplot(df) + geom_vline(aes(xintercept = x), data = data.frame(x = 1)[F, , drop = FALSE]) + expect_error(plotly::ggplotly(p), NA) }) From ca4ccd58e4b8d0cfc65dff62bc5d64da27181d80 Mon Sep 17 00:00:00 2001 From: Dereck Mezquita <44912288+dereckdemezquita@users.noreply.github.com> Date: Sat, 3 Jun 2023 10:08:01 -0500 Subject: [PATCH 12/16] Unnecessary comment. Co-authored-by: Carson Sievert --- R/layers2traces.R | 1 - 1 file changed, 1 deletion(-) diff --git a/R/layers2traces.R b/R/layers2traces.R index 2a7c7dd4a4..7757f94319 100644 --- a/R/layers2traces.R +++ b/R/layers2traces.R @@ -464,7 +464,6 @@ to_basic.GeomVline <- function(data, prestats_data, layout, params, p, ...) { data = layout$layout, cols = paste0(y, c("_min", "_max")), values_to = y, names_to = "variable" ) lay <- as.data.frame(lay) - # fix for #1947; applied to Hline as well if (nrow(data) > 0) { data <- merge(lay[c("PANEL", y)], data, by = "PANEL") } From 49dda5c773ad965cc4d97bb55d07b59354aa2b2b Mon Sep 17 00:00:00 2001 From: dereckdemezquita Date: Sat, 3 Jun 2023 10:14:33 -0500 Subject: [PATCH 13/16] vline/hline empty df news fix. --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index 0468fe30be..9fb4dbaae8 100644 --- a/NEWS.md +++ b/NEWS.md @@ -12,6 +12,7 @@ * Closed #2208: `ggplotly()` no longer errors given a `geom_area()` with 1 or less data points (error introduced by new behavior in ggplot2 v3.4.0). (#2209) * Closed #2220: `ggplotly()` no longer errors on `stat_summary(geom = "crossbar")`. (#2222) * Closed #2212: `ggplotly()` no longer removes legends when setting guide properties via `guides(aes = guide_xxx(...))`. +* Closed #1947: `ggplotly()` now correctly handles `geom_vline` with empty data. Previously, if `geom_vline` was passed an empty data frame, it would result in an error. The plot is drawn even if no lines are found; this is the same behaviour as `ggplot2`. (#1947) # 4.10.1 From 19a65ea5502d22f199fd0c1c62087af6272975bf Mon Sep 17 00:00:00 2001 From: dereckdemezquita Date: Sat, 3 Jun 2023 10:15:46 -0500 Subject: [PATCH 14/16] Issue closes both functione errors. --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 9fb4dbaae8..0e0d844031 100644 --- a/NEWS.md +++ b/NEWS.md @@ -12,7 +12,7 @@ * Closed #2208: `ggplotly()` no longer errors given a `geom_area()` with 1 or less data points (error introduced by new behavior in ggplot2 v3.4.0). (#2209) * Closed #2220: `ggplotly()` no longer errors on `stat_summary(geom = "crossbar")`. (#2222) * Closed #2212: `ggplotly()` no longer removes legends when setting guide properties via `guides(aes = guide_xxx(...))`. -* Closed #1947: `ggplotly()` now correctly handles `geom_vline` with empty data. Previously, if `geom_vline` was passed an empty data frame, it would result in an error. The plot is drawn even if no lines are found; this is the same behaviour as `ggplot2`. (#1947) +* Closed #1947: `ggplotly()` now correctly handles `geom_vline`/`geom_hline` with empty data. Previously, if `geom_vline`/`geom_hline` was passed an empty data frame, it would result in an error. The plot is drawn even if no lines are found; this is the same behaviour as `ggplot2`. (#1947) # 4.10.1 From 95cbcbd2ef719d64ec4236c911bd97d59d974635 Mon Sep 17 00:00:00 2001 From: dereckdemezquita Date: Sat, 3 Jun 2023 10:17:01 -0500 Subject: [PATCH 15/16] American English! --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 0e0d844031..9236172314 100644 --- a/NEWS.md +++ b/NEWS.md @@ -12,7 +12,7 @@ * Closed #2208: `ggplotly()` no longer errors given a `geom_area()` with 1 or less data points (error introduced by new behavior in ggplot2 v3.4.0). (#2209) * Closed #2220: `ggplotly()` no longer errors on `stat_summary(geom = "crossbar")`. (#2222) * Closed #2212: `ggplotly()` no longer removes legends when setting guide properties via `guides(aes = guide_xxx(...))`. -* Closed #1947: `ggplotly()` now correctly handles `geom_vline`/`geom_hline` with empty data. Previously, if `geom_vline`/`geom_hline` was passed an empty data frame, it would result in an error. The plot is drawn even if no lines are found; this is the same behaviour as `ggplot2`. (#1947) +* Closed #1947: `ggplotly()` now correctly handles `geom_vline`/`geom_hline` with empty data. Previously, if `geom_vline`/`geom_hline` was passed an empty data frame, it would result in an error. The plot is drawn even if no lines are found; this is the same behavior as `ggplot2`. (#1947) # 4.10.1 From 76b5b387a221a215d38a9330615fe096c61c0712 Mon Sep 17 00:00:00 2001 From: dereckdemezquita Date: Sat, 3 Jun 2023 10:17:36 -0500 Subject: [PATCH 16/16] Don't need number at the ned. --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 9236172314..4e0cfd14f2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -12,7 +12,7 @@ * Closed #2208: `ggplotly()` no longer errors given a `geom_area()` with 1 or less data points (error introduced by new behavior in ggplot2 v3.4.0). (#2209) * Closed #2220: `ggplotly()` no longer errors on `stat_summary(geom = "crossbar")`. (#2222) * Closed #2212: `ggplotly()` no longer removes legends when setting guide properties via `guides(aes = guide_xxx(...))`. -* Closed #1947: `ggplotly()` now correctly handles `geom_vline`/`geom_hline` with empty data. Previously, if `geom_vline`/`geom_hline` was passed an empty data frame, it would result in an error. The plot is drawn even if no lines are found; this is the same behavior as `ggplot2`. (#1947) +* Closed #1947: `ggplotly()` now correctly handles `geom_vline`/`geom_hline` with empty data. Previously, if `geom_vline`/`geom_hline` was passed an empty data frame, it would result in an error. The plot is drawn even if no lines are found; this is the same behavior as `ggplot2`. # 4.10.1