0

I'm trying to plot Likert-scale data on a divergent stacked bar chart with ggplot2. The legend is positioned horizontally at the bottom to match the order of the bars.

library(tidyverse)
library(hrbrthemes)

# Sample data
data <- tibble(
        item = rep(c("A", "B", "C", "D", "E"), each = 5),
        resp = rep(c("Strongly disagree", "Disagree", "Neither agree nor disagree", "Agree", "Strongly agree"), 5) %>% 
            factor(head(., 5), ordered = T),
        count = sample(1:10, 25, replace = T)) %>% 
    mutate(count = if_else(resp == "Neither agree nor disagree", count/2, as.double(count)))

# Divergent stacked bar chart
data %>% 
    ggplot(aes(item, count, fill = resp, order = resp)) +
    geom_col(data = filter(data, !(resp %in% c("Strongly disagree", "Disagree"))),
                     position = position_stack(reverse = T)) +
    geom_col(aes(y = -count),
                     filter(data, !(resp %in% c("Agree", "Strongly agree")))) +
    scale_fill_brewer(palette = "RdBu", drop = F) +
    labs(y = NULL) +
    coord_flip() +
    theme_ipsum_rc() +
    theme(legend.position="bottom",
          legend.spacing.x = unit(0.1, "cm"), # reduces margin around text, but not the right spacing
          legend.text = element_text(margin = margin(0,0,0,0)), # no effect
          legend.margin=margin(c(0,0,0,0)))                     # no effect

I'm using hrbrthemes::theme_ipsum_rc(), which I'd really like to keep using.

But the spacing between the legend items seems to be very large, and proportional to the text's length:

ggplot

I have tried various theme() settings to attempt to reduce the spacing (see code), but I can't seem to find the source of this text-dependent spacing.

EDIT: As @chemdork123 & @marek-fiołka noted, it seems to come from the ggplot theme theme_ipsum_rc(). I edited the question title, text, code and graph to reflect this.

iNyar
  • 1,916
  • 1
  • 17
  • 31
  • 1
    OP, when I run your code, there's no spacing issue on the legend for me. I fiddled a bunch with the viewport size, so it doesn't appear to be a scaling issue either. Do you have other packages loaded? Try restarting a new session and only loading `ggplot2`, `tidyr` and `dplyr` or the `tidyverse` and see if you still have the same issue. – chemdork123 Sep 01 '21 at 19:45
  • OK, then it must be because I had loaded `library(hrbrthemes)` and `theme_set(theme_ipsum_rc())` before (I thought it was reset by `+ theme_gray()` but it seems some stuff was left in place). It must come from `theme_ipsum_rc()` then. Yet, I still don't know where it originates from. – iNyar Sep 01 '21 at 20:30
  • Note: I edited the question accordingly. – iNyar Sep 01 '21 at 20:44
  • 1
    Hm... I've loaded the theme and still don't see the spacing you do. What version of R are you using? I have `R` version 4.0.2, `tidyverse` 1.3.0 loaded, and `hrbrthemes` 0.8.0. – chemdork123 Sep 02 '21 at 01:17
  • Wow. You're right. I just restarted R with a clean session, only `tidyverse` and `hrbrthemes` and there's no spacing. I'm going to try to find out which other package/theme is causing it! – iNyar Sep 02 '21 at 01:47
  • 1
    OK! I found the culprit! It was `showtext::showtext_auto()` which was causing this weird spacing. I don't really understand why (and I also don't get why `hrbrthemes` fonts such as _Roboto Condensed_ were suddenly working without needing `showtext` at all). But thanks for helping me realize this! – iNyar Sep 02 '21 at 01:54

2 Answers2

1

Thanks to @chemdork123, I realized that it was actually not caused by ggplot2 nor by hrbrthemes.

It seems the culprit for this weird spacing was having loaded

library(showtext)
showtext_auto()

to be able to use special fonts (such as Roboto Condensed used by theme_ipsum_rc()).

Stopping it with showtext_end() actually solved the problem and removed the unwanted spacing between legend items.

iNyar
  • 1,916
  • 1
  • 17
  • 31
  • 1
    That's great to hear, OP! Hopefully this question is useful for anyone else who encounters some odd spacing when this inevitably happens to someone else :) – chemdork123 Sep 02 '21 at 02:10
0

For me, your code gave this result

library(tidyverse)
# Sample data
data <- tibble(
  item = rep(c("A", "B", "C", "D", "E"), each = 5),
  resp = rep(c("Strongly disagree", "Disagree", "Neither agree nor disagree", "Agree", "Strongly agree"), 5) %>% 
    factor(head(., 5), ordered = T),
  count = sample(1:10, 25, replace = T)) %>% 
  mutate(count = if_else(resp == "Neither agree nor disagree", count/2, as.double(count)))

# Divergent stacked bar chart
data %>% 
  ggplot(aes(item, count, fill = resp, order = resp)) +
  geom_col(data = filter(data, !(resp %in% c("Strongly disagree", "Disagree"))),
           position = position_stack(reverse = T)) +
  geom_col(aes(y = -count),
           filter(data, !(resp %in% c("Agree", "Strongly agree")))) +
  scale_fill_brewer(palette = "RdBu", drop = F) +
  labs(y = NULL) +
  coord_flip() +
  theme(legend.position="bottom")

enter image description here

Maybe you have obsolete versions of your packages. My tidyverse package is version 1.3.1

Marek Fiołka
  • 4,825
  • 1
  • 5
  • 20
  • Thanks for your answer. It seems to come for another loaded theme. I edited the question accordingly to try to identify the source of the problem. – iNyar Sep 01 '21 at 20:45