1

Background

I took the data from a Stephen Few Example and wanted to add labels to each of the bars to pull the legend from the side of the graphic.

The code in the "Hack Graphic" section got me there because I couldn't get the position_dodge() to work with the text labels.

Load Data

library(tidyverse)
library(forcats)

### Build data from his table
candidates <- tibble::tibble(`Rating Areas` = c("Experience", 
"Communication", "Friendliness", "Subject matter knowledge", "Presentation", 
"Education"), `Karen Fortou` = c(4,3.5, 4, 4, 3, 3.5), `Mike Rafun` = c(4.5, 
2, 2, 5, 1.5, 4.5), `Jack Nymbul` = c(2.5, 5, 4.5, 2.5, 2.75, 2)) %>%
gather("Candidates", "Score", -`Rating Areas`) 

# The totals for each candidate
totals <- candidates %>% group_by(Candidates) %>% summarise(Score = 
sum(Score))

Hack Graphic

Notice how I used manually created x-axis values (x = c(seq(.6,1.35, by = .15), seq(1.6,2.35, by = .15), seq(2.6,3.35, by = .15))) to place the labels instead of using position = position_dodge() as described in this post.

candidates %>% 
  ggplot(aes(x = fct_reorder(Candidates, Score), y = Score)) +
  geom_col(data = totals, alpha = .45) +
  geom_col(aes(fill = `Rating Areas`), position = position_dodge(.9), color = "black", 
           show.legend = FALSE) +
  geom_text(label = rep(c("Experience", "Communication", "Friendliness", 
           "Subject matter knowledge", "Presentation", "Education"),3), 
            x = c(seq(.6,1.35, by = .15), seq(1.6,2.35, by = .15), 
            seq(2.6,3.35, by = .15)), y = 5.1, angle = 90, color = "black", 
            hjust = "left", size = 4, fontface = "bold") +
  scale_fill_brewer(type = "qual") + 
  scale_y_continuous(breaks = seq(0, 25, by = 2)) +
  theme_bw() + 
  labs(x = "\nCandidates", y = "Rating Score") +
  theme(axis.text.x = element_text(size = 14, color = "black"), legend.text = element_text(size = 14),
    legend.title = element_text(size = 15), axis.title = element_text(size = 15))

Graphic Code that doesn't work

When I follow the example from the previous Stack answer using geom_text(aes(label =Rating Areas), position = position_dodge(width = 0.9), angle = 90, color = "black", hjust = "left", size = 4, fontface = "bold") it does not spread the labels out ever each bar.

I must be missing something obvious. Please help with how to get position_dodge() to work with this example?

candidates %>% 
  ggplot(aes(x = fct_reorder(Candidates, Score), y = Score)) +
  geom_col(data = totals, alpha = .45) +
  geom_col(aes(fill = `Rating Areas`), position = position_dodge(.9), color = "black", show.legend = FALSE) +
  geom_text(aes(label = `Rating Areas`), position = position_dodge(width = 0.9), angle = 90, color = "black", hjust = "left", size = 4, fontface = "bold") +
  scale_fill_brewer(type = "qual") + 
  scale_y_continuous(breaks = seq(0, 25, by = 2)) +
  theme_bw() + 
  labs(x = "\nCandidates", y = "Rating Score") +
  theme(axis.text.x = element_text(size = 14, color = "black"), legend.text = element_text(size = 14), legend.title = element_text(size = 15), axis.title = element_text(size = 15))
hathawayj
  • 230
  • 1
  • 8

1 Answers1

1

I think you need to have the same mapping for both geom_col and geom_text. You can add fill = Rating Areas to the aesthetics of geom_text. You will get a warning though.

candidates %>% 
    ggplot(aes(x = fct_reorder(Candidates, Score), y = Score)) +
    geom_col(data = totals, alpha = .45) +
    geom_col(aes(fill = `Rating Areas`), position = position_dodge(.9), color = "black", show.legend = FALSE) +
    geom_text(aes(fill = `Rating Areas`, label = `Rating Areas`), position = position_dodge(width = 0.9), angle = 90, color = "black", hjust = "left", size = 4, fontface = "bold") +
    scale_fill_brewer(type = "qual") + 
    scale_y_continuous(breaks = seq(0, 25, by = 2)) +
    theme_bw() + 
    labs(x = "\nCandidates", y = "Rating Score") +
    theme(axis.text.x = element_text(size = 14, color = "black"), legend.text = element_text(size = 14), legend.title = element_text(size = 15), axis.title = element_text(size = 15))

Edit: Here's a way to do it without the warning:

candidates %>% 
    ggplot(aes(x = fct_reorder(Candidates, Score), y = Score, fill = `Rating Areas`)) +
    geom_col(data = totals, aes(x = fct_reorder(Candidates, Score), y = Score), alpha = .45, inherit.aes = FALSE) +
    geom_col(position = position_dodge(.9), color = "black", show.legend = FALSE) +
    geom_text(aes(label = `Rating Areas`), position = position_dodge(width = 0.9), angle = 90, color = "black", hjust = "left", size = 4, fontface = "bold") +
    scale_fill_brewer(type = "qual") + 
    scale_y_continuous(breaks = seq(0, 25, by = 2)) +
    theme_bw() + 
    labs(x = "\nCandidates", y = "Rating Score") +
    theme(axis.text.x = element_text(size = 14, color = "black"), legend.text = element_text(size = 14), legend.title = element_text(size = 15), axis.title = element_text(size = 15))
Hallie Swan
  • 2,714
  • 1
  • 15
  • 23