Skip to content

Commit 2ee6ed2

Browse files
cpsievertclaude
andcommitted
Fix #2281: geom_blank no longer drops legend for other geoms
Two changes were needed: 1. geom2trace.GeomBlank now returns showlegend = FALSE to prevent blank traces from claiming the legendgroup 2. The legendgroup deduplication logic now skips invisible traces so they don't prevent visible traces from showing in the legend Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 89f9241 commit 2ee6ed2

File tree

3 files changed

+31
-6
lines changed

3 files changed

+31
-6
lines changed

R/ggplotly.R

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,12 +574,17 @@ gg2list <- function(p, width = NULL, height = NULL,
574574
tr
575575
})
576576
# show only one legend entry per legendgroup
577+
# For deduplication, skip invisible traces (like GeomBlank) so they don't
578+
# "claim" the legendgroup and prevent visible traces from showing in legend
577579
grps <- sapply(traces, "[[", "legendgroup")
580+
is_visible <- sapply(traces, function(tr) !isFALSE(tr$visible))
581+
# Only consider visible traces for deduplication - invisible traces shouldn't claim legendgroup
582+
grps_for_dedup <- ifelse(is_visible, grps, paste0(grps, "_invisible_", seq_along(grps)))
578583
traces <- Map(function(x, y) {
579584
if (!is.null(x[["frame"]])) return(x)
580585
x$showlegend <- isTRUE(x$showlegend) && y
581586
x
582-
}, traces, !duplicated(grps))
587+
}, traces, !duplicated(grps_for_dedup))
583588

584589
# ------------------------------------------------------------------------
585590
# axis/facet/margin conversion

R/layers2traces.R

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,9 @@ geom2trace <- function(data, params, p) {
712712

713713
#' @export
714714
geom2trace.GeomBlank <- function(data, params, p) {
715-
list(visible = FALSE)
715+
# GeomBlank should never show in legend - it would claim the legendgroup
716+
# and cause visible traces with the same group to not show their legend entry
717+
list(visible = FALSE, showlegend = FALSE)
716718
}
717719

718720
#' @export

tests/testthat/test-ggplot-blank.R

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,31 @@ test_that("geom_blank", {
33
skip_if_not_installed("ggplot2", "3.4.0")
44
qp <- expect_warning(qplot(), "deprecated")
55
l <- ggplotly(qp)$x
6-
6+
77
expect_length(l$data, 1)
88
expect_false(l$data[[1]]$visible)
9-
9+
1010
l <- ggplotly(ggplot())$x
11-
11+
1212
expect_length(l$data, 1)
1313
expect_false(l$data[[1]]$visible)
14-
14+
15+
})
16+
17+
test_that("geom_blank does not drop legend (#2281)", {
18+
# When geom_blank() is combined with other geoms, legend should still appear
19+
p <- ggplot(iris, aes(Sepal.Length, Sepal.Width, col = Species)) +
20+
geom_blank() +
21+
geom_point()
22+
23+
L <- plotly_build(ggplotly(p))$x
24+
25+
# geom_point should create 3 visible traces with legend
26+
visible_traces <- Filter(function(d) !isFALSE(d$visible) && d$type == "scatter", L$data)
27+
expect_equal(length(visible_traces), 3)
28+
expect_true(any(sapply(visible_traces, function(d) isTRUE(d$showlegend))))
29+
30+
# Trace names should be species names
31+
trace_names <- sapply(visible_traces, function(d) d$name)
32+
expect_true(all(c("setosa", "versicolor", "virginica") %in% trace_names))
1533
})

0 commit comments

Comments
 (0)