tidyverse / ggplot2

An implementation of the Grammar of Graphics in R
https://ggplot2.tidyverse.org
Other
6.54k stars 2.03k forks source link

Legend label alignment weirdness #2573

Closed hadley closed 6 years ago

hadley commented 6 years ago
library(ggplot2)
df <- reshape2::melt(outer(1:4, 1:4), varnames = c("X1", "X2"))

p1 <- ggplot(df, aes(X1, X2)) + geom_tile(aes(fill = value))
p1 + scale_fill_continuous(breaks = c(5, 10, 15),
  labels = paste("long", c(5, 10, 15)),
  guide = guide_legend(
    direction = "horizontal",
    title.position = "top",
    label.position = "bottom",
    label.theme = element_text(angle = 90, hjust = 1, vjust = 1)
  )
)

Created on 2018-05-11 by the reprex package (v0.2.0).

hjust and vjust seem to interact in weird ways here so I couldn't get them looking correctly (i.e. centered and top-aligned). @clauswilke would you mind taking a look?

clauswilke commented 6 years ago

Rotated text is going to be the end of me. I'll take a look.

clauswilke commented 6 years ago

There's two separate issues here:

  1. When using the justify_grob() function, I must not also set hjust and vjust inside the text grob. Makes sense but didn't come up until you tried rotated text.

  2. Should the meaning of hjust and vjust be flipped when text is rotated? For the justify_grobs() function I opted for no, since that function should be general and cannot figure out in what orientation the grob internals are drawn. However, I could add a parameter that tells justify_grobs() the internal orientation and modifies hjust and vjust accordingly, similar to what is done here: https://github.com/tidyverse/ggplot2/blob/4463da6abc9b8ff7a2451686b9685de36933b358/R/margins.R#L42-L55

Fixing point 1 but not point 2, I get:

library(ggplot2)
df <- reshape2::melt(outer(1:4, 1:4), varnames = c("X1", "X2"))

p1 <- ggplot(df, aes(X1, X2)) + geom_tile(aes(fill = value))
p1 + scale_fill_continuous(
  breaks = c(5, 10, 15),
  labels = paste("long", c(5, 10, 15)),
  guide = guide_legend(
    direction = "horizontal",
    title.position = "top",
    label.position = "bottom",
    label.theme = element_text(angle = 90, hjust = 0.5, vjust = 1, debug = TRUE)
  )
)

karawoo commented 6 years ago

On point 2, I think the answer should be yes, hjust and vjust should be interpreted relative to the direction of the text because that's how axis titles, facet strip labels, etc. already behave.

clauswilke commented 6 years ago

@karawoo I think you're right, though it's confusing because margins do not behave this way. Overall, I think the entire text handling is still not quite right and overly complex, but that's beyond the scope of what can be done for this release.

baptiste commented 6 years ago

These issues have come up over and over again (suggesting some design flaws in grid and elsewhere). Could it be discussed within the broader scope of grid, or at least gtable? titleGrob, justify_grobs, etc. really belong in the broader ecosystem.

It's good if ggplot2 defines a robust and consistent way to handle margins/padding, justification, and rotation, but it would be so much better if such strategies were accessible, documented, and discussed outside ggplot2, to become a new standard for future developments in extension packages and in grid itself.

lock[bot] commented 6 years ago

This old issue has been automatically locked. If you believe you have found a related problem, please file a new issue (with reprex) and link to this issue. https://reprex.tidyverse.org/