- R을 이용한 축구 데이터 분석 (MAP)2023년 06월 11일 17시 38분 47초에 업로드 된 글입니다.작성자: r-code-for-data-analysis
오늘 새벽 유럽 챔피언스 결승 경기로 많은 사람들이 아침잠을 설쳤을 것이다.
R을 이용하여 축구 데이터 분석을 할 수 있는 블로그를 발견하여 약간 변형하여 따라 해 보았다.
참조 블로그
https://towardsdatascience.com/how-to-visualize-football-data-using-r-ee963b3a0ba4
위 예시는 옛날 경기라 20/21 라리가의 메시를 중심으로 데이터 분석을 다시 진행하였다.
필요한 패키지 설치 및 라이브러리 불러오기# 필요한 라이브러리 설치 install.packages('devtools') devtools::install_github("statsbomb/SDMTools") devtools::install_github("statsbomb/StatsBombR") install.packages('tidyverse') install.packages('ggsoccer' ) # 라이브러리 로드 library(tidyverse) library(StatsBombR) library(ggsoccer)
축구 오픈 데이터 깃허브 주소는 아래와 같다.
https://github.com/statsbomb/open-data
데이터 불러오기 (20/21년 스페인 라리가 바르셀로나와 셀타 비고 경기)# 사용 가능한 모든 대회 검색 Comp <- FreeCompetitions() # 대회 필터링 ucl_german <- Comp %>% filter(competition_id==11 & season_name=="2020/2021") # Retrieve all available matches matches <- FreeMatches(ucl_german) # Retrieve the event data events_df <- get.matchFree(matches) # 데이터 전처리 clean_df <- allclean(events_df)
메시의 패스 데이터 불러와서 시각화 하기
# 패스 맵 messi_pass <- clean_df %>% filter(player.name == 'Lionel Andrés Messi Cuccittini') %>% filter(type.name == 'Pass') ggplot(messi_pass) + annotate_pitch(dimensions = pitch_statsbomb) + geom_segment(aes(x=location.x, y=location.y, xend=pass.end_location.x, yend=pass.end_location.y), colour = "coral", arrow = arrow(length = unit(0.15, "cm"), type = "closed")) + labs(title="Lionel Andrés Messi's Passing Map", subtitle="La Liga 20/21", caption=" 데이터 소스: StatsBomb")+ theme( plot.background = element_rect(fill='#021e3f', color='#021e3f'), panel.background = element_rect(fill='#021e3f', color='#021e3f'), plot.title = element_text(hjust=0.5, vjust=0, size=14), plot.subtitle = element_text(hjust=0.5, vjust=0, size=8), plot.caption = element_text(hjust=0.5), text = element_text(family="Geneva", color='white'), panel.grid = element_blank(), axis.title = element_blank(), axis.text = element_blank() )
각 팀의 슛 맵을 그려보자
barcelona_shot <- clean_df %>% filter(type.name == 'Shot') %>% filter(team.name == 'Barcelona') %>% select(player.name, location.x, location.y, shot.end_location.x, shot.end_location.y, shot.statsbomb_xg) celta_shot <- clean_df %>% filter(type.name == 'Shot') %>% filter(team.name == 'Celta Vigo') %>% select(player.name, location.x, location.y, shot.end_location.x, shot.end_location.y, shot.statsbomb_xg) ggplot() + annotate_pitch(dimensions = pitch_statsbomb, colour='white', fill='#021e3f') + geom_point(data=barcelona_shot, aes(x=location.x, y=location.y, size=shot.statsbomb_xg) , color="red") + geom_point(data=celta_shot, aes(x=120-location.x, y=location.y, size=shot.statsbomb_xg), color="yellow") + labs( title= "Barcelona vs Celta Vigo", subtitle = "Shots Map | La Liga 20/21", caption="Data Source: StatsBomb" ) + theme( plot.background = element_rect(fill='#021e3f', color='#021e3f'), panel.background = element_rect(fill='#021e3f', color='#021e3f'), axis.title.x = element_blank(), axis.title.y = element_blank(), axis.text.x = element_blank(), axis.text.y = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), text = element_text(family="Geneva", color='white'), plot.title = element_text(hjust=0.5, vjust=0, size=14), plot.subtitle = element_text(hjust=0.5, vjust=0, size=8), plot.caption = element_text(hjust=0.5), plot.margin = margin(2, 2, 2, 2), legend.position = "none" )
바르셀로나가 셀타비고를 압박하는 pressure map 그려보기# Pressure Heat Map barcelona_pressure <- clean_df %>% filter(team.name == 'Barcelona') %>% filter(type.name == 'Pressure') ggplot(barcelona_pressure)+ annotate_pitch(dimensions = pitch_statsbomb, fill='#021e3f', colour='#DDDDDD') + geom_density2d_filled(aes(location.x, location.y, fill=..level..), alpha=0.4, contour_var='ndensity') + scale_x_continuous(c(0, 120)) + scale_y_continuous(c(0, 80)) + labs(title="Barcelona's Pressure Heat Map", subtitle="La Liga 20/21", caption=" 데이터 소스: StatsBomb")+ theme_minimal() + theme( plot.background = element_rect(fill='#021e3f', color='#021e3f'), panel.background = element_rect(fill='#021e3f', color='#021e3f'), plot.title = element_text(hjust=0.5, vjust=0, size=14), plot.subtitle = element_text(hjust=0.5, vjust=0, size=8), plot.caption = element_text(hjust=0.5), text = element_text(family="Geneva", color='white'), panel.grid = element_blank(), axis.title = element_blank(), axis.text = element_blank(), legend.position = "none" )
앞으로 스포츠 데이터 분석 분야는 더 많은 수요가 있지 않을까?
728x90반응형'데이터 분석' 카테고리의 다른 글
[머신러닝 모델링을 통한 타이타닉 데이터 분석] (0) 2023.07.09 [R을 이용한 타이타닉 생존자 예측] (0) 2023.07.09 점탄성 특성 분석 (ANOVA, PCA분석) (0) 2023.05.30 [Machine Learning] 여러가지 모델 한번에 적용해서 분석하기 (0) 2023.05.29 Multi slit 구조에서 빛의 회절을 시뮤레이션 해 보기 (0) 2023.05.29 댓글