07_Data_Analysis

07_비교 시각화

chuu_travel 2025. 3. 17. 00:55
728x90
비교 시각화

 

  • 그룹별 차이를 나타내기 위한 비교 시각화는 데이터가 간단하다면 막대 그래프만으로도 충분히 표현할 수 있음
  • 하지만 그룹별 요소가 많아지게 되면, 보다 효율적인 표현기법을 사용해야 함
  • 히트맵 차트는 그룹과 비교 요소가 많을 때 효과적으로 시각화를 할 수 있는 방법
    • 히트맵은 각각의 셀의 색상이나 채도를 통해 데이터 값의 높고 낮음을 나타냄
    • 따라서 각 그룹을 기준으로 요소들의 크기를 비교할 수도 있고, 각 요소를 기준으로 그룹들의 크기를 비교할 수도 있음
  • 이를 통해 각 그룹이 어떤 요소에서 높은, 혹은 낮은 값을 가지는지 쉽게 파악할 수 있고, 요소 간의 관계도 파악이 가능
    • 차트의 열을 시간 흐름으로 설정하면 시간 시각화로도 활용이 가능
  • 비교 시각화를 하는 방법으로는 방사형 차트(Rader chart)도 있음
    • 예) 게임에서 캐릭터가 가질 능력별 수준을 시각적으로 쉽게 확인할 수 있도록 표현할 수 있음
  • 평행 좌표 그래프(Parallel coordinates)를 통한 그룹별 요소 비교 시각화도 있음(전략캔버스)
    • 평행 좌표 그래프를 보다 효과적으로 표현하려면 변수별 값을 정규화해야함
      • 가장 낮은 값은 0%, 가장 높은 값은 100%로 변환하여 차이를 더욱 부각
    • 여러 변수를 평행으로 배치해서 수치를 표현하기 때문에 각 그룹별 요소별 차이 수준을 효과적으로 파악할 수 있을 뿐만 아니라 집단적 경향성을 표현하는 데에 용이함
import matplotlib.pyplot as plt
import pandas as pd
from math import pi
from pandas.plotting import parallel_coordinates
df = pd.read_csv("./data/nba2021_advanced.csv")
df.head()

 

# 히트맵 시각화를 위한 데이터 전처리

# 5개 팀만 필터링
df1 = df[df["Tm"].isin(["ATL", "BOS", "BRK", "CHI", "CHO"])]

# 6개 컬럼만 필터링
df1 = df1[["Tm", "ORB%", "TRB%", "AST%", "BLK%", "USG%"]]

 

df1.head()

 

df1.shape
(82, 6)

 

# 팀 별 요소 평균
df1 = df1. groupby("Tm").mean()
df1.head()

 

# 히트맵 시각화
fig = plt.figure(figsize = (8, 8))
fig.set_facecolor("white") # 배경색지정:흰색
plt.pcolor(df1.values)

plt.xticks(range(len(df1.columns)), df1.columns)
plt.yticks(range(len(df1.index)), df1.index)

plt.xlabel("Value", fontsize = 14)
plt.ylabel("Team", fontsize = 14)
plt.colorbar()
plt.show()

 

  • 각 팀별 요소들을 히트맵으로 시각화
  • 각 요소들의 값이 비슷하여 팀 간에 큰 차이를 보이지는 않음
# 히트맵 시각화 ver2를 위한 데이터 전처리
# 5개 팀만 필터링
df2 = df[df["Tm"].isin(["ATL", "BOS", "BRK", "CHI", "CHO"])]

# 팀명, 연령, 참여 게임 수 컬럼만 필터링
df2 = df2[["Tm", "Age", "G"]]

# 팀-연령 기준 평균으로 전처리
df2 = df2.groupby(["Tm", "Age"]).mean().reset_index()

# 테이블 피벗
df2 = df2.pivot(index = "Tm", columns = "Age", values = "G")
df2.head()

 

  • 각 팀에서 선수들의 연령에 따라 경기 참여 횟수(G)를 히트맵 시각화하기 위해 전처리
fig = plt.figure(figsize = (8, 8))

plt.pcolor(df2.values)

plt.xticks(range(len(df2.columns)), df2.columns)
plt.yticks(range(len(df2.index)), df2.index)

plt.xlabel("Age", fontsize = 14)
plt.ylabel("Team", fontsize = 14)
plt.colorbar()
plt.show()

 

  • 팀별로 19세부터 34세까지의 나이에 따라 게임 참여 횟수가 얼마나 되는지 히트맵의 색상으로 파악
  • 흰색은 NULL을 뜻함
  • BRK팀은 34세 선수의 게임 참여 횟수가 확연하게 높음
df[df["Age"] == 34]

 

# 방사형 차트를 위한 인덱스 초기화
df3 = df1.reset_index()
df3.head()

 

 

# 방사형 차트 - 하나씩 시각화

labels = df3.columns[1:] # 1번째부터 슬라이싱
num_labels = len(labels) # 데이터의 개수(축의 개수 구하기 위해)

# 등분점 생성    
angles = [x/float(num_labels)*(2*pi) for x in range(num_labels)] #축을 넣기 위해 각도 계산
angles += angles[:1] # 시작점 생성
   
my_palette = plt.cm.get_cmap("Set2", len(df3.index))
 
fig = plt.figure(figsize=(15,20))
fig.set_facecolor('white')
 
for i, row in df3.iterrows():
    color = my_palette(i)
    data = df3.iloc[i].drop('Tm').tolist()
    data += data[:1]
   
    ax = plt.subplot(3,2,i+1, polar=True)
    # 시작점 설정
    ax.set_theta_offset(pi / 2)
    # 시계방향 설정
    ax.set_theta_direction(-1)
   
    # 각도 축 눈금 생성
    plt.xticks(angles[:-1], labels, fontsize=13)
    # 각 축과 눈금 사이 여백생성
    ax.tick_params(axis='x', which='major', pad=15)
    # 반지름 축 눈금 라벨 각도 0으로 설정
    ax.set_rlabel_position(0)
    # 반지름 축 눈금 설정
    plt.yticks([0,5,10,15,20],['0','5','10','15','20'], fontsize=10)
    plt.ylim(0,20)
   
    # 방사형 차트 출력
    ax.plot(angles, data, color=color, linewidth=2, linestyle='solid')
    # 도형 안쪽 색상 설정
    ax.fill(angles, data, color=color, alpha=0.4)
    # 각 차트의 제목 생성
    plt.title(row.Tm, size=20, color=color,x=-0.2, y=1.2, ha='left')
# 차트 간 간격 설정
plt.tight_layout(pad=3)
plt.show()

 

 

  • 방사형 차트 시각화는 코드가 복잡한 편
    • 기본적인 코드 틀을 가지고 데이터프레임명과 컬럼명만 수정하여 시각화
    • 데이터 값의 범위에 따라 반지름 축 눈금 수치를 조절할 필요는 있음
# 방사형 차트 - 한번에 시각화

labels = df3.columns[1:]
num_labels = len(labels)

# 등분점 생성
angles = [x/float(num_labels)*(2*pi) for x in range(num_labels)]
# 시작점 생성
angles += angles[:1]
   
my_palette = plt.cm.get_cmap("Set2", len(df3.index))

fig = plt.figure(figsize=(8,8))
fig.set_facecolor('white')
ax = fig.add_subplot(polar=True)
for i, row in df3.iterrows():
    color = my_palette(i)
    data = df3.iloc[i].drop('Tm').tolist()
    data += data[:1]
   
    # 시작점
    ax.set_theta_offset(pi / 2)
    # 시계방향 설정
    ax.set_theta_direction(-1)
   
    # 각도 축 눈금 생성
    plt.xticks(angles[:-1], labels, fontsize=13)
    # 각 축과 눈금 사이 여백생성
    ax.tick_params(axis='x', which='major', pad=15)
    # 반지름 축 눈금 라벨 각도 0으로 설정
    ax.set_rlabel_position(0)
    # 반지름 축 눈금 설정
    plt.yticks([0,5,10,15,20],['0','5','10','15','20'], fontsize=10)
    plt.ylim(0,20)
   
    # 방사형 차트 출력
    ax.plot(angles, data, color=color, linewidth=2, linestyle='solid', label=row.Tm)
    # 도형 안쪽 색상 설정
    ax.fill(angles, data, color=color, alpha=0.4)
   
plt.legend(loc=(0.9,0.9))
plt.show()

 

  • 하나의 방사형 차트에 5개 팀 모두가 표현되도록 시각화
    • 그룹이 많지 않은 경우에는 이렇게 시각화하는 것이 비교하기에 더 좋음
  • CHO 팀이 대체적으로 모든 요소에서 약간씩 우세한 것을 확인할 수 있음
# 팀 기준 평행 좌표 그래프 생성
fig, axes = plt.subplots(figsize = (16, 8))
parallel_coordinates(df3, "Tm", ax = axes, colormap = "winter", linewidth = 1.5)
plt.show()

  • 팀 기준의 평행 좌표 그래프 시각화
  • 방사형 차트에 비해 간단하게 구현할 수 있음
  • 평행 좌표 그래프로 확인했을 때도 CHO 팀이 모든 변수에서 조금씩 우위에 있음
# plotly로 방사형 차트 시각화

fig = go.Figure(data = go.Scatterpolar(
    r = df1.iloc[0],
    theta = df1.columns,
    fill = "toself"
))

# 업데이트 하는 식으로 사용
fig.update_layout(
    # 방사형 차트의 속성: polar
    polar = dict(
        radialaxis = dict(
            visible = True # 방사형 격자 표시 여부
        ),
    ),
    showlegend = False # 범례 표시 여부
)

fig.show()

df1.head()

 

# plotly로 여러 팀 방사형 차트 시각화

fig = go.Figure(data = go.Scatterpolar(
    r = df1.iloc[0],
    theta = df1.columns,
    fill = "toself",
    name = "ATL" # 여러 팀을 표시하는 경우 name이 필요
))

fig.add_trace(go.Scatterpolar(
    r = df1.iloc[1],
    theta = df1.columns,
    fill = "toself",
    name = "BOS"
))


# 업데이트 하는 식으로 사용
fig.update_layout(
    # 방사형 차트의 속성: polar
    polar = dict(
        radialaxis = dict(
            visible = True # 방사형 격자 표시 여부
        ),
    ),
    showlegend = True # 범례 표시 여부
)

fig.show()

728x90

'07_Data_Analysis' 카테고리의 다른 글

09_데이터 분석의 이해  (4) 2025.03.17
08_분포 시각화  (0) 2025.03.17
06_시간 시각화  (0) 2025.03.17
05_Folium(지도 시각화 도구)  (1) 2025.03.17
04_seaborn예제  (0) 2025.03.16