발표 준비, 혹은 문서 작성을 하다 보면 데이터의 수치를 시각화하고 싶은 경우가 있습니다.
그럴 때 많이 이용하는 것이 히트맵인데요
히트맵은 다양한 데이터를 열 분포의 형태로 나타낼 수 있는 시각화 방법입니다.
이 히트맵을 이미지 위에 그림으로서 일부분을 강조하는 형태로 만들어 보여줄 수 있는데요
이번에는 파이썬으로 이미지 위에 히트맵을 그리는 방법을 알아보도록 하겠습니다.
깃허브에서 두 가지 코드를 가지고 왔습니다.
1. heatmap
https://github.com/durandtibo/heatmap
보시는 것과 같이 알파값과 위치만 입력하여 단순하게 히트맵을 그릴 수 있는 툴입니다.
이 코드는 pip에는 등록되어있지 않아 git clone을 이용하거나 홈페이지에서 직접 다운로드를 받아 패키지를 이용해야 합니다.
코드를 다운받으셨으면 패키지를 인스톨 해 줍니다.
python setup.py install
참고로 파이썬 3버전을 이용해야 하므로 기본 파이썬 버전이 2이신 분들은 python3 setup.py install 을 이용해 주시면 되겠습니다.
패키지 설치가 완료되었으면 demo 안에서 데모 코드를 확인하실 수 있습니다.
코드를 먼저 살펴보죠.
import heatmap
from scipy import ndimage
from skimage import io
import numpy as np
# read image
#자신이 원하는 이미지 경로로 수정
image_filename = '../data/face.png'
image = io.imread(image_filename)
# create heat map
x = np.zeros((101, 101)) #히트맵을 생성할 100x100크기 격자
x[50, 50] = 1 #히트맵의 중심이 될 부분
heat_map = ndimage.filters.gaussian_filter(x, sigma=16)
#자신이 출력하고 싶은 경로로 수정
heatmap.add(image, heat_map, alpha=0.7, save='../data/face_heat_map.png')
for alpha in np.arange(0, 1.1, 0.1):
print('alpha ' + str(alpha))
heatmap.add(image, heat_map, alpha=alpha,
save='../data/face_heat_map_' + str(alpha) + '.png', axis='off') #자신이 출력하고 싶은 경로로 수정
read image 부분에서는 읽어올 이미지 경로를 설정해 줍니다.
기본적으로는 데모로 사용할 너구리 얼굴 이미지 경로가 지정되어 있습니다.
각자 자신이 히트맵을 그리고 싶은 이미지 경로를 넣어주시면 되겠습니다.
create heat map 부분에서는 히트맵을 생성합니다.
x 변수에 numpy를 이용해 0으로 채워진 100x100 사이즈의 배열을 선언해 줍니다
그리고 히트맵을 생성하고 싶은 중심 부분은 1로 수정해주면 그 부분을 기준으로 히트맵이 생성됩니다.
gaussian_filter의 sigma를 조정하면 히트맵의 크기를 조정할 수 있습니다
그 후엔 단순히 heatmap.add() 함수를 이용해서 히트맵을 추가할 수 있고, 저장하고 싶다면 save=''에 경로를 입력해주면 됩니다.
add() 함수의 인자들을 살펴보면 다음과 같이 선언되어 있습니다.
def add(image, heat_map, alpha=0.6, display=False, save=None, cmap='viridis', axis='on', verbose=False)
image에 입력할 이미지를 넣어줄 수 있고
heat_map에는 create heat map부분에서 생성한 히트맵을 넣어줍니다.
alpha값을 조정하여 오버레이되는 히트맵의 불투명도를 조정할 수 있습니다.
axis를 on으로 할 경우 이미지의 좌표값이 나타납니다. off로 할 경우 입력 이미지와 같은 이미지가 출력됩니다.
save에 경로를 입력해 줄 경우 결과가 입력한 경로에 파일로 출력됩니다.
데모 코드를 실행하면 0부터 1까지 0.1씩 alpha값을 변경하며 생성된 히트맵 이미지가 저장됩니다.
원하는대로 히트맵을 작성하고 싶다면 create heat map 부분에서 좌표값을 더 추가하고
원하는 alpha값을 지정하면 새로운 이미지를 만들 수 있습니다.
예를 들어서..
인물 사진의 손을 강조하고 싶을 때에 이와 같은 이미지를 만들어 쓸 수 있습니다.
아래와 같은 코드를 이용했습니다.
# read image
image_filename = '../data/hand4.jpeg'
image = io.imread(image_filename)
# create heat map
x = np.zeros((101, 101))
x[20, 20] = 1
x[30, 20] = 1
x[40, 20] = 1
heat_map = ndimage.filters.gaussian_filter(x, sigma=8)
alpha = 0.6
heatmap.add(image, heat_map, alpha=alpha,
save='../data/hand1_heat_map_' + str(alpha) + '.jpeg', axis='off')
import문은 생략했습니다. 데모 코드와 같이 해주시면 됩니다.
타원형으로 히트맵을 만들고 싶은 경우에는 점을 여러개 생성해주시면 됩니다.
2. heatmappy
https://github.com/LumenResearch/heatmappy
또 다른 패키지로는 heatmappy라는 패키지가 있습니다.
heatmap 패키지는 전체가 파란색으로 오버레이 된 이미지를 생성했는데요
heatmappy 패키지는 이미지의 원본 색상 위에 히트맵을 작성할 수 있습니다.
또한 동영상에 히트맵을 그려주는 것도 가능합니다.
이와 같은 히트맵 이미지를 생성할 수 있습니다.
한 번 사용해보도록 하지요.
이 패키지는 pip에 등록되어 있으므로 pip로도 설치가 가능합니다.
pip install heatmappy
설치가 정상적으로 완료되신다면 그대로 사용하셔도 괜찮지만, 어째선지 오류가 많은 것 같더군요
만약 오류가 나타날 경우 heatmap패키지를 설치했던 것과 같이 setup.py를 직접 실행시켜주면 오류 없이 설치할 수 있었습니다.
python setup.py install
setup.py를 실행시켜 설치시키실 경우에는 아시다시피
git clone을 이용하거나 깃허브 홈페이지에서 코드를 다운로드 받아주셔야 합니다.
설치가 되었다면 바로 사용하실 수 있습니다.
heatmappy는 demo 코드가 따로 없어서 간단하게 코드를 만들어 보았습니다.
from heatmappy import Heatmapper
from PIL import Image
# 입력 이미지 경로 설정
example_img_path = 'data/hand5.jpeg'
example_img = Image.open(example_img_path)
example_points = [(180, 130), (185, 140), (190,155)] # 히트맵 중심 좌표 설정
# 히트맵 그리기
heatmapper = Heatmapper(
point_diameter=150, # the size of each point to be drawn
point_strength=1, # the strength, between 0 and 1, of each point to be drawn
opacity=0.6, # the opacity of the heatmap layer
colours='default', # 'default' or 'reveal'
# OR a matplotlib LinearSegmentedColorMap object
# OR the path to a horizontal scale image
grey_heatmapper='PIL' # The object responsible for drawing the points
# Pillow used by default, 'PySide' option available if installed
)
# 이미지 위에 히트맵 그리기
heatmap = heatmapper.heatmap_on_img(example_points, example_img)
# 출력 이미지 경로 설정
heatmap.save('data/hand5_heatmap.png')
기본적으로 설정해 줄 것은 heatmap 패키지와 비슷합니다
입력 이미지 경로를 설정하고 이미지를 오픈해줍니다.
그 다음 히트맵을 그릴 중심 좌표를 찍어줍니다.
heatmap 패키지와 다른 점은 heatmappy는 격자를 임의로 생성하는 것이 아닌, 직접 이미지의 좌표를 찍어주어야 한다는 점입니다.
때문에 이미지 사이즈를 고려하여 히트맵의 중심이 될 부분의 좌표를 설정해 줍니다.
다음으론 히트맵을 그릴 때 사용할 Heatmapper를 설정해줍니다.
point_diameter로는 히트맵 원의 크기를 설정해줄 수 있습니다.
point_strength는 색깔의 강도입니다. 0부터 1 사이 값으로, 1에 가까울수록 중심이 붉어집니다. 색깔은 아래와 같은 분포를 가집니다.
opacity는 히트맵의 투명도입니다.
colours는 default와 reveal을 설정해줄 수 있는데, default로 설정해줄 경우 위와 같은 분포를 가지는 기본적인 히트맵을 생성할 수 있습니다.
객체를 생석했으면 heatmap_on_img() 함수를 이용해서 히트맵 이미지를 만들 수 있습니다.
히트맵을 그릴 좌표값과, 입력 이미지를 파라미터로 주면 됩니다.
히트맵 그리기까지 완료되었으면 save() 함수를 이용해서 저장할 수 있습니다.
파라미터로는 저장할 경로값을 주면 됩니다.
위와 같은 코드를 실행해서 생성된 이미지입니다.
heatmap과는 다르게 원본 컬러를 유지한 채 히트맵을 그려줄 수 있습니다.
타원 모양을 그려주고 싶을 경우 똑같이 인접한 점을 찍어주면 됩니다.
이번에는 이미지 위에 히트맵을 그릴 수 있는 파이썬 패키지들을 알아 보았습니다.
이미지 시각화에서는 많이 사용되는 방법인 만큼 알아두면 좋을 것 같다고 생각합니다.
'Python 이야기' 카테고리의 다른 글
Folium으로 지도 그리기 (2) | 2019.05.08 |
---|