From 88e87f06b51cc1bf2ebf5e8bb26dfcf90042de72 Mon Sep 17 00:00:00 2001 From: NandaniAggarwal Date: Sun, 8 Mar 2026 21:18:08 +0530 Subject: [PATCH 1/7] Removed geom_dotplot and replace with error --- NEWS.md | 4 ++++ R/geom-dotplot.r | 1 + tests/testthat/test-renderer1-dotplot.R | 32 +++++++++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 tests/testthat/test-renderer1-dotplot.R diff --git a/NEWS.md b/NEWS.md index ec55e63d8..3c3fe9029 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,7 @@ +# Changes in version 2026.3.8 (PR#311) + +- `geom_dotplot()` is now deprecated and will show a warning. Use `geom_point()` instead for interactive visualizations. (Fixed #289) + # Changes in version 2025.12.3 (PR#282) - URL hash handling: Removed old `window.location.hash` parsing code from `animint.js` (issue #280). diff --git a/R/geom-dotplot.r b/R/geom-dotplot.r index 79bf00a6a..2daf2aa32 100644 --- a/R/geom-dotplot.r +++ b/R/geom-dotplot.r @@ -130,6 +130,7 @@ geom_dotplot <- function(mapping = NULL, data = NULL, na.rm = FALSE, show.legend = NA, inherit.aes = TRUE) { + stop("geom_dotplot() has been removed from animint2. Use geom_point() instead.") # If identical(position, "stack") or position is position_stack(), tell them # to use stackgroups=TRUE instead. Need to use identical() instead of ==, # because == will fail if object is position_stack() or position_dodge() diff --git a/tests/testthat/test-renderer1-dotplot.R b/tests/testthat/test-renderer1-dotplot.R new file mode 100644 index 000000000..fae7e7f9c --- /dev/null +++ b/tests/testthat/test-renderer1-dotplot.R @@ -0,0 +1,32 @@ +library(testthat) +library(animint2) + +test_that("geom_dotplot shows error", { + expect_error( + geom_dotplot(), + "geom_point" + ) +}) + +test_that("geom_point creates a plot object", { + df <- data.frame(x = "A", y = c(1, 1.1, 1.2, 1.3, 100, 200)) + p <- ggplot() + geom_point(aes(x, y), data = df) + + expect_true(is.ggplot(p)) +}) + +test_that("geom_point produces no warnings", { + df <- data.frame(x = "A", y = c(1, 1.1, 1.2, 1.3, 100, 200)) + + expect_no_warning( + ggplot() + geom_point(aes(x, y), data = df) + ) +}) + +test_that("geom_point produces no errors", { + df <- data.frame(x = "A", y = c(1, 1.1, 1.2, 1.3, 100, 200)) + + expect_no_error( + ggplot() + geom_point(aes(x, y), data = df) + ) +}) \ No newline at end of file From 522f71d68da05e06aca095f4601ffe944383a9e2 Mon Sep 17 00:00:00 2001 From: NandaniAggarwal Date: Sun, 8 Mar 2026 23:33:03 +0530 Subject: [PATCH 2/7] updated some files to pass the CI check --- NAMESPACE | 1 - R/geom-dotplot.r | 290 +------------------ man/animint2-gganimintproto.Rd | 3 +- man/checkSelectorNames.Rd | 17 ++ man/geom_dotplot.Rd | 196 +------------ tests/testthat/test-compiler-dotplot.r | 92 ++---- tests/testthat/test-compiler-function-args.r | 2 +- 7 files changed, 60 insertions(+), 541 deletions(-) create mode 100644 man/checkSelectorNames.Rd diff --git a/NAMESPACE b/NAMESPACE index 72f51e800..8f94a3988 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -140,7 +140,6 @@ export(GeomCurve) export(GeomCustomAnn) export(GeomDensity) export(GeomDensity2d) -export(GeomDotplot) export(GeomErrorbar) export(GeomErrorbarh) export(GeomFreqpoly) diff --git a/R/geom-dotplot.r b/R/geom-dotplot.r index 2daf2aa32..7e61f7642 100644 --- a/R/geom-dotplot.r +++ b/R/geom-dotplot.r @@ -1,286 +1,14 @@ -#' Dot plot +#' Dot plot (removed) #' -#' In a dot plot, the width of a dot corresponds to the bin width -#' (or maximum width, depending on the binning algorithm), and dots are -#' stacked, with each dot representing one observation. +#' @description +#' `geom_dotplot()` has been removed from animint2 due to fundamental issues +#' with interactive rendering. Please use `geom_point()` instead. #' -#' With dot-density binning, the bin positions are determined by the data and -#' \code{binwidth}, which is the maximum width of each bin. See Wilkinson -#' (1999) for details on the dot-density binning algorithm. -#' -#' With histodot binning, the bins have fixed positions and fixed widths, much -#' like a histogram. -#' -#' When binning along the x axis and stacking along the y axis, the numbers on -#' y axis are not meaningful, due to technical limitations of ggplot2. You can -#' hide the y axis, as in one of the examples, or manually scale it -#' to match the number of dots. -#' -#' @section Aesthetics: -#' \Sexpr[results=rd,stage=build]{animint2:::rd_aesthetics("geom", "dotplot")} -#' -#' @inheritParams layer -#' @inheritParams geom_point -#' @param stackdir which direction to stack the dots. "up" (default), -#' "down", "center", "centerwhole" (centered, but with dots aligned) -#' @param stackratio how close to stack the dots. Default is 1, where dots just -#' just touch. Use smaller values for closer, overlapping dots. -#' @param dotsize The diameter of the dots relative to \code{binwidth}, default 1. -#' @param stackgroups should dots be stacked across groups? This has the effect -#' that \code{position = "stack"} should have, but can't (because this geom has -#' some odd properties). -#' @param binaxis The axis to bin along, "x" (default) or "y" -#' @param method "dotdensity" (default) for dot-density binning, or -#' "histodot" for fixed bin widths (like stat_bin) -#' @param binwidth When \code{method} is "dotdensity", this specifies maximum bin -#' width. When \code{method} is "histodot", this specifies bin width. -#' Defaults to 1/30 of the range of the data -#' @param binpositions When \code{method} is "dotdensity", "bygroup" (default) -#' determines positions of the bins for each group separately. "all" determines -#' positions of the bins with all the data taken together; this is used for -#' aligning dot stacks across multiple groups. -#' @param origin When \code{method} is "histodot", origin of first bin -#' @param right When \code{method} is "histodot", should intervals be closed -#' on the right (a, b], or not [a, b) -#' @param width When \code{binaxis} is "y", the spacing of the dot stacks -#' for dodging. -#' @param drop If TRUE, remove all bins with zero counts -#' @section Computed variables: -#' \describe{ -#' \item{x}{center of each bin, if binaxis is "x"} -#' \item{y}{center of each bin, if binaxis is "x"} -#' \item{binwidth}{max width of each bin if method is "dotdensity"; -#' width of each bin if method is "histodot"} -#' \item{count}{number of points in bin} -#' \item{ncount}{count, scaled to maximum of 1} -#' \item{density}{density of points in bin, scaled to integrate to 1, -#' if method is "histodot"} -#' \item{ndensity}{density, scaled to maximum of 1, if method is "histodot"} -#' } #' @export -#' @references Wilkinson, L. (1999) Dot plots. The American Statistician, -#' 53(3), 276-281. -#' @examples -#' ggplot(mtcars, aes(x = mpg)) + geom_dotplot() -#' ggplot(mtcars, aes(x = mpg)) + geom_dotplot(binwidth = 1.5) -#' -#' # Use fixed-width bins -#' ggplot(mtcars, aes(x = mpg)) + -#' geom_dotplot(method="histodot", binwidth = 1.5) -#' -#' # Some other stacking methods -#' ggplot(mtcars, aes(x = mpg)) + -#' geom_dotplot(binwidth = 1.5, stackdir = "center") -#' ggplot(mtcars, aes(x = mpg)) + -#' geom_dotplot(binwidth = 1.5, stackdir = "centerwhole") -#' -#' # y axis isn't really meaningful, so hide it -#' ggplot(mtcars, aes(x = mpg)) + geom_dotplot(binwidth = 1.5) + -#' scale_y_continuous(NULL, breaks = NULL) -#' -#' # Overlap dots vertically -#' ggplot(mtcars, aes(x = mpg)) + geom_dotplot(binwidth = 1.5, stackratio = .7) -#' -#' # Expand dot diameter -#' ggplot(mtcars, aes(x = mpg)) + geom_dotplot(binwidth = 1.5, dotsize = 1.25) -#' -#' \donttest{ -#' # Examples with stacking along y axis instead of x -#' ggplot(mtcars, aes(x = 1, y = mpg)) + -#' geom_dotplot(binaxis = "y", stackdir = "center") -#' -#' ggplot(mtcars, aes(x = factor(cyl), y = mpg)) + -#' geom_dotplot(binaxis = "y", stackdir = "center") -#' -#' ggplot(mtcars, aes(x = factor(cyl), y = mpg)) + -#' geom_dotplot(binaxis = "y", stackdir = "centerwhole") -#' -#' ggplot(mtcars, aes(x = factor(vs), fill = factor(cyl), y = mpg)) + -#' geom_dotplot(binaxis = "y", stackdir = "center", position = "dodge") -#' -#' # binpositions="all" ensures that the bins are aligned between groups -#' ggplot(mtcars, aes(x = factor(am), y = mpg)) + -#' geom_dotplot(binaxis = "y", stackdir = "center", binpositions="all") -#' -#' # Stacking multiple groups, with different fill -#' ggplot(mtcars, aes(x = mpg, fill = factor(cyl))) + -#' geom_dotplot(stackgroups = TRUE, binwidth = 1, binpositions = "all") -#' -#' ggplot(mtcars, aes(x = mpg, fill = factor(cyl))) + -#' geom_dotplot(stackgroups = TRUE, binwidth = 1, method = "histodot") -#' -#' ggplot(mtcars, aes(x = 1, y = mpg, fill = factor(cyl))) + -#' geom_dotplot(binaxis = "y", stackgroups = TRUE, binwidth = 1, method = "histodot") -#' } -geom_dotplot <- function(mapping = NULL, data = NULL, - position = "identity", - ..., - binwidth = NULL, - binaxis = "x", - method = "dotdensity", - binpositions = "bygroup", - stackdir = "up", - stackratio = 1, - dotsize = 1, - stackgroups = FALSE, - origin = NULL, - right = TRUE, - width = 0.9, - drop = FALSE, - na.rm = FALSE, - show.legend = NA, - inherit.aes = TRUE) { - stop("geom_dotplot() has been removed from animint2. Use geom_point() instead.") - # If identical(position, "stack") or position is position_stack(), tell them - # to use stackgroups=TRUE instead. Need to use identical() instead of ==, - # because == will fail if object is position_stack() or position_dodge() - if (!is.null(position) && - (identical(position, "stack") || (inherits(position, "PositionStack")))) - message("position=\"stack\" doesn't work properly with geom_dotplot. Use stackgroups=TRUE instead.") - - if (stackgroups && method == "dotdensity" && binpositions == "bygroup") - message('geom_dotplot called with stackgroups=TRUE and method="dotdensity". You probably want to set binpositions="all"') - - layer( - data = data, - mapping = mapping, - stat = StatBindot, - geom = GeomDotplot, - position = position, - show.legend = show.legend, - inherit.aes = inherit.aes, - # Need to make sure that the binaxis goes to both the stat and the geom - params = list( - binaxis = binaxis, - binwidth = binwidth, - binpositions = binpositions, - method = method, - origin = origin, - right = right, - width = width, - drop = drop, - stackdir = stackdir, - stackratio = stackratio, - dotsize = dotsize, - stackgroups = stackgroups, - na.rm = na.rm, - ... - ) +#' @keywords internal +geom_dotplot <- function(...) { + stop( + "geom_dotplot() has been removed from animint2. Use geom_point() instead.\n", + "See issue #289 for details: https://github.com/animint/animint2/issues/289" ) } - -#' @rdname animint2-gganimintproto -#' @format NULL -#' @usage NULL -#' @export -GeomDotplot <- gganimintproto("GeomDotplot", Geom, - required_aes = c("x", "y"), - non_missing_aes = c("size", "shape"), - - default_aes = aes(colour = "black", fill = "black", alpha = NA), - - setup_data = function(data, params) { - data$width <- data$width %||% - params$width %||% (resolution(data$x, FALSE) * 0.9) - - # Set up the stacking function and range - if (is.null(params$stackdir) || params$stackdir == "up") { - stackdots <- function(a) a - .5 - stackaxismin <- 0 - stackaxismax <- 1 - } else if (params$stackdir == "down") { - stackdots <- function(a) -a + .5 - stackaxismin <- -1 - stackaxismax <- 0 - } else if (params$stackdir == "center") { - stackdots <- function(a) a - 1 - max(a - 1) / 2 - stackaxismin <- -.5 - stackaxismax <- .5 - } else if (params$stackdir == "centerwhole") { - stackdots <- function(a) a - 1 - floor(max(a - 1) / 2) - stackaxismin <- -.5 - stackaxismax <- .5 - } - - - # Fill the bins: at a given x (or y), if count=3, make 3 entries at that x - data <- data[rep(1:nrow(data), data$count), ] - - # Next part will set the position of each dot within each stack - # If stackgroups=TRUE, split only on x (or y) and panel; if not stacking, also split by group - plyvars <- params$binaxis %||% "x" - plyvars <- c(plyvars, "PANEL") - if (is.null(params$stackgroups) || !params$stackgroups) - plyvars <- c(plyvars, "group") - - # Within each x, or x+group, set countidx=1,2,3, and set stackpos according to stack function - data <- plyr::ddply(data, plyvars, function(xx) { - xx$countidx <- 1:nrow(xx) - xx$stackpos <- stackdots(xx$countidx) - xx - }) - - - # Set the bounding boxes for the dots - if (is.null(params$binaxis) || params$binaxis == "x") { - # ymin, ymax, xmin, and xmax define the bounding rectangle for each stack - # Can't do bounding box per dot, because y position isn't real. - # After position code is rewritten, each dot should have its own bounding box. - data$xmin <- data$x - data$binwidth / 2 - data$xmax <- data$x + data$binwidth / 2 - data$ymin <- stackaxismin - data$ymax <- stackaxismax - data$y <- 0 - - } else if (params$binaxis == "y") { - # ymin, ymax, xmin, and xmax define the bounding rectangle for each stack - # Can't do bounding box per dot, because x position isn't real. - # xmin and xmax aren't really the x bounds, because of the odd way the grob - # works. They're just set to the standard x +- width/2 so that dot clusters - # can be dodged like other geoms. - # After position code is rewritten, each dot should have its own bounding box. - data <- plyr::ddply(data, "group", transform, - ymin = min(y) - binwidth[1] / 2, - ymax = max(y) + binwidth[1] / 2) - - data$xmin <- data$x + data$width * stackaxismin - data$xmax <- data$x + data$width * stackaxismax - # Unlike with y above, don't change x because it will cause problems with dodging - } - data - }, - - - draw_group = function(data, panel_scales, coord, na.rm = FALSE, - binaxis = "x", stackdir = "up", stackratio = 1, - dotsize = 1, stackgroups = FALSE) { - if (!coord$is_linear()) { - warning("geom_dotplot does not work properly with non-linear coordinates.") - } - - tdata <- coord$transform(data, panel_scales) - - # Swap axes if using coord_flip - if (inherits(coord, "CoordFlip")) - binaxis <- ifelse(binaxis == "x", "y", "x") - - if (binaxis == "x") { - stackaxis = "y" - dotdianpc <- dotsize * tdata$binwidth[1] / (max(panel_scales$x.range) - min(panel_scales$x.range)) - - } else if (binaxis == "y") { - stackaxis = "x" - dotdianpc <- dotsize * tdata$binwidth[1] / (max(panel_scales$y.range) - min(panel_scales$y.range)) - } - - ggname("geom_dotplot", - dotstackGrob(stackaxis = stackaxis, x = tdata$x, y = tdata$y, dotdia = dotdianpc, - stackposition = tdata$stackpos, stackratio = stackratio, - default.units = "npc", - gp = gpar(col = alpha(tdata$colour, tdata$alpha), - fill = alpha(tdata$fill, tdata$alpha))) - ) - }, - - draw_key = draw_key_dotplot -) diff --git a/man/animint2-gganimintproto.Rd b/man/animint2-gganimintproto.Rd index 98118db09..0ea2620f0 100644 --- a/man/animint2-gganimintproto.Rd +++ b/man/animint2-gganimintproto.Rd @@ -6,7 +6,7 @@ % R/stat-.r, R/geom-abline.r, R/geom-rect.r, R/geom-bar.r, R/geom-bin2d.r, % R/geom-blank.r, R/geom-path.r, R/geom-contour.r, R/geom-crossbar.r, % R/geom-segment.r, R/geom-curve.r, R/geom-ribbon.r, R/geom-density.r, -% R/geom-density2d.r, R/geom-dotplot.r, R/geom-errorbar.r, R/geom-errorbarh.r, +% R/geom-density2d.r, R/geom-errorbar.r, R/geom-errorbarh.r, % R/geom-freqpoly.r, R/geom-hex.r, R/geom-hline.r, R/geom-label-aligned.R, % R/geom-label.R, R/geom-linerange.r, R/geom-point.r, R/geom-pointrange.r, % R/geom-rug.r, R/geom-smooth.r, R/geom-spoke.r, R/geom-text.r, @@ -55,7 +55,6 @@ \alias{GeomArea} \alias{GeomDensity} \alias{GeomDensity2d} -\alias{GeomDotplot} \alias{GeomErrorbar} \alias{GeomErrorbarh} \alias{GeomFreqpoly} diff --git a/man/checkSelectorNames.Rd b/man/checkSelectorNames.Rd new file mode 100644 index 000000000..c8ffe6875 --- /dev/null +++ b/man/checkSelectorNames.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/z_animintHelpers.R +\name{checkSelectorNames} +\alias{checkSelectorNames} +\title{Validate selector names for CSS compatibility} +\usage{ +checkSelectorNames(selectors) +} +\arguments{ +\item{selectors}{selectors to validate} +} +\value{ +\code{NULL}. Throws error if invalid characters found. +} +\description{ +Validate selector names for CSS compatibility +} diff --git a/man/geom_dotplot.Rd b/man/geom_dotplot.Rd index 0949f5666..31bc950d0 100644 --- a/man/geom_dotplot.Rd +++ b/man/geom_dotplot.Rd @@ -2,198 +2,12 @@ % Please edit documentation in R/geom-dotplot.r \name{geom_dotplot} \alias{geom_dotplot} -\title{Dot plot} +\title{Dot plot (removed)} \usage{ -geom_dotplot( - mapping = NULL, - data = NULL, - position = "identity", - ..., - binwidth = NULL, - binaxis = "x", - method = "dotdensity", - binpositions = "bygroup", - stackdir = "up", - stackratio = 1, - dotsize = 1, - stackgroups = FALSE, - origin = NULL, - right = TRUE, - width = 0.9, - drop = FALSE, - na.rm = FALSE, - show.legend = NA, - inherit.aes = TRUE -) -} -\arguments{ -\item{mapping}{Set of aesthetic mappings created by \code{\link{aes}} or -\code{\link{aes_}}. If specified and \code{inherit.aes = TRUE} (the -default), it is combined with the default mapping at the top level of the -plot. You must supply \code{mapping} if there is no plot mapping.} - -\item{data}{The data to be displayed in this layer. There are three - options: - - If \code{NULL}, the default, the data is inherited from the plot - data as specified in the call to \code{\link{ggplot}}. - - A \code{data.frame}, or other object, will override the plot - data. All objects will be fortified to produce a data frame. See - \code{\link{fortify}} for which variables will be created. - - A \code{function} will be called with a single argument, - the plot data. The return value must be a \code{data.frame.}, and - will be used as the layer data.} - -\item{position}{Position adjustment, either as a string, or the result of -a call to a position adjustment function.} - -\item{...}{other arguments passed on to \code{\link{layer}}. These are -often aesthetics, used to set an aesthetic to a fixed value, like -\code{color = "red"} or \code{size = 3}. They may also be parameters -to the paired geom/stat.} - -\item{binwidth}{When \code{method} is "dotdensity", this specifies maximum bin -width. When \code{method} is "histodot", this specifies bin width. -Defaults to 1/30 of the range of the data} - -\item{binaxis}{The axis to bin along, "x" (default) or "y"} - -\item{method}{"dotdensity" (default) for dot-density binning, or -"histodot" for fixed bin widths (like stat_bin)} - -\item{binpositions}{When \code{method} is "dotdensity", "bygroup" (default) -determines positions of the bins for each group separately. "all" determines -positions of the bins with all the data taken together; this is used for -aligning dot stacks across multiple groups.} - -\item{stackdir}{which direction to stack the dots. "up" (default), -"down", "center", "centerwhole" (centered, but with dots aligned)} - -\item{stackratio}{how close to stack the dots. Default is 1, where dots just -just touch. Use smaller values for closer, overlapping dots.} - -\item{dotsize}{The diameter of the dots relative to \code{binwidth}, default 1.} - -\item{stackgroups}{should dots be stacked across groups? This has the effect -that \code{position = "stack"} should have, but can't (because this geom has -some odd properties).} - -\item{origin}{When \code{method} is "histodot", origin of first bin} - -\item{right}{When \code{method} is "histodot", should intervals be closed -on the right (a, b], or not [a, b)} - -\item{width}{When \code{binaxis} is "y", the spacing of the dot stacks -for dodging.} - -\item{drop}{If TRUE, remove all bins with zero counts} - -\item{na.rm}{If \code{FALSE} (the default), removes missing values with -a warning. If \code{TRUE} silently removes missing values.} - -\item{show.legend}{logical. Should this layer be included in the legends? -\code{NA}, the default, includes if any aesthetics are mapped. -\code{FALSE} never includes, and \code{TRUE} always includes.} - -\item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics, -rather than combining with them. This is most useful for helper functions -that define both data and aesthetics and shouldn't inherit behaviour from -the default plot specification, e.g. \code{\link{borders}}.} +geom_dotplot(...) } \description{ -In a dot plot, the width of a dot corresponds to the bin width -(or maximum width, depending on the binning algorithm), and dots are -stacked, with each dot representing one observation. -} -\details{ -With dot-density binning, the bin positions are determined by the data and -\code{binwidth}, which is the maximum width of each bin. See Wilkinson -(1999) for details on the dot-density binning algorithm. - -With histodot binning, the bins have fixed positions and fixed widths, much -like a histogram. - -When binning along the x axis and stacking along the y axis, the numbers on -y axis are not meaningful, due to technical limitations of ggplot2. You can -hide the y axis, as in one of the examples, or manually scale it -to match the number of dots. -} -\section{Aesthetics}{ - -\Sexpr[results=rd,stage=build]{animint2:::rd_aesthetics("geom", "dotplot")} -} - -\section{Computed variables}{ - -\describe{ - \item{x}{center of each bin, if binaxis is "x"} - \item{y}{center of each bin, if binaxis is "x"} - \item{binwidth}{max width of each bin if method is "dotdensity"; - width of each bin if method is "histodot"} - \item{count}{number of points in bin} - \item{ncount}{count, scaled to maximum of 1} - \item{density}{density of points in bin, scaled to integrate to 1, - if method is "histodot"} - \item{ndensity}{density, scaled to maximum of 1, if method is "histodot"} -} -} - -\examples{ -ggplot(mtcars, aes(x = mpg)) + geom_dotplot() -ggplot(mtcars, aes(x = mpg)) + geom_dotplot(binwidth = 1.5) - -# Use fixed-width bins -ggplot(mtcars, aes(x = mpg)) + - geom_dotplot(method="histodot", binwidth = 1.5) - -# Some other stacking methods -ggplot(mtcars, aes(x = mpg)) + - geom_dotplot(binwidth = 1.5, stackdir = "center") -ggplot(mtcars, aes(x = mpg)) + - geom_dotplot(binwidth = 1.5, stackdir = "centerwhole") - -# y axis isn't really meaningful, so hide it -ggplot(mtcars, aes(x = mpg)) + geom_dotplot(binwidth = 1.5) + - scale_y_continuous(NULL, breaks = NULL) - -# Overlap dots vertically -ggplot(mtcars, aes(x = mpg)) + geom_dotplot(binwidth = 1.5, stackratio = .7) - -# Expand dot diameter -ggplot(mtcars, aes(x = mpg)) + geom_dotplot(binwidth = 1.5, dotsize = 1.25) - -\donttest{ -# Examples with stacking along y axis instead of x -ggplot(mtcars, aes(x = 1, y = mpg)) + - geom_dotplot(binaxis = "y", stackdir = "center") - -ggplot(mtcars, aes(x = factor(cyl), y = mpg)) + - geom_dotplot(binaxis = "y", stackdir = "center") - -ggplot(mtcars, aes(x = factor(cyl), y = mpg)) + - geom_dotplot(binaxis = "y", stackdir = "centerwhole") - -ggplot(mtcars, aes(x = factor(vs), fill = factor(cyl), y = mpg)) + - geom_dotplot(binaxis = "y", stackdir = "center", position = "dodge") - -# binpositions="all" ensures that the bins are aligned between groups -ggplot(mtcars, aes(x = factor(am), y = mpg)) + - geom_dotplot(binaxis = "y", stackdir = "center", binpositions="all") - -# Stacking multiple groups, with different fill -ggplot(mtcars, aes(x = mpg, fill = factor(cyl))) + - geom_dotplot(stackgroups = TRUE, binwidth = 1, binpositions = "all") - -ggplot(mtcars, aes(x = mpg, fill = factor(cyl))) + - geom_dotplot(stackgroups = TRUE, binwidth = 1, method = "histodot") - -ggplot(mtcars, aes(x = 1, y = mpg, fill = factor(cyl))) + - geom_dotplot(binaxis = "y", stackgroups = TRUE, binwidth = 1, method = "histodot") -} -} -\references{ -Wilkinson, L. (1999) Dot plots. The American Statistician, - 53(3), 276-281. +`geom_dotplot()` has been removed from animint2 due to fundamental issues +with interactive rendering. Please use `geom_point()` instead. } +\keyword{internal} diff --git a/tests/testthat/test-compiler-dotplot.r b/tests/testthat/test-compiler-dotplot.r index d92456b26..1292314b1 100644 --- a/tests/testthat/test-compiler-dotplot.r +++ b/tests/testthat/test-compiler-dotplot.r @@ -1,65 +1,27 @@ -context("Dotplot") - -set.seed(111) -dat <- data.frame(x = LETTERS[1:2], y = rnorm(30), g = LETTERS[3:5]) - -test_that("Dodging works", { - p <- ggplot(dat, aes(x = x, y = y, fill = g)) + - geom_dotplot( - binwidth = 0.2, - binaxis = "y", - position = "dodge", - stackdir = "center" - ) - df <- layer_data(p) - - # Number of levels in the dodged variable - ndodge <- 3 - - # The amount of space allocated within each dodge group - dwidth <- .9 / ndodge - - # This should be the x position for each before dodging - xbase <- ceiling(df$group / ndodge) - - # This is the offset from dodging - xoffset <- (df$group - 1) %% ndodge - (ndodge - 1) / 2 - xoffset <- xoffset * dwidth - - # Check actual x locations equal predicted x locations - expect_true(all(abs(df$x - (xbase + xoffset)) < 1e-6)) - - # Check that xmin and xmax are in the right place - expect_true(all(abs(df$xmax - df$x - dwidth/2) < 1e-6)) - expect_true(all(abs(df$x - df$xmin - dwidth/2) < 1e-6)) -}) - - -test_that("Binning works", { - bp <- ggplot(dat, aes(y)) + - geom_dotplot(binwidth = .4, method = "histodot") - x <- layer_data(bp)$x - - # Need ugly hack to make sure mod function doesn't give values like -3.99999 - # due to floating point error - expect_true(all(abs((x - min(x) + 1e-7) %% .4) < 1e-6)) - - bp <- ggplot(dat, aes(x = y)) + - geom_dotplot(binwidth = .4, method = "dotdensity") - x <- layer_data(bp)$x - - # This one doesn't ensure that dotdensity works, but it does check that it's not - # doing fixed bin sizes - expect_false(all(abs((x - min(x) + 1e-7) %% .4) < 1e-6)) -}) - - -test_that("NA's result in warning from stat_bindot", { - set.seed(122) - dat <- data.frame(x = rnorm(20)) - dat$x[c(2,10)] <- NA - - # Need to assign it to a var here so that it doesn't automatically print - expect_warning(ggplot_build(ggplot(dat, aes(x)) + geom_dotplot(binwidth = .2)), - "Removed 2 rows.*stat_bindot") -}) +context("Dotplot removal") + +test_that("geom_dotplot throws error with removal message", { + dat <- data.frame(x = LETTERS[1:2], y = rnorm(30), g = LETTERS[3:5]) + + # Test that any call to geom_dotplot produces the expected error + expect_error( + ggplot(dat, aes(x, y)) + geom_dotplot(), + "geom_dotplot.*removed" + ) + + expect_error( + ggplot(dat, aes(x = x, y = y, fill = g)) + + geom_dotplot(binwidth = 0.2, binaxis = "y", position = "dodge", stackdir = "center"), + "geom_dotplot.*removed" + ) + + expect_error( + ggplot(dat, aes(y)) + geom_dotplot(binwidth = .4, method = "histodot"), + "geom_dotplot.*removed" + ) + + expect_error( + ggplot(dat, aes(x = y)) + geom_dotplot(binwidth = .4, method = "dotdensity"), + "geom_dotplot.*removed" + ) +}) \ No newline at end of file diff --git a/tests/testthat/test-compiler-function-args.r b/tests/testthat/test-compiler-function-args.r index 999803b8a..a9ac38e4f 100644 --- a/tests/testthat/test-compiler-function-args.r +++ b/tests/testthat/test-compiler-function-args.r @@ -13,7 +13,7 @@ test_that("geom_xxx and GeomXxx$draw arg defaults match", { # These aren't actually geoms, or need special parameters and can't be tested this way. geom_fun_names <- setdiff( geom_fun_names, - c("geom_aesthetics", "geom_map", "annotation_custom", "annotation_map", "annotation_id") + c("geom_aesthetics", "geom_map", "annotation_custom", "annotation_map", "annotation_id","geom_dotplot") ) # For each geom_xxx function and the corresponding GeomXxx$draw and From 789a70ed20b5263c3bfe9d7e7c397a96ca0e6ad7 Mon Sep 17 00:00:00 2001 From: NandaniAggarwal Date: Wed, 11 Mar 2026 00:39:23 +0530 Subject: [PATCH 3/7] Delete man/checkSelectorNames.Rd --- man/checkSelectorNames.Rd | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 man/checkSelectorNames.Rd diff --git a/man/checkSelectorNames.Rd b/man/checkSelectorNames.Rd deleted file mode 100644 index c8ffe6875..000000000 --- a/man/checkSelectorNames.Rd +++ /dev/null @@ -1,17 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/z_animintHelpers.R -\name{checkSelectorNames} -\alias{checkSelectorNames} -\title{Validate selector names for CSS compatibility} -\usage{ -checkSelectorNames(selectors) -} -\arguments{ -\item{selectors}{selectors to validate} -} -\value{ -\code{NULL}. Throws error if invalid characters found. -} -\description{ -Validate selector names for CSS compatibility -} From 36fda33ad62398dfc61774e201696eb9e98553ce Mon Sep 17 00:00:00 2001 From: NandaniAggarwal Date: Wed, 11 Mar 2026 00:40:55 +0530 Subject: [PATCH 4/7] Refactor geom_dotplot to simplify error message --- R/geom-dotplot.r | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/R/geom-dotplot.r b/R/geom-dotplot.r index 7e61f7642..8b607da2c 100644 --- a/R/geom-dotplot.r +++ b/R/geom-dotplot.r @@ -7,8 +7,5 @@ #' @export #' @keywords internal geom_dotplot <- function(...) { - stop( - "geom_dotplot() has been removed from animint2. Use geom_point() instead.\n", - "See issue #289 for details: https://github.com/animint/animint2/issues/289" - ) + stop("geom_dotplot() has been removed from animint2. Use geom_point() instead. See issue #289 for details: https://github.com/animint/animint2/issues/289") } From 58bed9bfbdf3e118217aee90b7e144f1c0d3da83 Mon Sep 17 00:00:00 2001 From: NandaniAggarwal Date: Wed, 11 Mar 2026 00:43:04 +0530 Subject: [PATCH 5/7] Update tests for geom_dotplot removal --- tests/testthat/test-compiler-dotplot.r | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/tests/testthat/test-compiler-dotplot.r b/tests/testthat/test-compiler-dotplot.r index 1292314b1..369a108dc 100644 --- a/tests/testthat/test-compiler-dotplot.r +++ b/tests/testthat/test-compiler-dotplot.r @@ -6,22 +6,6 @@ test_that("geom_dotplot throws error with removal message", { # Test that any call to geom_dotplot produces the expected error expect_error( ggplot(dat, aes(x, y)) + geom_dotplot(), - "geom_dotplot.*removed" + "geom_dotplot() has been removed from animint2. Use geom_point() instead." ) - - expect_error( - ggplot(dat, aes(x = x, y = y, fill = g)) + - geom_dotplot(binwidth = 0.2, binaxis = "y", position = "dodge", stackdir = "center"), - "geom_dotplot.*removed" - ) - - expect_error( - ggplot(dat, aes(y)) + geom_dotplot(binwidth = .4, method = "histodot"), - "geom_dotplot.*removed" - ) - - expect_error( - ggplot(dat, aes(x = y)) + geom_dotplot(binwidth = .4, method = "dotdensity"), - "geom_dotplot.*removed" - ) -}) \ No newline at end of file +}) From 5755e0a51006e3add9ac2f02b164ba62040f3bec Mon Sep 17 00:00:00 2001 From: NandaniAggarwal Date: Wed, 11 Mar 2026 00:43:36 +0530 Subject: [PATCH 6/7] Delete tests/testthat/test-renderer1-dotplot.R --- tests/testthat/test-renderer1-dotplot.R | 32 ------------------------- 1 file changed, 32 deletions(-) delete mode 100644 tests/testthat/test-renderer1-dotplot.R diff --git a/tests/testthat/test-renderer1-dotplot.R b/tests/testthat/test-renderer1-dotplot.R deleted file mode 100644 index fae7e7f9c..000000000 --- a/tests/testthat/test-renderer1-dotplot.R +++ /dev/null @@ -1,32 +0,0 @@ -library(testthat) -library(animint2) - -test_that("geom_dotplot shows error", { - expect_error( - geom_dotplot(), - "geom_point" - ) -}) - -test_that("geom_point creates a plot object", { - df <- data.frame(x = "A", y = c(1, 1.1, 1.2, 1.3, 100, 200)) - p <- ggplot() + geom_point(aes(x, y), data = df) - - expect_true(is.ggplot(p)) -}) - -test_that("geom_point produces no warnings", { - df <- data.frame(x = "A", y = c(1, 1.1, 1.2, 1.3, 100, 200)) - - expect_no_warning( - ggplot() + geom_point(aes(x, y), data = df) - ) -}) - -test_that("geom_point produces no errors", { - df <- data.frame(x = "A", y = c(1, 1.1, 1.2, 1.3, 100, 200)) - - expect_no_error( - ggplot() + geom_point(aes(x, y), data = df) - ) -}) \ No newline at end of file From a102a3de44096e1240daf21b4585680e19eb2e0c Mon Sep 17 00:00:00 2001 From: NandaniAggarwal Date: Wed, 11 Mar 2026 01:21:24 +0530 Subject: [PATCH 7/7] Added fixed to true for considering it fixed string --- tests/testthat/test-compiler-dotplot.r | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/testthat/test-compiler-dotplot.r b/tests/testthat/test-compiler-dotplot.r index 369a108dc..de99567eb 100644 --- a/tests/testthat/test-compiler-dotplot.r +++ b/tests/testthat/test-compiler-dotplot.r @@ -6,6 +6,7 @@ test_that("geom_dotplot throws error with removal message", { # Test that any call to geom_dotplot produces the expected error expect_error( ggplot(dat, aes(x, y)) + geom_dotplot(), - "geom_dotplot() has been removed from animint2. Use geom_point() instead." + "geom_dotplot() has been removed from animint2. Use geom_point() instead. See issue #289 for details: https://github.com/animint/animint2/issues/289", + fixed = TRUE ) })