Reputation: 61
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
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
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
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