1

Our organization has a very exacting style book, so I've been tasked with creating a ggplot theme that programmers can use to ensure that their charts and graphs are as close as possible to "official" style.

One of the requirements is that the legend for a graph be below the graph, but vertically stacked, like this:

Example of acceptable pie chart

I've been generating graphics like this in the following way:

pie_theme <- theme(
    text = element_text(family = "Arial", face = "bold", size = 7, color = "black"),
    plot.caption = element_text(hjust = 0, size = 6),
    legend.position = "bottom",
    etc.
    )
    
    p1 <- ggplot(bla bla bla)+geom_bar(bla bla bla)+coord_polar(bla bla bla)
    
    p1+ guides(fill=guide_legend(ncol=1)) +
      pie_theme

Ideally, I'd like to integrate the guides() command into the theme so that programmers don't have to add the guides() every time they output a chart and the legend automatically stacks vertically. But I don't see a theme() attribute that will do that. Any advice?

Thank you!

leviemb
  • 49
  • 6

1 Answers1

3

The + operation for ggplot objects and lists work such that every element of the list is added to the plot seperately. For this to work, you can just wrap the theme and guides in a list, which you can then add just like you would a regular theme.

A word of warning though, if you map a continuous variable to the guide, it will try to pick guide_legend() instead of guide_colorbar(), which is arguably more appropriate, if you use it in this way.

library(ggplot2)

pie_theme <- list(
  theme(
    text = element_text(face = "bold", size = 7, color = "black"),
    plot.caption = element_text(hjust = 0, size = 6),
    legend.position = "bottom"
  ),
  guides(fill = guide_legend(ncol = 1))
)

ggplot(mtcars, aes(x = factor(1), fill = factor(cyl))) +
  geom_bar(width = 1) +
  coord_polar(theta = "y") +
  pie_theme

Created on 2020-12-23 by the reprex package (v0.3.0)

teunbrand
  • 33,645
  • 4
  • 37
  • 63
  • A possible extension to the question: is it possible with a function (instead of predefined `pie_theme`) to only add guides/themes/... if not previously set? For instance, if your `ggplot(...) + geom_bar(...) + coord_polar(...) + themes(legend.position="top") + pie_theme()`, it would not try to duplicate the previously-assigned theme value? – r2evans Dec 23 '20 at 19:05
  • Well, it is probably a lot easier to do `... + pie_theme + theme(legend.position = "top")` instead of the other way around. I'm imagining you could write a custom theme class with its own `ggplot_add()` method that checks for this, however this would be more involved than just switching the order of operations. – teunbrand Dec 23 '20 at 19:11
  • That's what I thought. I was imagining a generic way that includes things included in `scale_*_*` in order to suppress the notes/warnings that `ggplot2` throws with duplicative calls/arguments. Thanks. – r2evans Dec 23 '20 at 19:12
  • 1
    I recall that I've answered a similar question on conditional theme settings here: https://stackoverflow.com/questions/58149562/conditionally-modify-ggplot-theme-based-on-presence-of-facets/ – teunbrand Dec 23 '20 at 19:17