Modify spacing between key glyphs in vertical legend whilst keeping key glyph border [duplicate]
Asked Answered
I

1

5

As a follow up to this famous thread. I decided to ask a new question because this is more specifically for vertical legends, and the given answers still don't provide a fully satisfactory solution. For polygon key glyphs, there was a suggestion to increase the size of the margin between the actual polygon glyph and the key border, with a modification of the underlying draw_key function. However, this doesn't really work if I want to keep a border, e.g., in black.

And when using other geoms (e.g., geom_line), I don't even see how to increase the margin between glyph and border - on a brief glance at the draw_key function used in ggplot2:::GeomLine (it doesn't use an exported draw_key function), it is not clear to me where to modify this.

So, my question is if there is a way to change the actual space between the key glyphs that would allow to keep a border (e.g., color = "black"), and without increasing the glyph size.

library(ggplot2)

p <- ggplot(dplyr::filter(msleep, grepl("^C", order)), 
       aes(sleep_total, sleep_rem, color = order)) +
  geom_line(na.rm = TRUE) +
  theme(legend.key = element_rect(color = "black"))
p

Example plot: Key glyphs touching.

p + theme(legend.key.height = unit(.5, "in"))

Example that would look as if the glyphs are more spaced if I'd remove the color, but I want the key glyphs in the same size as above, just space between them.

The underlying draw_key in GeomLine

# ggplot2:::GeomLine$draw_key
#> ...
#> segmentsGrob(0.1, 0.5, 0.9, 0.5, gp = gpar(col = alpha(data$colour %||% 
#>                                                          data$fill %||% "black", data$alpha), fill = alpha(params$arrow.fill %||% 
#>                                                                                                              data$colour %||% data$fill %||% "black", data$alpha), 
#>                                            lwd = (data$size %||% 0.5) * .pt, lty = data$linetype %||% 
#>                                              1, lineend = "butt"), arrow = params$arrow)
#> ...

Created on 2021-12-29 by the reprex package (v2.0.1)

P.S. This question arose on answering this interesting question

Irtysh answered 29/12, 2021 at 18:49 Comment(0)
R
5

There is a way to do this, but it is not very intuitive. It depends on the byrow setting in the legend guide, whether the legend spacing is respected or not (don't ask me why!).

library(ggplot2)

ggplot(dplyr::filter(msleep, grepl("^C", order)), 
            aes(sleep_total, sleep_rem, color = order)) +
  geom_line(na.rm = TRUE) +
  guides(
    color = guide_legend(byrow = TRUE)
  ) +
  theme(legend.key = element_rect(color = "black"),
        legend.spacing.y = unit(1, "cm"))

Created on 2021-12-30 by the reprex package (v2.0.0)

I've complained raised the suggestion that this is unintuitive elsewhere.

If you want the title to be in a relatively normal position, you can use the following incantation to the theme function, wherein 11 pt is the default legend spacing:

legend.title = element_text(
  margin = margin(
  b = -1 + grid::convertUnit(unit(11, "pt"), "cm", valueOnly = TRUE), 
  unit = "cm")
)
Robichaux answered 29/12, 2021 at 23:22 Comment(1)
Teunbrand. thanks once more, and certainly not the last time :) I've updated Tung's answer in the linked thread accordingly, and closed this thread here as a duplicate. Happy new yearIrtysh

© 2022 - 2024 — McMap. All rights reserved.