Skip to content

Commit fcea644

Browse files
cpsievertclaude
andcommitted
Fix #2305: geom_boxplot outlier.shape=NA now hides outlier points
The geom2trace.GeomBoxplot function now checks for: - outliers = FALSE parameter - outlier.shape = NA (via params$outlier_gp$shape in newer ggplot2) When either condition is true, boxpoints is set to FALSE in the plotly trace to hide outlier points. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent a6ba02d commit fcea644

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

R/layers2traces.R

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,12 @@ geom2trace.GeomBoxplot <- function(data, params, p) {
872872
# marker styling must inherit from GeomPoint$default_aes
873873
# https://github.com/hadley/ggplot2/blob/ab42c2ca81458b0cf78e3ba47ed5db21f4d0fc30/NEWS#L73-L7
874874
point_defaults <- GeomPoint$use_defaults(NULL)
875+
876+
# Determine if outliers should be hidden
877+
# Hide outliers if: outliers = FALSE, or outlier.shape = NA (via outlier_gp$shape)
878+
hide_outliers <- isFALSE(params$outliers) ||
879+
isTRUE(is.na(params$outlier_gp$shape))
880+
875881
compact(list(
876882
x = data[["x"]],
877883
y = data[["y"]],
@@ -885,6 +891,8 @@ geom2trace.GeomBoxplot <- function(data, params, p) {
885891
aes2plotly(data, params, "fill"),
886892
aes2plotly(data, params, "alpha")
887893
),
894+
# Control whether outlier points are shown
895+
boxpoints = if (hide_outliers) FALSE else "outliers",
888896
# markers/points
889897
marker = list(
890898
opacity = point_defaults$alpha,

tests/testthat/test-ggplot-boxplot.R

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,29 @@ test_that("correct # of unique fillcolors", {
8383
fills <- sapply(L$data, "[[", "fillcolor")
8484
expect_equivalent(length(unique(fills)), length(unique(dat$col)))
8585
})
86+
87+
test_that("outlier.shape = NA hides outlier points (#2305)", {
88+
# With outlier.shape = NA, plotly should not show outlier points
89+
p <- ggplot(iris, aes(Species, Sepal.Length)) + geom_boxplot(outlier.shape = NA)
90+
L <- plotly_build(ggplotly(p))$x
91+
expect_equal(L$data[[1]]$type, "box")
92+
# boxpoints should be FALSE or "false" to hide outliers
93+
expect_true(isFALSE(L$data[[1]]$boxpoints) || identical(L$data[[1]]$boxpoints, "false"))
94+
95+
# With default (no outlier.shape specified), outliers should show
96+
p_default <- ggplot(iris, aes(Species, Sepal.Length)) + geom_boxplot()
97+
L_default <- plotly_build(ggplotly(p_default))$x
98+
# Default should either be NULL (plotly default shows outliers) or "outliers"/"suspectedoutliers"
99+
expect_true(
100+
is.null(L_default$data[[1]]$boxpoints) ||
101+
L_default$data[[1]]$boxpoints %in% c("outliers", "suspectedoutliers", TRUE)
102+
)
103+
})
104+
105+
test_that("outliers = FALSE hides outlier points", {
106+
# ggplot2 also supports outliers = FALSE parameter
107+
p <- ggplot(iris, aes(Species, Sepal.Length)) + geom_boxplot(outliers = FALSE)
108+
L <- plotly_build(ggplotly(p))$x
109+
expect_equal(L$data[[1]]$type, "box")
110+
expect_true(isFALSE(L$data[[1]]$boxpoints) || identical(L$data[[1]]$boxpoints, "false"))
111+
})

0 commit comments

Comments
 (0)