[OPGG] 롤 나의 게임 정보 불러오기

Updated:

1. 나의 게임 정보

그동안 배웠던 내용을 토대로 나의 롤 플레이 정보를 불러와 여러 지표를 확인할 것이다.

# ploty 패키지 설치
# !pip install plotly
import pandas as pd
import numpy as np
import requests
import time

# 시각화 패키지
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots

# 경고창 무시
import warnings
warnings.filterwarnings("ignore")

1.1 accountId

# API 키 갱신 확인 후 사용
api_key = ##직접 입력##

# 소환사 이름
summonerName = "Romg2"
summoner_url = f"https://kr.api.riotgames.com/lol/summoner/v4/summoners/by-name/{summonerName}?api_key={api_key}"
summoner_r = requests.get(summoner_url)

# 나의 accountId
encryptedAccountId = summoner_r.json()['accountId']
  • 개발자 홈페이지에 대한 이해가 조금 필요한데 여기선 소환사 이름을 통해 해당 유저의 accountId를 불러왔다.

1.2 gameId stack

beginIndex = 0

# 매치 정보 (지수표현으로 나오지 않는지 확인)
my_matchid = np.array([], dtype=int)

while True:
    match_url = f"https://kr.api.riotgames.com/lol/match/v4/matchlists/by-account/{encryptedAccountId}?api_key={api_key}&beginIndex={beginIndex}"
    match_r = requests.get(match_url)
    
    # stop 조건: 불러온 json 파일의 length
    if len(pd.json_normalize(match_r.json()['matches'])) == 0:
        break
    
    # 한번에 100의 매치 정보
    temp_matchid = pd.DataFrame(match_r.json()['matches'])["gameId"]
    
    # gameid stack
    my_matchid = np.concatenate([my_matchid, temp_matchid.values])
    
    # start index 변경
    beginIndex += 100
    
    # RATE LIMITS 피하기
    time.sleep(1)
  • 앞서 얻은 accountId를 URL에 입력하여 해당 accountId가 플레이한 matchid를 가져오는 과정이다.

  • 여기서 전체 플레이를 불러오기 위해 while문을 사용하여 더 이상 불러올 수 없으면 멈춘다.

  • 아래는 라이엇에서 개인용 API KEY로 불러올 수 있는 LIMIT에 대한 설명이다.

RATE LIMITS

20 requests every 1 seconds(s)
100 requests every 2 minutes(s)
  • 이에 따라 time.sleep()을 설정해두었다.

1.3 match information stack

my_game = pd.DataFrame()

for i in my_matchid:
    gameid = i

    game_url = f"https://kr.api.riotgames.com/lol/match/v4/matches/{gameid}?api_key={api_key}"
    game_r = requests.get(game_url)
    
    # 10명의 대전 정보
    temp_game = pd.json_normalize(game_r.json()['participants'])
    
    # 나의 participantid 확인
    summoner_lst = pd.json_normalize(game_r.json()['participantIdentities'])
    me = summoner_lst[summoner_lst['player.accountId'] == encryptedAccountId]
    
    # 나의 대전 정보
    temp_game = temp_game[temp_game['participantId'] == int(me['participantId'])]
    
    # 추가 정보 (게임 종류, 게임 시간)
    temp_game["subType"] = game_r.json()["queueId"]
    temp_game["gameLength"] = game_r.json()["gameDuration"]
    
    # 대전 정보 stack
    my_game = my_game.append(temp_game)
    
    # RATE LIMITS 피하기
    time.sleep(1)
  • 이제 각 matchid에 대한 게임 정보를 데이터 프레임으로 만드는 과정이다.

  • 게임 판수가 많다면 시간이 매우 오래걸린다.

  • 한 게임당 1초의 sleep을 주었으니 2,000게임이면 대략 30분 정도 걸릴 것이다.

  • 불러오는 과정에서 게임 종류나 시간은 participants에 포함된 데이터가 아니어서 다시 돌렸다.

  • 처음부터 원하는 컬럼에 대해 파악하고 테스트 한 후 잘 짜두어야 한다.

# # 시간이 오래걸리므로 csv로 저장
# my_game.to_csv(f"Day02_02_{summonerName}_log.csv", index=False)
  • 시간이 오래 걸리기에 csv 파일로 저장하였다.

2. 데이터 전처리

2.1 데이터 로드

# 저장한 csv load
my_game2 = pd.read_csv(f"Day02_02_{summonerName}_log.csv")
my_game2.head()
participantId teamId championId spell1Id spell2Id stats.participantId stats.win stats.item0 stats.item1 stats.item2 ... timeline.goldPerMinDeltas.20-30 timeline.csDiffPerMinDeltas.30-end timeline.csDiffPerMinDeltas.20-30 timeline.xpDiffPerMinDeltas.30-end timeline.xpDiffPerMinDeltas.20-30 timeline.damageTakenPerMinDeltas.30-end timeline.damageTakenPerMinDeltas.20-30 timeline.damageTakenDiffPerMinDeltas.30-end timeline.damageTakenDiffPerMinDeltas.20-30 highestAchievedSeasonTier
0 10 200 126 32 4 10 False 3070 1036 1036 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1 4 100 164 32 4 4 False 3143 6630 3111 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 5 100 517 32 4 5 False 3066 6656 3158 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 10 200 115 7 4 10 False 3157 4637 6653 ... 446.0 0.05 1.15 -148.5 -49.65 1081.5 721.4 282.45 -102.45 NaN
4 9 200 163 7 4 9 True 1056 2003 0 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

5 rows × 143 columns

  • 드디어 나의 플레이 정보를 위와 같이 확인 할 수 있다.

  • 컬럼이 너무 많으니 원하는 컬럼만 사용해보자.

# 특정 컬럼만 사용
col_lst = ["subType", "teamId", "gameLength", "championId", 
           "stats.win", "stats.kills", "stats.deaths", "stats.assists", 
           "timeline.lane"]

my_game3 = my_game2[col_lst]

# 랭크(420)만 사용
my_game3 = my_game3[my_game3["subType"].isin([420])]
print(my_game3.shape)
(871, 9)
my_game3.head()
subType teamId gameLength championId stats.win stats.kills stats.deaths stats.assists timeline.lane
3 420 200 2482 115 False 14 10 15 BOTTOM
4 420 200 192 163 True 0 1 0 NONE
11 420 100 1402 412 True 1 3 8 BOTTOM
12 420 100 1712 163 True 4 6 8 MIDDLE
13 420 100 1322 50 True 4 4 6 MIDDLE
  • 총 871판의 랭크 게임 데이터 정보에 대해 일부 컬럼을 확인하였다.
my_game3.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 871 entries, 3 to 1499
Data columns (total 9 columns):
 #   Column         Non-Null Count  Dtype 
---  ------         --------------  ----- 
 0   subType        871 non-null    int64 
 1   teamId         871 non-null    int64 
 2   gameLength     871 non-null    int64 
 3   championId     871 non-null    int64 
 4   stats.win      871 non-null    bool  
 5   stats.kills    871 non-null    int64 
 6   stats.deaths   871 non-null    int64 
 7   stats.assists  871 non-null    int64 
 8   timeline.lane  871 non-null    object
dtypes: bool(1), int64(7), object(1)
memory usage: 62.1+ KB
  • 컬럼별 데이터 타입 확인
my_game3.isnull().sum()
subType          0
teamId           0
gameLength       0
championId       0
stats.win        0
stats.kills      0
stats.deaths     0
stats.assists    0
timeline.lane    0
dtype: int64
  • 결측값은 없으나 다시하기 여부나 포지션이 제대로 입력되었는지 확인이 필요하다.

2.2 다시하기, 포지션 확인

my_game3["stats.win"].value_counts()
False    446
True     425
Name: stats.win, dtype: int64
  • 다시하기가 UNKNOWN으로 있으리라 생각했는데 없다.

  • 아마 다시하기가 False에 포함되어 있지 않을까?

# 4분 이내 승리여부
my_game3[my_game3["gameLength"] < 240]
subType teamId gameLength championId stats.win stats.kills stats.deaths stats.assists timeline.lane
4 420 200 192 163 True 0 1 0 NONE
603 420 200 203 203 True 0 0 0 NONE
1042 420 200 194 99 True 0 0 0 NONE
1065 420 100 197 266 False 0 0 0 NONE
1107 420 200 198 22 False 0 0 0 NONE
1122 420 100 201 266 True 0 0 0 NONE
1145 420 200 197 235 True 0 0 0 NONE
  • 다시하기 기준 3분과 투표시간 1분을 고려해서 확인하였을 때 승리 여부에서 True, False가 혼합되어 있다.

  • 더불어서 포지션의 경우 NONE으로 입력된 경우가 있다.

  • 분리할 방법을 못 찾겠어서 일반적인 서렌 기준 15분 보다 작은 데이터는 삭제하자.

  • 이렇게 보면 다시하기 투표를 한 팀에 속하는 경우 패배, 아닌 경우는 승리가 아닐까?

print(my_game3["timeline.lane"].unique())
print(my_game3["timeline.lane"].value_counts())
['BOTTOM' 'NONE' 'MIDDLE' 'TOP' 'JUNGLE']
BOTTOM    533
NONE       97
JUNGLE     87
MIDDLE     77
TOP        77
Name: timeline.lane, dtype: int64
  • 우선 서폿, 원딜 구분이 안되고 NONE이 97개로 생각보다 많다.

  • 추후 챔피언 이름을 붙혀서 일부 예외말고는 분류가 잘 되있다면 수기 분류

2.3 컬럼 수정

# KDA 추가하기
def cal_KDA(df):
    # perfect KDA는 death에 1을 추가
    if df["stats.deaths"] == 0:
        adjust = 1
    else:
        adjust = 0
        
    KDA = (df["stats.kills"] + df["stats.assists"]) / (df["stats.deaths"] + adjust)
    
    return KDA
    
my_game3["K/D/A"] = my_game3.apply(lambda x: cal_KDA(x), axis=1)
my_game3.head()
subType teamId gameLength championId stats.win stats.kills stats.deaths stats.assists timeline.lane K/D/A
3 420 200 2482 115 False 14 10 15 BOTTOM 2.9
4 420 200 192 163 True 0 1 0 NONE 0.0
11 420 100 1402 412 True 1 3 8 BOTTOM 3.0
12 420 100 1712 163 True 4 6 8 MIDDLE 2.0
13 420 100 1322 50 True 4 4 6 MIDDLE 2.5
  • KDA는 데스가 0인 경우는 분모를 1로 설정
# 챔피언 정보 가져오기
champion_constant = requests.get("http://ddragon.leagueoflegends.com/cdn/11.15.1/data/ko_KR/champion.json")
champion_df = pd.DataFrame(champion_constant.json()['data']).T[['key','id']]

# 데이터 타입 변경
champion_df["key"] = champion_df["key"].astype(int)

# 챔피언 이름 추가
my_game4 = pd.merge(my_game3, champion_df, how = 'left', left_on = 'championId', right_on = 'key')

# 컬럼명 변경
rename_col_lst = {
    "subType": "type", 
    "teamId": "side", 
    "id": "champion", 
    "gameLength": "length",
    "stats.win": "win",
    "timeline.lane": "position",
    "stats.kills": "K",
    "stats.deaths":"D",
    "stats.assists":"A",
    "K/D/A": "KDA"
}

my_game4.rename(columns = rename_col_lst, inplace = True)

# 게임종류, 진영 이름 적어주기, 승패여부 int, 게임시간 분단위
my_game4["type"] = my_game4["type"].apply(lambda x: "Rank" if x == 420 else "Aram")
my_game4["side"] = my_game4["side"].apply(lambda x: "Blue" if x == 100 else "Red")
my_game4["win"] = my_game4["win"].astype(int)
my_game4["length"] = my_game4["length"] / 60

# 일부 컬럼 추출
my_game4 = my_game4[rename_col_lst.values()]
my_game4
type side champion length win position K D A KDA
0 Rank Red Ziggs 41.366667 0 BOTTOM 14 10 15 2.900000
1 Rank Red Taliyah 3.200000 1 NONE 0 1 0 0.000000
2 Rank Blue Thresh 23.366667 1 BOTTOM 1 3 8 3.000000
3 Rank Blue Taliyah 28.533333 1 MIDDLE 4 6 8 2.000000
4 Rank Blue Swain 22.033333 1 MIDDLE 4 4 6 2.500000
... ... ... ... ... ... ... ... ... ... ...
866 Rank Red Kaisa 25.616667 1 BOTTOM 0 7 4 0.571429
867 Rank Blue Varus 26.516667 1 BOTTOM 2 2 14 8.000000
868 Rank Blue Lucian 23.083333 1 MIDDLE 11 1 6 17.000000
869 Rank Blue Ashe 34.483333 1 BOTTOM 11 8 11 2.750000
870 Rank Red Karma 19.166667 0 NONE 0 6 4 0.666667

871 rows × 10 columns

  • 컬럼명과 값들을 보기 쉽게 편집 (게임종류의 경우 이미 랭크만 뽑아서 안써도 상관 없음)

  • 여기서 2번째 index 탈리야 정보가 게임길이가 3분 정도인데 이겼다고 확인

  • op.gg에 Romg2 검색시 탈리야로 최근 20게임 검색시 다시하기로 되어있음을 확인 가능하다.

2.4 다시하기, 포지션 수정

print(f"삭제 전 게임 수: {my_game4.shape[0]}")

my_game4 = my_game4[my_game4["length"] > 15]

print(f"삭제 후 게임 수: {my_game4.shape[0]}")
삭제 전 게임 수: 871
삭제 후 게임 수: 858
location = my_game4["position"].unique()

for i in location:
    print(i, "\n", my_game4[my_game4["position"] == f"{i}"]["champion"].unique(), "\n")
BOTTOM 
 ['Ziggs' 'Thresh' 'Ashe' 'Samira' 'Karma' 'Swain' 'Ezreal' 'Varus'
 'Taliyah' 'Aphelios' 'Sivir' 'Lucian' 'Senna' 'MissFortune' 'Xayah'
 'Jinx' 'Jhin' 'Alistar' 'Zyra' 'Braum' 'Xerath' 'Kaisa' 'Neeko' 'Lux'
 'Tristana' 'Jax' 'Caitlyn' 'Twitch' 'Kalista' 'Sona' 'Vayne' 'Morgana'
 'Blitzcrank' 'Maokai' 'Yasuo' 'Irelia'] 

MIDDLE 
 ['Taliyah' 'Swain' 'Varus' 'Ezreal' 'Senna' 'Sylas' 'TwistedFate' 'Ahri'
 'Tristana' 'Gnar' 'Jinx' 'Corki' 'Xayah' 'Jhin' 'Malzahar' 'Lucian'
 'Ashe' 'Caitlyn' 'Sivir' 'Zilean' 'Garen' 'Leblanc' 'Diana' 'Gragas'
 'Quinn' 'Aatrox' 'MissFortune' 'Ryze' 'Qiyana' 'Akali' 'Irelia' 'Poppy'
 'Kaisa'] 

TOP 
 ['Camille' 'Viego' 'Sylas' 'Gnar' 'Gangplank' 'Poppy' 'Jayce' 'Ornn'
 'Kled' 'Quinn' 'Kayle' 'Kalista' 'Aatrox' 'Karma' 'DrMundo' 'Lucian'
 'Vayne' 'Garen' 'Vladimir' 'Mordekaiser' 'Nasus' 'Jax' 'Fiora' 'Kaisa'] 

NONE 
 ['Kalista' 'Senna' 'Samira' 'Varus' 'Swain' 'Xayah' 'Thresh' 'Ashe'
 'Sivir' 'MissFortune' 'Ahri' 'Aatrox' 'Jax' 'Tristana' 'Kaisa' 'Gnar'
 'Nasus' 'Renekton' 'Kindred' 'Ekko' 'Jhin' 'Ezreal' 'Caitlyn' 'Twitch'
 'Jinx' 'Taliyah' 'Lucian' 'Vladimir' 'Aphelios' 'Alistar' 'Garen' 'Leona'
 'Corki' 'Kayle' 'Irelia' 'Diana' 'Vayne' 'Pyke' 'Karma'] 

JUNGLE 
 ['Viego' 'Varus' 'Swain' 'Diana' 'LeeSin' 'Jax' 'Ekko' 'Gnar' 'Graves'
 'Lillia' 'Renekton' 'Nidalee' 'Gragas' 'JarvanIV' 'Kindred' 'Shyvana'
 'Elise' 'Kayn' 'RekSai' 'Qiyana' 'Taliyah' 'Fiora' 'Sylas' 'DrMundo'
 'Ashe'] 
  • 어느 정도 맞는거 같기도 한데.. 정글 스웨인이나 애쉬는 도저히 아닌거 같다.

  • 포지션은 아쉽지만 우선 버리기로 결정

# 포지션 컬럼 삭제
my_game4.drop(columns="position", inplace=True, axis=1)

2.5 게임 시간 구간

# 게임 시간 5분 단위로 (ex 15분이상 20분 미만)
len1 = (my_game4["length"] //5 *5).astype(str).str[:2]
len2 = (my_game4["length"] //5 *5 + 5).astype(str).str[:2]

my_game4["length_dummy"] = len1 + "_" + len2 + "min"
my_game4.head()
type side champion length win K D A KDA length_dummy
0 Rank Red Ziggs 41.366667 0 14 10 15 2.9 40_45min
2 Rank Blue Thresh 23.366667 1 1 3 8 3.0 20_25min
3 Rank Blue Taliyah 28.533333 1 4 6 8 2.0 25_30min
4 Rank Blue Swain 22.033333 1 4 4 6 2.5 20_25min
5 Rank Red Camille 29.533333 0 7 6 2 1.5 25_30min
  • 게임 시간 구간별 승률을 확인하기 위해 5분 단위로 잘라서 생성
my_game4["length_dummy"].value_counts()
25_30min    237
30_35min    200
20_25min    196
35_40min     89
15_20min     84
40_45min     37
45_50min     14
50_55min      1
Name: length_dummy, dtype: int64
my_game4 = my_game4[my_game4["length_dummy"] != "50_55min"]
  • 50분 이상 55분 미만 게임은 하나밖에 없어 편의상 제거하였다.

3. 지표 확인

3.1 진영, 게임 시간별 승률

# KDA 추가하기
def cal_KDA2(df):
    # perfect KDA는 death에 1을 추가
    if df["D"] == 0:
        adjust = 1
    else:
        adjust = 0
        
    KDA = (df["K"] + df["A"]) / (df["D"] + adjust)
    
    return KDA

# 승률
def ratio(x):
    return x.sum() / x.count() * 100

# 그룹별 집계
def group_statistic(df, group_lst, sort=False):
    # 판수, 승리수, 승률
    temp = df.groupby(group_lst)["win"].agg({'count', "sum", ratio}).reset_index()
    
    # 패배수 추가
    temp["lc"] = temp["count"] - temp["sum"]
    
    # 그룹별 KDA 추가
    kda = df.groupby(group_lst).sum().apply(lambda x: cal_KDA2(x), axis=1).values
    temp["kda"] = kda
    
    # 컬럼 순서 지정
    re = {"count":"total_count", "sum":"win_count", "lc":"lose_count", "ratio":"win_rate", "kda":"KDA"}
    temp = temp.rename(columns=re)
    temp = temp[group_lst + list(re.values())]
    
    # 정렬 옵션
    if sort != False:
        temp = temp.sort_values(by=[sort], ascending=False)    
    
    return temp
  • 지정한 그룹별로 승률 및 KDA 계산하는 함수

  • KDA의 경우 기존 KDA(게임별)를 평균 내면 안될 것 같아 새로 산출

group_statistic(my_game4, ["type"], sort="win_rate")
type total_count win_count lose_count win_rate KDA
0 Rank 857 417 440 48.65811 2.655069
  • 우선 전체 랭크 승률인데 50%가 안된다..

  • 매치별 날짜를 확인 못하겠는데 2019시즌까지는 플레였는데 그 후로 쭉 내리막으로 골드여서 그런게 아닐까?

  • 매치별 날짜와 티어가 확인 된다면 좋을 듯한데 못 찾았다.

group_statistic(my_game4, ["side"], sort="win_rate")
side total_count win_count lose_count win_rate KDA
1 Red 433 218 215 50.346420 2.656510
0 Blue 424 199 225 46.933962 2.653634
  • 진영별로는 Blue 진영에 비해 Red 진영이 판수가 더 많고 승률도 높다.

  • 예상과 반대로 Red 진영 승률이 더 높다.

group_statistic(my_game4, ["length_dummy"])
length_dummy total_count win_count lose_count win_rate KDA
0 15_20min 84 38 46 45.238095 1.967213
1 20_25min 196 105 91 53.571429 2.381842
2 25_30min 237 101 136 42.616034 2.344715
3 30_35min 200 106 94 53.000000 3.001775
4 35_40min 89 43 46 48.314607 2.984823
5 40_45min 37 19 18 51.351351 3.296578
6 45_50min 14 5 9 35.714286 2.649254
  • 게임 시간별로는 20분 이상 25분 미만에서 승률이 가장 좋았다.

  • 초반 승률이 낮고 후반 승률이 높은 등의 추세를 보고 싶었는데 특별한 패턴은 안보인다.

  • 전처리를 잘못해서 그럴까, 진짜 이럴까?

group_statistic(my_game4, ["side", "length_dummy"])
side length_dummy total_count win_count lose_count win_rate KDA
0 Blue 15_20min 32 15 17 46.875000 1.867347
1 Blue 20_25min 101 57 44 56.435644 2.485333
2 Blue 25_30min 117 47 70 40.170940 2.213355
3 Blue 30_35min 100 50 50 50.000000 2.911765
4 Blue 35_40min 44 19 25 43.181818 3.167247
5 Blue 40_45min 22 8 14 36.363636 3.535211
6 Blue 45_50min 8 3 5 37.500000 2.512500
7 Red 15_20min 52 23 29 44.230769 2.034247
8 Red 20_25min 95 48 47 50.526316 2.278075
9 Red 25_30min 120 54 66 45.000000 2.475649
10 Red 30_35min 100 56 44 56.000000 3.096539
11 Red 35_40min 45 24 21 53.333333 2.813725
12 Red 40_45min 15 11 4 73.333333 3.016529
13 Red 45_50min 6 2 4 33.333333 2.851852
  • 진영, 게임 시간별 승률도 확인

3.2 챔피언별 승률

# 15판 이상 플레이한 챔피언 승률
temp = group_statistic(my_game4, ["champion"], sort="win_rate")
temp[(temp["total_count"] >= 15)]
champion total_count win_count lose_count win_rate KDA
62 Swain 19 14 5 73.684211 4.379747
58 Senna 95 52 43 54.736842 3.311203
4 Aphelios 33 18 15 54.545455 2.287234
13 Ekko 24 13 11 54.166667 3.445652
39 Lucian 43 22 21 51.162791 2.528571
27 Jinx 28 14 14 50.000000 2.582781
69 Varus 38 19 19 50.000000 3.170732
64 Taliyah 31 15 16 48.387097 3.006289
57 Samira 23 11 12 47.826087 2.640000
15 Ezreal 67 32 35 47.761194 2.741433
73 Xayah 24 11 13 45.833333 2.566372
5 Ashe 60 27 33 45.000000 2.286127
26 Jhin 29 13 16 44.827586 3.078740
43 MissFortune 30 12 18 40.000000 2.868571
28 Kaisa 26 7 19 26.923077 1.793333
  • 15판 이상 플에이한 챔피언의 승률이다.

  • 세나는 95판이나 플레이했는데 승률도 준수한 반면 카이사 괜히 해서 승률 엄청 까먹은 것을 확인 가능하다.

3.3 시각화

# 챔피언별 승률 (전체 플레이 수 상위 10개)
temp = group_statistic(my_game4, ["champion"], sort="total_count")
top_10_champ = temp.iloc[:10,0].values

temp = group_statistic(my_game4, ["side", "champion"], sort="total_count")
temp2 = temp[temp["champion"].isin(top_10_champ)]

fig1 = px.bar(temp2, x="win_rate", y="champion", color="side", 
              barmode="group", orientation="h",
              hover_data=["total_count", "win_count", "lose_count", "KDA"], hover_name="side")

# 게임 시간별 승률
temp = group_statistic(my_game4, ["side", "length_dummy"])

fig2 = px.bar(temp, x="length_dummy", y="win_rate", color="side", 
              barmode="group", 
              hover_data=["total_count", "win_count", "lose_count", "KDA"], hover_name="side")

# 진영별 승률
temp3 = my_game4.copy()
temp3["win"] = temp3["win"].apply(lambda x: "승리" if x==1 else "패배")
temp3_blue = temp3[temp3["side"]=="Blue"]
temp3_red = temp3[temp3["side"]=="Red"]

fig3 = px.pie(temp3_blue, names="win", hole = 0.5)
fig3.update_traces(textposition="inside", textinfo="percent+label")

fig4 = px.pie(temp3_red, names="win", hole = 0.5)
fig4.update_traces(textposition="inside", textinfo="percent+label")

# subplot type 설정 (2x3)
fig = make_subplots(rows=2, cols=3, shared_xaxes=False, 
                    specs=[ [{'type':'xy',"rowspan": 2}, {'type':'xy','colspan':2}, None], 
                            [None, {'type':'domain'}, {'type':'domain'}] ])

trace1_1 = fig1['data'][0]
trace1_2 = fig1['data'][1]

trace2_1 = fig2['data'][0]
trace2_2 = fig2['data'][1]

trace3 = fig3['data'][0]
trace4 = fig4['data'][0]

fig.add_trace(trace1_1, row=1, col=1)
fig.add_trace(trace1_2, row=1, col=1)

fig.add_trace(trace2_1, row=1, col=2)
fig.add_trace(trace2_2, row=1, col=2)

fig.add_trace(trace3, row=2, col=2)
fig.add_trace(trace4, row=2, col=3)

fig.update_layout(
    title_text="Win Rate",
    height=600,width=1000,
    showlegend=False,

    plot_bgcolor='white'
)
    
fig.show()

fig.write_html("Day02_02_check_me.html")
  • plotly 패키지를 이용한 시각화로 마우스를 올리면 진영과 승률, 판수, 승수, KDA 등이 확인 가능

  • 오른쪽 아래 도넛 차트 2가지는 진영별로 승률을 나타냈으나 현재 시각화가 깔끔하지 못함

  • 조금 더 깔끔하게 수정 필요

4. 추후 파악요소?

어느정도 살펴보았을 때 아래 부분을 파악하면 더 재밌을 것 같습니다

  1. 다시하기 기준

  2. 포지션 분류 기준

  3. 게임 날짜 확인

  4. 티어 확인

  5. 시각화 보완

Leave a comment