New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Legend title is incorrectly aligned when horizontal #2465

Open
hadley opened this Issue Feb 27, 2018 · 10 comments

Comments

Projects
None yet
5 participants
@hadley
Member

hadley commented Feb 27, 2018

library(ggplot2)

df <- data.frame(z = 1:5)
p <- ggplot(df, aes(1, 1, colour = z)) + geom_point()

# Title should be centered with legend
p + theme(legend.position = "top")

@hadley hadley added this to the v2.3.0 milestone Apr 27, 2018

@hadley hadley changed the title from Check on legend text alignment to Legend title is incorrectly aligned when horizontal May 1, 2018

@hadley

This comment has been minimized.

Member

hadley commented May 1, 2018

@clauswilke have you seen this too? I quickly skimmed through your PRs but I didn't see anything that addressed this explicitly

@clauswilke

This comment has been minimized.

Member

clauswilke commented May 1, 2018

I haven't addressed or modified this in any way. What is happening is that the title is centered relative to the entire legend:

p + theme(legend.position = "top") + 
  theme(legend.spacing.y = grid::unit(50, "cm")) # 50 cm equals to 5 cm because of issue #2398

screen shot 2018-05-01 at 5 49 25 pm

@clauswilke

This comment has been minimized.

Member

clauswilke commented May 1, 2018

Note that guide_legend() behaves exactly the same:

df <- data.frame(z = 1:5)
p <- ggplot(df, aes(1, 1, colour = factor(z))) + 
  geom_point() + 
  scale_color_discrete(guide = guide_legend(label.position = "bottom"))

# Title should be centered with legend
p + theme(legend.position = "top") + theme(legend.spacing.y = grid::unit(5, "cm"))

screen shot 2018-05-01 at 5 56 08 pm

@hadley

This comment has been minimized.

Member

hadley commented May 1, 2018

Oh so this probably isn't a regression

@hadley hadley removed this from the v2.3.0 milestone May 1, 2018

@clauswilke

This comment has been minimized.

Member

clauswilke commented May 6, 2018

The bigger issue, in my mind, is that there is no simple workaround, because the vjust setting is ignored. I'm showing this here with both a discrete and a continuous scale, to show that they behave the same:

library(ggplot2)
p <- ggplot(mtcars, aes(hp, disp, color = mpg, shape = factor(cyl))) +
  geom_point(size = 2) +
  scale_shape_discrete(guide = guide_legend(label.position = "bottom")) + 
  theme(legend.position = "top")
p

screen shot 2018-05-06 at 3 14 39 pm

p + theme(legend.title = element_text(vjust = 1, colour = "red"))

screen shot 2018-05-06 at 3 14 29 pm

(I've colored the legend title red to show that styling the legend title works, only the justification arguments are ignored.)

I'll see if there's a simple way to fix this that doesn't require touching much code. In the long run, I think the legend drawing code needs to be rethought from the ground up, but that's not for 2.3.0.

@ptoche

This comment has been minimized.

ptoche commented May 6, 2018

Workaround of sorts:

library(ggplot2)
ggplot(mtcars, aes(hp, disp, color = mpg, shape = factor(cyl))) +
    geom_point(size = 2) +
    theme(legend.position = "top") +
    guides(shape = guide_legend(label.position = "bottom", 
            title.position = "left", title.vjust = 0.8), 
        color = guide_legend(label.position = "top", 
            title.position = "right", title.vjust=0.4))

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

@clauswilke

This comment has been minimized.

Member

clauswilke commented May 6, 2018

I now see that there are (at least) two separate issues. One is that vjust and hjust can't be set in the theme but can be set via the guide function. It is a simple fix to allow setting via the theme as well. The second is that the margin settings in legend.title are ignored. This is a problem because if we set vjust to a number other than 1 then the text is moved different amounts for grobs of different heights. I guess the workaround could be to manually fiddle with the title.vjust settings for each guide function until things look right, but if margins could be set that would be better I think.

library(ggplot2)
ggplot(mtcars, aes(hp, disp, color = mpg, shape = factor(cyl))) +
  geom_point(size = 2) + theme(legend.position = "top") +
  guides(color = guide_colorbar(title.vjust = .8),
         shape = guide_legend(title.vjust = .8)) +
  theme(legend.title = 
          element_text(
            debug = TRUE,
            margin = margin(10, 0, 0, 0, "pt") # margin setting is ignored
          )
       )

screen shot 2018-05-06 at 5 57 52 pm

@karawoo

This comment has been minimized.

Member

karawoo commented May 7, 2018

The latter issue about the margins for legend text/titles has been raised in #1502. I tried to tackle that after reworking titleGrob() last year, but wasn't able to wrap my head around the legend code enough to make any headway at the time.

@clauswilke

This comment has been minimized.

Member

clauswilke commented May 7, 2018

@karawoo I just opened a pull request (#2556) that provides a partial fix for this issue. I hadn't seen #1502 previously and will take a look. My fix for legend titles would likely work for legend text as well. (Meaning: we can use the same technique to fix legend text. But it isn't currently fixed in the pending pull request.)

@flying-sheep

This comment has been minimized.

flying-sheep commented Dec 7, 2018

Also if you fiddle with title.vjust, the bounding box is unaffected. If you title is higher than the legend, this results in some seriously wrong spacing:

grafik

this is title.vjust = 5 to make the bar line up with the second line of the title.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment