diff --git a/NAMESPACE b/NAMESPACE
index 143c78b767..a931b99665 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -305,6 +305,7 @@ export(draw_key_boxplot)
export(draw_key_crossbar)
export(draw_key_dotplot)
export(draw_key_label)
+export(draw_key_linerange)
export(draw_key_path)
export(draw_key_point)
export(draw_key_pointrange)
diff --git a/NEWS.md b/NEWS.md
index 5733b1e4ef..91ac7ab6dc 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -67,6 +67,9 @@ precedence between `bins` and `binwidth`. (@eliocamp, #4651)
* Dots in `geom_dotplot()` are now correctly aligned to the baseline when
`stackratio != 1` and `stackdir != "up"` (@mjskay, #4614)
+* Key glyphs for `geom_boxplot()`, `geom_crossbar()`, `geom_pointrange()`, and
+ `geom_linerange()` are now orientation-aware (@mjskay, #4732)
+
# ggplot2 3.3.5
This is a very small release focusing on fixing a couple of untenable issues
that surfaced with the 3.3.4 release
diff --git a/R/geom-linerange.r b/R/geom-linerange.r
index 5e9462013b..2d5bf284d6 100644
--- a/R/geom-linerange.r
+++ b/R/geom-linerange.r
@@ -93,7 +93,7 @@ geom_linerange <- function(mapping = NULL, data = NULL,
GeomLinerange <- ggproto("GeomLinerange", Geom,
default_aes = aes(colour = "black", size = 0.5, linetype = 1, alpha = NA),
- draw_key = draw_key_vpath,
+ draw_key = draw_key_linerange,
required_aes = c("x|y", "ymin|xmin", "ymax|xmax"),
diff --git a/R/legend-draw.r b/R/legend-draw.r
index ac02b97fea..aebcc83c36 100644
--- a/R/legend-draw.r
+++ b/R/legend-draw.r
@@ -106,7 +106,8 @@ draw_key_boxplot <- function(data, params, size) {
lty = data$linetype %||% 1,
lineend = params$lineend %||% "butt",
linejoin = params$linejoin %||% "mitre"
- )
+ ),
+ vp = if (isTRUE(params$flipped_aes)) viewport(angle = -90)
)
}
@@ -123,7 +124,8 @@ draw_key_crossbar <- function(data, params, size) {
lty = data$linetype %||% 1,
lineend = params$lineend %||% "butt",
linejoin = params$linejoin %||% "mitre"
- )
+ ),
+ vp = if (isTRUE(params$flipped_aes)) viewport(angle = -90)
)
}
@@ -177,11 +179,21 @@ draw_key_dotplot <- function(data, params, size) {
)
}
+#' @export
+#' @rdname draw_key
+draw_key_linerange <- function(data, params, size) {
+ if (isTRUE(params$flipped_aes)) {
+ draw_key_path(data, params, size)
+ } else {
+ draw_key_vpath(data, params, size)
+ }
+}
+
#' @export
#' @rdname draw_key
draw_key_pointrange <- function(data, params, size) {
grobTree(
- draw_key_vpath(data, params, size),
+ draw_key_linerange(data, params, size),
draw_key_point(transform(data, size = (data$size %||% 1.5) * 4), params)
)
}
diff --git a/man/draw_key.Rd b/man/draw_key.Rd
index 302855aced..1c0dfc7761 100644
--- a/man/draw_key.Rd
+++ b/man/draw_key.Rd
@@ -12,6 +12,7 @@
\alias{draw_key_path}
\alias{draw_key_vpath}
\alias{draw_key_dotplot}
+\alias{draw_key_linerange}
\alias{draw_key_pointrange}
\alias{draw_key_smooth}
\alias{draw_key_text}
@@ -40,6 +41,8 @@ draw_key_vpath(data, params, size)
draw_key_dotplot(data, params, size)
+draw_key_linerange(data, params, size)
+
draw_key_pointrange(data, params, size)
draw_key_smooth(data, params, size)
diff --git a/tests/testthat/_snaps/draw-key/horizontal-boxplot-and-crossbar.svg b/tests/testthat/_snaps/draw-key/horizontal-boxplot-and-crossbar.svg
new file mode 100755
index 0000000000..3d583d9ea6
--- /dev/null
+++ b/tests/testthat/_snaps/draw-key/horizontal-boxplot-and-crossbar.svg
@@ -0,0 +1,97 @@
+
+
diff --git a/tests/testthat/_snaps/draw-key/horizontal-linerange-and-pointrange.svg b/tests/testthat/_snaps/draw-key/horizontal-linerange-and-pointrange.svg
new file mode 100755
index 0000000000..a427b44746
--- /dev/null
+++ b/tests/testthat/_snaps/draw-key/horizontal-linerange-and-pointrange.svg
@@ -0,0 +1,81 @@
+
+
diff --git a/tests/testthat/test-draw-key.R b/tests/testthat/test-draw-key.R
index d378473b20..aeba592a6c 100644
--- a/tests/testthat/test-draw-key.R
+++ b/tests/testthat/test-draw-key.R
@@ -17,3 +17,37 @@ test_that("alternative key glyphs work", {
geom_point(aes(fill = z), pch = 21, size = 3, stroke = 2, key_glyph = draw_key_dotplot)
)
})
+
+# Orientation-aware key glyphs --------------------------------------------
+
+test_that("horizontal key glyphs work", {
+ df <- data.frame(
+ middle = 1:2,
+ lower = 0:1,
+ upper = 2:3,
+ min = -1:0,
+ max = 3:4,
+ group1 = c("a","b"),
+ group2 = c("c","d")
+ )
+
+ p <- ggplot(df, aes(
+ x = middle,
+ xmiddle = middle,
+ xlower = lower,
+ xupper = upper,
+ xmin = min,
+ xmax = max
+ ))
+
+ expect_doppelganger("horizontal boxplot and crossbar",
+ p +
+ geom_boxplot(aes(y = group1, color = group1), stat = "identity") +
+ geom_crossbar(aes(y = group2, fill = group2))
+ )
+ expect_doppelganger("horizontal linerange and pointrange",
+ p +
+ geom_linerange(aes(y = group1, color = group1)) +
+ geom_pointrange(aes(y = group2, shape = group2))
+ )
+})