Emre Toros
Emre Toros

Reputation: 61

How can I connect all of the points with each other of a scatter plot created by geom_point?

I am trying to plot a pass network on a football pitch. After the cleaning the data it looks like this

structure(list(surname_sender = c("Ajite", "Dikmen", "Dikmen", 
"Dikmen", "Dikmen", "Jylmaz", "Jylmaz", "Jylmaz", "Kandejas", 
"Kandejas", "Kandejas", "Kandejas", "Kizildag", "Kizildag", "Kizildag", 
"Kizildag", "Kizildag", "Motta", "Motta", "Motta", "Motta", "Motta", 
"Motta", "Nordfel'dt", "Nordfel'dt", "Poloma", "Sio", "Ture", 
"Ture", "Ture", "Ture", "Ture", "Uhansson", "Uhansson", "Uhansson", 
"Uhansson"), surname_receiver = c("Poloma", "Kizildag", "Poloma", 
"Ture", "Uhansson", "Kandejas", "Poloma", "Uhansson", "Motta", 
"Nordfel'dt", "Ture", "Uhansson", "Dikmen", "Motta", "Nordfel'dt", 
"Ture", "Uhansson", "Dikmen", "Jylmaz", "Kizildag", "Poloma", 
"Ture", "Uhansson", "Ture", "Uhansson", "Ture", "Dikmen", "Jylmaz", 
"Kandejas", "Kizildag", "Motta", "Poloma", "Kandejas", "Kizildag", 
"Sio", "Uhansson"), passes = c(4L, 4L, 4L, 4L, 6L, 4L, 5L, 4L, 
4L, 5L, 4L, 9L, 10L, 6L, 4L, 5L, 8L, 5L, 4L, 6L, 4L, 4L, 5L, 
4L, 6L, 13L, 5L, 5L, 4L, 9L, 8L, 7L, 14L, 8L, 5L, 4L), mean_passer_x = c(64.7, 
44.41875, 44.41875, 44.41875, 44.41875, 68.725, 68.725, 68.725, 
75.2919444444445, 75.2919444444445, 75.2919444444445, 75.2919444444445, 
29.5423333333333, 29.5423333333333, 29.5423333333333, 29.5423333333333, 
29.5423333333333, 44.31, 44.31, 44.31, 44.31, 44.31, 44.31, 8.60416666666667, 
8.60416666666667, 58.6384615384615, 52.46, 38.2090952380952, 
38.2090952380952, 38.2090952380952, 38.2090952380952, 38.2090952380952, 
51.7642857142857, 51.7642857142857, 51.7642857142857, 51.7642857142857
), mean_passer_y = c(46.9, 38.7083333333333, 38.7083333333333, 
38.7083333333333, 38.7083333333333, 35.3533333333333, 35.3533333333333, 
35.3533333333333, 10.7833333333333, 10.7833333333333, 10.7833333333333, 
10.7833333333333, 23.6785, 23.6785, 23.6785, 23.6785, 23.6785, 
34.6552777777778, 34.6552777777778, 34.6552777777778, 34.6552777777778, 
34.6552777777778, 34.6552777777778, 32.2166666666667, 32.2166666666667, 
65.3, 25.7, 46.9388571428571, 46.9388571428571, 46.9388571428571, 
46.9388571428571, 46.9388571428571, 7.25, 7.25, 7.25, 7.25)), row.names = c(NA, 
-36L), class = c("tbl_df", "tbl", "data.frame"))

The solution that I have found seems quite boring and silly :)

library(tidyverse)
library(ggsoccer)
library(ggrepel)

 ggplot(df2, aes(mean_passer_x, mean_passer_y)) +
   annotate_pitch(dimensions = pitch_custom) +
  geom_point(color = "red") +
  geom_line(aes(mean_passer_x, mean_passer_y, size = passes, alpha = 0.2),
              data = . %>% filter(surname_sender %in% c("Motta", "Kizildag"))) +
  geom_line(aes(mean_passer_x, mean_passer_y, size = passes, alpha = 0.2),
            data = . %>% filter(surname_sender %in% c("Motta", "Uhansson"))) +
  geom_line(aes(mean_passer_x, mean_passer_y, size = passes, alpha = 0.2),
            data = . %>% filter(surname_sender %in% c("Motta", "Ture"))) +
  geom_line(aes(mean_passer_x, mean_passer_y, size = passes, alpha = 0.2),
            data = . %>% filter(surname_sender %in% c("Motta", "Sio"))) +
  geom_line(aes(mean_passer_x, mean_passer_y, size = passes, alpha = 0.2),
            data = . %>% filter(surname_sender %in% c("Motta", "Dikmen"))) +
  geom_line(aes(mean_passer_x, mean_passer_y, size = passes, alpha = 0.2),
            data = . %>% filter(surname_sender %in% c("Motta", "Kandejas"))) +
  geom_line(aes(mean_passer_x, mean_passer_y, size = passes, alpha = 0.2),
            data = . %>% filter(surname_sender %in% c("Motta", "Jylmaz"))) +
  geom_line(aes(mean_passer_x, mean_passer_y, size = passes, color= "red", alpha = 0.2),
            data = . %>% filter(surname_sender %in% c("Kizildag", "Ture"))) +
  geom_line(aes(mean_passer_x, mean_passer_y, size = passes, color= "red", alpha = 0.2),
            data = . %>% filter(surname_sender %in% c("Nordfel'dt", "Ture"))) +
  geom_line(aes(mean_passer_x, mean_passer_y, size = passes, color= "red", alpha = 0.2),
            data = . %>% filter(surname_sender %in% c("Nordfel'dt", "Kizildag"))) +
  geom_text(aes(label = surname_sender) ) +
  theme_pitch() 

The end result is

enter image description here

All I want to do is to connect all of the points(players) with each other by lines and define the line size according to the number of passes.

Thanks a lot

Upvotes: 1

Views: 199

Answers (1)

stefan
stefan

Reputation: 123818

Not completely sure about your final result. However, as far as I get it your data needs some additional wrangling before you can plot your passing network. The issue is that each row of your df contains only the position of the "sender" but not of the receiver. Therefore

  1. I first extracted the names and (mean) positions of all players
  2. I join the dataset with the positions back to your original df where I join on the receiving players name. As a result each row now contains both the position of the sending and the receiving player.
  3. After doing so you can plot your network easily by making use of geom_segment and map the number of passes on size. Additionally I mapped the surname_receiver on color to make the direction of passes visible.
library(ggplot2)
library(ggsoccer)
library(ggrepel)
library(dplyr)

pos_player <- df2 %>% 
  select(name = surname_sender, pos_x = mean_passer_x, pos_y = mean_passer_y) %>% 
  distinct()

df2 %>% 
  left_join(pos_player, by = c("surname_receiver" = "name")) %>% 
  group_by(surname_sender) %>% 
  mutate(is_label = row_number() == 1) %>% 
  arrange(desc(passes)) %>% 
  ggplot(aes(x = mean_passer_x, y = mean_passer_y)) +
  annotate_pitch() +
  geom_segment(aes(xend = pos_x, yend = pos_y, size = passes, color = surname_sender), alpha = 0.5) +
  geom_point(color = "red") +
  ggrepel::geom_text_repel(aes(label = ifelse(is_label, surname_sender, "")) ) +
  scale_color_brewer(type = "qual", palette = "Set3") +
  theme_pitch()

Upvotes: 3

Related Questions