안녕하세요! 오늘은 bar-chart-race(직역하면 막대그래프 경주)를 이용해서 시각화 하는 방법을 알려드리려고 합니다.
예제로 EPL 영국 프리미어 축구 리그 데이터를 활용하여 bar-chart-race 시각화를 해 보도록 하겠습니다.
step1. 필요한 데이터 준비
이번에 사용할 데이터는 영국 프리미어 축구 리그 EPL의 2010년부터 2021년까지의 데이터입니다.
데이터에는 각 팀의 시즌별 순위 및 득점 정보가 나와 있습니다.
데이터는 Kaggle에서 받을 수 있습니다.
여기를 클릭하여 EPL Standings 2010-2021.csv를 받아 주세요 :)
링크를 클릭하면 위와 같은 화면이 나타나는데 다운로드를 클릭하시면 데이터셋이 저장됩니다.
step2. FFmpeg 설치하기
다음으로 bar-chart-race를 구동할 때 필요한 FFmpeg를 설치하여 줍니다.
https://ffmpeg.org/download.html#build-windows
위에 링크를 클릭한 후,
파란 윈도우 아이콘 선택 후 Windows builds from gyan.dev를 클릭하여 줍니다.
그럼 위와 같은 화면이 나타납니다. 최신 버전을 사용하여도 되지만 안정적인 버전을 다운받아보도록 하겠습니다.
ffmpeg-4.4.1-full_build.7z를 클릭하여 다운받아주세요.
다운 받은 압축 파일을 압축 해제해 주세요. 저는 Program Files라는 곳에 파일을 이동시켜 압축해제 하였습니다.
압축 해제한 ffmpeg-4.4.1-full_build 폴더 이름은 ffmpeg으로 변경해 주세요.
그 후 ffmpeg> bin에 ffmpeg.exe, ffplay.exe, ffprobe.exe 가 있으면 준비는 거의 다 되었습니다.
윈도우 검색창에 시스템 환경 변수 편집을 타이핑하고 클릭하여 주세요.
위의 창에서 환경 변수를 클릭하여 줍니다.
user에 대한 사용자 변수 > Path > 편집을 클릭하여 주세요.
새로 만들기 > ffmpeg.exe 가 있는 주소 입력 > 확인을 차례대로 눌러주세요.
그 후 나머지 창들도 확인을 클릭하여 창을 닫아줍니다.
다음으로, windows + R 키를 누른 후 cmd를 입력후 엔터하여 명령 창을 열어 줍니다.
나오는 창에 ffmpeg을 쳤을때 위와 같이 나오면 잘 설치가 되었다는 뜻입니다. :)
step3. bar_chart_race 모듈 다운받기
pip install bar_chart_race
위의 코드를 아나콘다 프롬프트에서 실행해 bar_chart_race를 다운 받습니다.
기본적인 bar_chart_race에는 image label 기능이 없기 때문에 bar_chart_library에 기능이 추가된 파일로 교체하도록 하겠습니다.
https://github.com/andresberejnoi/bar_chart_race/tree/image_labels
위의 사이트에 들어간 후,
Code 클릭 > Download ZIP을 클릭하여 파일을 다운 받은 후 압축을 풀어 줍니다.
bar_chart_race-image_labels > bar_chart_race에서 빨간 박스의 모든 .py파일을 복사해 주세요.
그 후 user > anaconda3 > Lib > site-packages > bar_chart_race 안에 복사한 파일을 아래와 같이 붙여주세요.
드디어 bar_chart_race를 사용하기 위한 모든 준비를 마쳤습니다.
step4. 데이터 전처리하기
처음에 다운받은 EPL Standings 2010-2021.csv를 전처리하여 bar_chart_race에 맞는 데이터로 바꾸어 봅시다.
#필요한 모듈 불러오기
#!pip install bar_chart_race as bcr
import pandas as pd
import numpy as np
import bar_chart_race as bcr
#필요한 데이터 셋 불러오기
# 주의할 점: 주소에 \를 //로 바꿔줄 것!
path = "C://Users//user//Desktop//blog//code//EPL_Standings_2010_2021.csv"
EPL = pd.read_csv(path)
# 요약출력
EPL.head()
파일 주소를 입력 할 때는 \를 //로 바꾸어 주세요. 그대로 복사 붙여넣기 하면 오류가 납니다.
출력:
위와 같이 파일의 내용이 나옵니다. 우리는 여기서 Season, Team, Pts(전체 포인트)만 사용하겠습니다.
# 필요한 데이터만 남기고 지우기
EPL = EPL[['Season','Team','Pts']]
EPL.head()
그러면 위와 같이 3개의 컬럼만 남습니다.
그 후 프리미어 축구 팀을 열로, 점수를 값으로 하여 피봇팅 해 주겠습니다.
#데이터를 알맞은 포맷으로 변형하기 - 피봇팅
df = EPL.pivot_table(values='Pts', index = ['Season'],columns='Team')
df.head()
결과를 보니 NaN값이 많이 있습니다. NaN이 있으면 점수 계산이 안되기 때문에 NaN 값을 0으로 바꾸어 주겠습니다.
# NaN값 0으로 바꾸어 주기
df.fillna(0,inplace=True)
df.sort_values(list(df.columns), inplace=True)
df = df.sort_index()
df.head()
어느 팀이 시간에 따라 제일 잘했는지 시각화하기 위해서는 시즌별 점수가 누적이 되어 나타나야 합니다.
예를 들어, 1시즌이 12점, 2시즌이 25점일 때, 표로는 1시즌 : 12, 2시즌: 12+25 = 37 ... 이런식으로 누적으로 표현되어야 bar_chart_race를 그릴 수 있습니다.
때문에 각 열의 값을 누적값으로 바꾸어 주겠습니다.
# 누적데이터로 각 축구팀의 데이터 값 바꾸기
df.iloc[:,0:-1] = df.iloc[:, 0:-1].cumsum()
df.head()
이렇게 누적 값이 만들어졌습니다.
이 파일에는 37개의 축구 클럽이 있는데 그중 시즌 별로 상위 10위 클럽만 남기고 나머지 팀은 정리하도록 하겠습니다.
# 37개의 클럽 중 시즌 별 top 10 클럽만 남기고 다른 데이터는 지우기
top_10_clubs= set()
for index, row in df.iterrows():
top_10_clubs |= set(row[row>0].sort_values(ascending=False).head(10).index)
df = df[top_10_clubs]
df.head()
대략 20개의 팀으로 줄었습니다.
step 5. bar_chart_race 만들기
위에서 전처리한 데이터를 가지고 bar_chart_race를 그려보겠습니다.
우선 각 팀별 막대 그래프에 이미지를 추가해 주기 위해 지금 작성하고 있는 코드가 있는 폴더 안에 각 축구팀의 이미지를 추가하도록 하겠습니다.
그림 파일은 제가 미리 준비를 하였으니 아래의 파일을 다운받은 후 압출을 풀어 주세요.
이때 주의할 점은 사진 이름이 df 파일에 있는 컬럼 명과 정확히 일치하여야 하고, png 파일이어야 합니다.
그리고 반드시 현재 작성하고 있는 코드와 같은 폴더에 위치시켜 주세요.
#bar chart race 그리기
bcr.bar_chart_race(df = df,
n_bars = 10,
sort='desc',
img_label_folder="bar_image_labels",
steps_per_period = 50,
title = 'TOP 10 EPL clubs(2010-2021)') #)#'TOP 6 TEAM in PL(1992-2017)'
#,filename = 'epl_10_clubs.mp4') #차트 레이스를 동영상으로 저장하고 싶을 때 사용
여기서 n_bars는 화면에 표시할 막대의 갯수, title은 제목, 그리고 파일을 저장하고 싶다면 file='파일이름.mp4'를 작성해 주시면 됩니다. :)
전체 코드
#필요한 모듈 불러오기
#!pip install bar_chart_race as bcr
import pandas as pd
import numpy as np
import bar_chart_race as bcr
#필요한 데이터 셋 불러오기
# 주의할 점: 주소에 \를 //로 바꿔줄 것!
path = "C://Users//user//Desktop//blog//code//EPL_Standings_2010_2021.csv"
EPL = pd.read_csv(path)
# 요약출력
EPL.head()
# 필요한 데이터만 남기고 지우기
EPL = EPL[['Season','Team','Pts']]
EPL.head()
#데이터를 알맞은 포맷으로 변형하기 - 피봇팅
df = EPL.pivot_table(values='Pts', index = ['Season'],columns='Team')
df.head()
# NaN값 0으로 바꾸어 주기
df.fillna(0,inplace=True)
df.sort_values(list(df.columns), inplace=True)
df = df.sort_index()
df.head()
# 누적데이터로 각 축구팀의 데이터 값 바꾸기
df.iloc[:,0:-1] = df.iloc[:, 0:-1].cumsum()
df.head()
# 37개의 클럽 중 시즌 별 top 10 클럽만 남기고 다른 데이터는 지우기
top_10_clubs= set()
for index, row in df.iterrows():
top_10_clubs |= set(row[row>0].sort_values(ascending=False).head(10).index)
df = df[top_10_clubs]
df.head()
#bar chart race 그리기
bcr.bar_chart_race(df = df,
n_bars = 10,
sort='desc',
img_label_folder="bar_image_labels",
steps_per_period = 50,
title = 'TOP 10 EPL clubs(2010-2021)') #)#'TOP 6 TEAM in PL(1992-2017)'
#,filename = 'epl_10_clubs.mp4') #차트 레이스를 동영상으로 저장하고 싶을 때 사용
코드 파일
마무리
오늘 이렇게 움직이는 그래프를 그려 보았는데요 한국어 자료가 거의 없어 여러 외국 사이트를 참고하고
bar_chart_race를 사용하기 위한 설치 작업이 많아 시간이 오래 걸렸네요.
그래도 만들고 결과를 보니 재밌었습니다.
다음에는 API를 이용하여 코로나 확진자 관련 그래프를 그려도 좋을 것 같다는 생각이 듭니다 ㅎㅎ
질문이나 좋은 의견이 있으면 댓글로 남겨주세요 :-)
++22.07.04 ffmpeg 설치방법 수정 완료.
'시각화(Visualization)' 카테고리의 다른 글
[python] CCTV,가로등 위치를 folium을 사용하여 clustering 시각화하기 (4) | 2021.11.17 |
---|---|
[python] folium을 이용하여 CCTV 위치 시각화하기 (3) | 2021.11.15 |
[python] 네이버 블로그 크롤링 결과로 WordCloud 시각화하기 (5) | 2021.11.10 |
[python] 공공데이터 코로나 확진자 데이터로 bar_chart_race 시각화하기 (3) | 2021.11.08 |
[python] matplotlib을 이용하여 3D 막대 그래프 그리기 (0) | 2021.10.27 |