Skip to content

Title default alignment to plot not panel (feature request) #3252

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

Closed
dempseynoel opened this issue Apr 20, 2019 · 5 comments · Fixed by #3494
Closed

Title default alignment to plot not panel (feature request) #3252

dempseynoel opened this issue Apr 20, 2019 · 5 comments · Fixed by #3494
Labels
feature a feature request or enhancement themes 💃

Comments

@dempseynoel
Copy link

Currently, the default alignment for titles and subtitles is against the panel of a plot but not the plot itself. In most cases this is absolutely fine, however, where a plot has very long labels on the y axis (x axis if you have done coord-flip) titles will appear quite some way away from the left hand-side of the plot - see the two example plots below.

We can adjust the positioning of titles with the hjust argument, although positioning is dependent on title length and this can be tedious - especially if you are auto-generating lots of plots where the title changes.

Is it possible to set the default alignment of titles and subtitles against the plot instead of against the panel? For example, in Plot 2 this would mean the title being in line with the lefthand most character of the y axis (the A in "And another really really long category name").

Apologies if this issue has been raised before - I couldn't see that it had.


Brief description of the problem

``` r

library(tidyverse)

data <- tibble(
  long_name = c("A really really long category name",
        "Another really really long category name",
        "And another really really long category name"),
  short_name = c("A", "B", "C"),
  values = c(200, 300, 500)
)

ggplot(data, aes(x = short_name, y = values)) +
  geom_bar(stat = "identity") +
  coord_flip() +
  labs(title = "My awesome title goes here...") +
  theme(axis.title.x = element_blank(),
        axis.title.y = element_blank())

ggplot(data, aes(x = long_name, y = values)) +
  geom_bar(stat = "identity") +
  coord_flip() +
  labs(title = "My awesome title goes here...") +
  theme(axis.title.x = element_blank(),
        axis.title.y = element_blank())

Created on 2019-04-20 by the reprex package (v0.2.1)

@thomasp85
Copy link
Member

The short answer is "No - this is not possible"... one workaround would be to add the title using cowplot or patchwork to get the behaviour you want, though I understand why that may feel suboptimal... This is, however, not something we plan to fix anytime soon if ever, as it would require a lot of rethinking about how the plot grid gets constructed and result in possibly breaking changes

@clauswilke
Copy link
Member

I'd like to reopen this issue. It's something that is bugging me a lot also.

Is there a good technical reason why we couldn't just provide different (somehow configurable) l and r arguments in these three gtable_add_grob() calls?

ggplot2/R/plot-build.r

Lines 267 to 277 in b842024

plot_table <- gtable_add_rows(plot_table, subtitle_height, pos = 0)
plot_table <- gtable_add_grob(plot_table, subtitle, name = "subtitle",
t = 1, b = 1, l = min(pans$l), r = max(pans$r), clip = "off")
plot_table <- gtable_add_rows(plot_table, title_height, pos = 0)
plot_table <- gtable_add_grob(plot_table, title, name = "title",
t = 1, b = 1, l = min(pans$l), r = max(pans$r), clip = "off")
plot_table <- gtable_add_rows(plot_table, caption_height, pos = -1)
plot_table <- gtable_add_grob(plot_table, caption, name = "caption",
t = -1, b = -1, l = min(pans$l), r = max(pans$r), clip = "off")

If I change them manually after the fact the resulting plot looks good.

library(tidyverse)

data <- tibble(
  long_name = c("A really really long category name",
                "Another really really long category name",
                "And another really really long category name"),
  short_name = c("A", "B", "C"),
  values = c(200, 300, 500)
)

p <- ggplot(data, aes(x = long_name, y = values)) +
  geom_bar(stat = "identity") +
  coord_flip() +
  labs(title = "My awesome, really long title goes here...") +
  theme(axis.title.x = element_blank(),
        axis.title.y = element_blank())

g <- ggplotGrob(p)
idx <- which(g$layout$name == "title")
g$layout$l[idx] <- 2
g$layout$r[idx] <- 8
grid::grid.newpage()
grid::grid.draw(g)

Created on 2019-08-19 by the reprex package (v0.3.0)

Even just two options (1. title/subtitle/caption covers only the panels, the default; 2. title/subtitle/caption covers the entire plot except margins) would go a long way. This could be made configurable either via new theme settings or maybe via optional arguments to ggtitle().

Is there anything I'm missing?

@clauswilke
Copy link
Member

I've made a PR with an example implementation: #3494.

library(ggplot2)

p <- ggplot(mpg, aes(x = class)) +
  geom_bar() +
  coord_flip() +
  labs(
    title = "SUVs are the most popular",
    subtitle = "Number of cars of different classes in the mpg dataset") +
  theme(axis.title.y = element_blank())

p

p + theme(plot.title.position = "plot")

Created on 2019-08-19 by the reprex package (v0.3.0)

@clauswilke
Copy link
Member

More complex example with multiple panels and legend.

library(ggplot2)

ggplot(mpg, aes(x = class, fill = drv)) +
  geom_bar() +
  facet_wrap(~cyl) +
  coord_flip() +
  labs(
    title = "SUVs are the most popular",
    subtitle = "Number of cars of different classes in the mpg dataset",
    caption = "Subset of the EPA fuel economy data,\nhttp://fueleconomy.gov") +
  theme(
    axis.title.y = element_blank(),
    plot.title.position = "plot"
  )

Created on 2019-08-19 by the reprex package (v0.3.0)

clauswilke added a commit to wilkelab/ggplot2_archive that referenced this issue Aug 26, 2019
clauswilke added a commit that referenced this issue Aug 27, 2019
* add plot.title.position theme element

* add plot.title.position to all themes, add visual test.

* Make separate parameter for caption position. Closes #3252.
@lock
Copy link

lock bot commented Feb 23, 2020

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/

@lock lock bot locked and limited conversation to collaborators Feb 23, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature a feature request or enhancement themes 💃
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants