Bren85
Bren85

Reputation: 63

Adding a legend to ggplot

I have the below dataset;

Player Goals Shots
Regan Charles-Cook 10 32
Tony Watt 9 36
Bruce Anderson 8 26
Liam Boyce 8 44
Kyogo Furuhashi 8 31
Alfredo Morelos 8 80
Christian Ramirez 8 41
Liel Abada 7 57
Martin Boyle 7 43
Kevin van Veen 7 45

I am attempting a dumbbell chart and so far have the following code;

library(tidyverse)
library(ggplot2)
library(ggalt)

theme_set(theme_bw())

read_excel("SPL_Goals.xlsx")

data <- read_excel("SPL_Goals.xlsx")

data %>%
  #the below code sets out the initial plot template without the data
  ggplot(aes(x= Goals, xend = Shots, y= Player)) +
  #below code inputs the data viz on to the plot
  geom_dumbbell(
    size = 1.5, color = "black", size_x = 10,   #size=1.5 dictates black line size
    size_xend = 3, colour_x = "green",
    colour_xend = "red") +
  labs(
    title = "Scotland; Goals v Shots",           #add title
    subtitle = "Top 10; Matchday 22",                         #add subtitle
    x = "Total", y = "Player"
  )+
  geom_text(aes(label = Goals))

This produces the below chart; enter image description here

My query is how do I order the chart so Goals (the green circle) is ascending and also add a legend to show Goals (green) and Shots (red)? I have tried mutate, reorder and fct_reorder but I am doing something wrong as none of these are working.

Upvotes: 1

Views: 104

Answers (1)

Konrad Rudolph
Konrad Rudolph

Reputation: 545488

To change the ordering of the y-axis, you need to reorder your y-axis variable based on the value that you want to order by. In your case, this means reordering Player based on Goals:

data %>% mutate(Player = reorder(Player, Goals) %>% …

Next, creating a manual legend for ggdumbell doesn’t seem possible, or at least it isn’t obvious to me how. However, if you draw the chart manually, you can add a manual legend. This requires several things:

  1. Create the dumbbell shape manually by plotting a geom_segment and two geom_points.
  2. Creating an aes for the colour, which will get mapped into the legend
  3. Create a manual color scale which we use to translate the mapping into actual colours, and to draw the legend.

Putting all that together:

data %>%
  mutate(Player = reorder(Player, Goals)) %>%
  ggplot(aes(x = Goals, y = Player)) +
  geom_segment(aes(xend = Shots, yend = Player), color = "black", size = 1.5) +
  geom_point(aes(color = "Goals"), size = 10) +
  geom_point(aes(x = Shots, color = "Shots"), size = 3) +
  geom_text(aes(label = Goals), color = "black") +
  scale_color_manual(
    values = c(Goals = "green", Shots = "red"),
    guide = guide_legend(title = "", override.aes = list(size = 3))
  ) +
  labs(
    title = "Scotland; Goals v Shots",
    subtitle = "Top 10; Matchday 22",
    x = "Total", y = "Player"
  )

We use override.aes to specify a fixed size for the points inside the legend. Without this, ‘ggplot2’ would overlay two points of different sizes. We also set the title of the legend to "" because the default title would be “colour”, and a title doesn’t seem necessary here.

first

I’ve also used theme_set(theme_bw() + theme(legend.position = "bottom") to generate the image above.

The above is still ordered slightly weirdly, because for players with the same number of goal shots the ordering is still arbitrary. I would probably order those players by (descending) attempted goal shots. That is, it’s better for a player to have scored many goals with the least attempts.

Unfortunately reorder doesn’t support such an ordering directly. Instead, we need to resort to arrangeing the entire table and then reorder players by their row number:

data %>%
  arrange(Goals, -Shots) %>%
  mutate(Player = reorder(Player, row_number())) %>%
  ggplot(aes(x = Goals, y = Player)) +
  geom_segment(aes(xend = Shots, yend = Player), color = "black", size = 1.5) +
  geom_point(aes(color = "Goals"), size = 10) +
  geom_point(aes(x = Shots, color = "Shots"), size = 3) +
  geom_text(aes(label = Goals), color = "black") +
  scale_color_manual(
    values = c(Goals = "green", Shots = "red"),
    guide = guide_legend(title = "", override.aes = list(size = 3))
  ) +
  labs(
    title = "Scotland; Goals v Shots",
    subtitle = "Top 10; Matchday 22",
    x = "Total", y = "Player"
  )

second

Upvotes: 2

Related Questions