Coding Diary.

(데이터분석) matplotlib으로 heatmap(히트맵) 작성하기 본문

Coding/Data analysis

(데이터분석) matplotlib으로 heatmap(히트맵) 작성하기

life-of-nomad 2024. 5. 27. 10:06
728x90
반응형

1. 히트맵

  • 히트맵은 일종의 이차원 히스토그램으로 산점도를 대체할 수 있는 차트입니다.
  • 두 숫자 변수의 값들이 두 개의 축을 기준으로 평면에 표시된다는 점에서 산점도와 유사합니다.
  • 한편, 데이터 포인트가 표시되는 영역은 격자 모양으로 분할되며, 각각의 격자 셀에는 그 안에 존재하는 점의 개수가 표시된다느 ㄴ점에서 히스토그램과 유사합니다.
  • 하지만, 히트맵에는 막대의 높이를 표현할 공간이 없으며 격자 셀의 색상을 통해 그 안에 존재하는 점의 개수를 나타냅니다.
  • 히트맵은 matplotlib의 hist2d() 함수를 사용해 작성할 수 있습니다.
  • 히트맵을 사용하는 경우는 아래의 두 가지입니다.
    • 1) 두 가지 불연속 변수를 나타내는 차트를 작성할 때
    • 2) 대량의 데이터 포인트가 존재할 때 투명도 대신 사용

 

2. 예시

1) Matplotlib.pyplot.hist2d() 사용한 기본 히트맵

  • 먼저, 필요한 라이브러리와 데이터를 불러옵니다.
import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
import seaborn as sns
df = pd.read_csv('../data/fuel-con.csv')
df.shape

df.head(5)

  • 차량의 연비와 관련된 데이터세트입니다.
  • 히트맵에서는 각 셀의 데이터 포인트 개수를 집계합니다
  • 그리고 그 개수에 대응하는 색상을 해당 셀에 입힙니다.
  • matplotlib을 이용해보겠습니다.
#x축: 리터 단위의 엔진 배기량, y축: 복합 연비
plt.hist2d(data=df, x='displ', y='comb')
#색상 막대를 추가해 색상에 따른 도수 확인 가능
plt.colorbar()
plt.xlabel('Displacement (1)')
plt.ylabel('Combined Fuel Eff. (mpg)');

  • 데이터를 위에서 내려다보며 작성한 2차원 버전의 히스토그램이라고 할 수 있습니다. 
  • 이때 막대의 높이는 확인할 수 없으므로 색상을 통해 도수를 표현합니다. 
  • 도수가 가장 큰 셀은 복합 연비가 25 약간  아래 정도이고 배기량은 대략 2리터 입니다.

 

2) 히트맵 계급 경계 지정하기

  • 히스토그램과 마찬가지로 히트맵에서도 np.arange를 사용해 계급의 크기를 지정할 수 있습니다.
bins_x = np.arange(0.6, 7+0.3, 0.3)
bins_y = np.arnage(12, 58+3, 3)

#색상 최소값 매개변수 : cmin (이보다 도수가 작은 셀에는 색상 입히지 않음)
#색상 팔레트 매개변수 : cmap (viridis_r : 색상 구성 반전)
plt.hist2d(data=df, x='displ', y='comb', cmin=0.5, cmap='viridis_r', bins=[bins_x, bins_y]
plt.colorbar()
plt.xlabel('Displacement (1)')
plt.ylabel('Combined Fuel Eff. (mpg)');

  • 셀 내에 존재하는 점의 개수가 늘어나면 셀은 어두워지며 색상이 노란색에서 파란색으로 바뀝니다.

3) pyplot.text() 함수 이용해 텍스트 주석 추가

  • 색상은 값을 정확하게 나타내지 못하므로 각 그리드 셀 위에 도수를 나타내는 숫자를 추가하는 것도 좋습니다.
# 계급 경계 지정하기
bins_x = np.arange(0.6, 7+0.7, 0.7)
bins_y = np.arange(12, 58+7, 7)
# cmin으로 최소한의 점 개수를 설정하기
# cmap으로 색상 구성을 반전시키기
h2d = plt.hist2d(data=df, x ='displ', y='comb', cmin=0.5, cmap='viridis_r', bins=[bins_x, bins_y])

plt.colorbar()
plt.xlabel('Displacement (1)')
plt.ylabel('Combined Fuel Eff. (mpg)');

# 표본 x와 y의 2D 배열인 이차원 히스토그램을 선택합니다.
# x 값은 첫 번째 차원에서 히스토그램화되며
# y 값은 두 번째 차원에서 히스토그램화됩니다.
# 각 셀에 포함되는 도수의 배열 구하기
counts = h2d[0]

# 각 셀에 텍스트 주석 추가하기
# counts 배열을 순회하면서 각 셀에 텍스트 주석 추가하기
for i in range(counts.shape[0]):
	for j in range(counts.shape[1]):
		c = counts[i,j]
		if c >= 100: # 어두운 셀의 텍스트 가시성 높이기
			plt.text(bins_x[i]+0.35, bins_y[j]+3.5, int(c),
					ha = 'center', va = 'center', color = 'white') #ha:가로정렬, va:세로정렬
		elif c > 0:
			plt.text(bins_x[i]+0.35, bins_y[j]+3.5, int(c),
					ha = 'center', va = 'center', color = 'black')

 

  • 이렇게 설정하면 도수가 100이상일 때는 텍스트가 흰색이 되며,
  • 도수가 0보다 큰 값일때는 텍스트가 검은색이 됩니다. 
  • 히트맵에 너무 많은 셀이 존재한다면 주석을 추가할 경우 차트가 번잡해ㅈ리 수 있으므로 그때는 주석을 추가하지 않고 데이터와 색상을 통해서만 표현하는 것이 좋습니다.
  • 결론적으로, 산점도에서는 점이 서로 겹쳐서 알아보기 어려울 수 있기 때문에 두 개의 불연속 변수를 나타낼때는 산점도보다 히트맵이 더 적합합니다.
728x90
반응형