Skip to content
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 · 12 comments
Open

Legend title is incorrectly aligned when horizontal #2465

hadley opened this issue Feb 27, 2018 · 12 comments
Labels
bug an unexpected problem or unintended behavior guides 📏 themes 💃

Comments

@hadley
Copy link
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 bug an unexpected problem or unintended behavior themes 💃 labels Apr 27, 2018
@hadley hadley added this to the v2.3.0 milestone Apr 27, 2018
@hadley hadley changed the title Check on legend text alignment Legend title is incorrectly aligned when horizontal May 1, 2018
@hadley
Copy link
Member Author

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
Copy link
Member

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
Copy link
Member

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
Copy link
Member Author

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
Copy link
Member

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
Copy link

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
Copy link
Member

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
Copy link
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
Copy link
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
Copy link
Contributor

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.

@ThomasDelSantoONeill
Copy link

Dear @clauswilke and @hadley
I was wondering how to position the legend title on top of an horizontal scale_colour_gradient key. Is this possible at all? Also it seems that the key does not fill completely.
Cheers in advance!!! :)

image

ggraph(lay.ggraph) +
  geom_edge_link0(aes(color = links$weight), width = links$weight*10, lineend = "round") + 
  scale_edge_color_gradient(name = "Link Strength", low = "#6495ED85", high = "#C1403D85") +
  geom_node_point(shape = 21, fill = "#D3D3D3", 
                  color = "#808080", size = 15, stroke = 2) +
  foodweb_theme +
  theme(legend.position = c(0.9, 0.1),
        legend.direction = "horizontal") +
  labs(y = "TL")

@ThomasDelSantoONeill
Copy link

Hi again,

I did find a workaround solution. Only a bit of merging trickery was needed between ggraph and ggplot2. Basically everything missing needed to be inserted in the guide = guide_edge_colorbar(...) argument within scale_edge_color_gradient. For the "not enterly filled colorbar" key I set the upper limit a bit more than 1 (i.e. 1.1). Code:

ggraph(lay.ggraph) + 
  geom_edge_link0(aes(edge_colour = links$weight), edge_width = links$weight*10, lineend = "round") +
  scale_edge_color_gradient(name = "Link Strength", low = "#6495ED85", high = "#C1403D85",
                            limits = c(0,1.01),
                            guide = guide_edge_colorbar(title = "Link Strength", title.position = "top",
                                                        title.hjust = 0.5, ticks = TRUE, label = TRUE,
                                                        frame.colour = "black", barwidth = 7.5)) +
  geom_node_point(shape = 21, fill = "#D3D3D3", color = "#808080", size = 15, stroke = 2) +
  labs(y = "TL") +
  foodweb_theme

This produces:

image

All the absolute best!

@thomasp85 thomasp85 added this to the ggplot2 3.3.4 milestone Mar 25, 2021
@thomasp85 thomasp85 removed this from the ggplot2 3.4.0 milestone May 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug an unexpected problem or unintended behavior guides 📏 themes 💃
Projects
None yet
Development

No branches or pull requests

8 participants