이번 포스팅에서는 X축과 Y축에 2개의 범주형 자료의 계급(class)별로 연속형 자료를 집계한 자료를 사용하여, 집계한 값에 비례하여 색깔을 다르게 해서 2차원으로 자료를 시각화하는 히트맵(Heatmap)을 그려보겠습니다. 


기본적인 Python 라이브러리를 importing 하였으며, matplotlib, seaborn, pandas 의 순서대로 히트맵 그리는 방법을 소개하겠습니다. 



import numpy as np

import pandas as pd


import matplotlib.pyplot as plt

import seaborn as sns

plt.rcParams['figure.figsize'] = [10, 8]

 




예제로 사용할 데이터는 연도(year)별 월(month)별 승객 수(passengers)를 모아놓은 flights 라는 seaborn에 내장되어 있는 데이터프레임입니다. 



flights = sns.load_dataset('flights')


flights.head()

yearmonthpassengers
01949January112
11949February118
21949March132
31949April129
41949May121

 




pivot() 함수를 이용하여 월별 연도별 승객수를 집계한 피벗 테이블(pivot table)을 만들어서, 이를 이용해서 이어서 히트맵을 그려보겠습니다. 



df = flights.pivot('month', 'year', 'passengers')


df.head()

year194919501951195219531954195519561957195819591960
month
January112115145171196204242284315340360417
February118126150180196188233277301318342391
March132141178193236235267317356362406419
April129135163181235227269313348348396461
May121125172183229234270318355363420472

 




  (1) matplotlib을 이용한 히트맵 그리기 (Heatmap by matplotlib)


plt.pcolor() 함수를 이용하여 히트맵을 그리고, plt.colorbar() 로 색상에 대한 정보를 오른쪽에 제시해줍니다. 



# heatmap by plt.pcolor()

plt.pcolor(df)

plt.xticks(np.arange(0.5, len(df.columns), 1), df.columns)

plt.yticks(np.arange(0.5, len(df.index), 1), df.index)

plt.title('Heatmap by plt.pcolor()', fontsize=20)

plt.xlabel('Year', fontsize=14)

plt.ylabel('Month', fontsize=14)

plt.colorbar()


plt.show()




  (2) seaborn을 이용한 히트맵 그리기 (Heatmap by seaborn)


seaborn은 데이터가 2차원 피벗 테이블 형태의 DataFrame으로 집계가 되어 있으면 sns.heatmap() 함수로 매우 간단하게 히트맵을 그려줍니다. 



# heatmap by seaborn

ax = sns.heatmap(df)

plt.title('Heatmap of Flight by seaborn', fontsize=20)

plt.show() 




이번에는 annot=True argument를 써서 각 셀에 숫자를 입력(annotate each cell with numeric value)하여 보겠습니다. fmt='d' 는 정수 형태(integer format)로 숫자를 입력하라는 뜻입니다. 



# annotate each cell with the numeric value of integer format

sns.heatmap(df, annot=True, fmt='d')

plt.title('Annoteat cell with numeric value', fontsize=20)

plt.show()





cmap 에 색깔을 다르게 설정해보겠습니다. 



# different colormap

sns.heatmap(df, cmap='RdYlGn_r')

plt.title('colormap of cmap=RdYlGn_r', fontsize=20)

plt.show()




히트맵의 색깔을 cmap='YIGnBu' 로 설정해서 파란색과 노란색 계열로 바꾸어보겠습니다. 



# different colormap

sns.heatmap(df, cmap='YlGnBu') # 

plt.title('colormap of cmap=YlGnBu', fontsize=20)

plt.show()




색깔 지도(color map)의 중심을 1949년 1월(January)으로 맞추어서 히트맵을 그려보겠습니다. 좌측 최상단이 1949년 1월 (1949 January) 로서 히트맵 색의 중심 위치가 되었습니다. 



# center the colormap at a specific value

sns.heatmap(df, center=df.loc['January', 1949])

plt.title('Center the colormap at Jan. 1949', fontsize=20)

plt.show()





  (3) pandas를 이용한 히트맵 그리기 (Heatmap by pandas)


pandas는 df.style.background_gradient(cmap='summer')를 사용해서 DataFrame에 숫자에 따라서 직접 색을 다르게 입힐 수 가 있습니다. 마치 엑셀에서 피벗 테이블한 다음에 숫자에 따라서 색을 다르게 입히는 것과 유사하게요. 



# heatmap by pandas

df.style.background_gradient(cmap='summer')



이상으로 Python으로 히트맵 그리기를 마치겠습니다. 

많은 도움이 되었기를 바랍니다. 


이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. :-)



Posted by R Friend R_Friend

x축과 y축으로 나타낸 그래프 혹은 2차원의 지도 위에 특정 연속형 변수의 값에 따라 색깔을 조금씩 다르게 하여 정보를 보여주는 시각화 방법으로 히트맵(Heat map)이 많이 사용됩니다. 

 

R ggplot2 패키지에서는 geom_tile(), geom_raster() 함수를 사용해서 쉽고 편하게 히트맵(Heat map)을 그릴 수 있습니다. 

 

이번 포스팅에서는 히트맵(Heat map)을 그리고, 축의 항목 위치를 바꾸어 보는 것을 예를 들어보이겠습니다.

 

아래 보시는 것은 구글에 히트맵(Heat map) 이라는 키워드로 나온 이미지들인데요, 평소에 알게 모르게 히트맵을 우리가 많이 접하고 있었다는 것을 알 수 있을 것입니다.

 

 

[히트맵 (Heat map) 예시 ]

 

* 이미지 출처 : 구글(www.google.co.kr)

 

 

MASS 패키지에 내장되어 있는 Cars93 데이터 프레임이며, 차종(Type), 실린더(Cylinders) 별 고속도로연비(MPG.highway) 를 사용하여 히트맵(Heat map)을 그려보겠습니다.

 

 

 
> library(MASS)
> str(Cars93)
'data.frame':	93 obs. of  27 variables:
 $ Manufacturer      : Factor w/ 32 levels "Acura","Audi",..: 1 1 2 2 3 4 4 4 4 5 ...
 $ Model             : Factor w/ 93 levels "100","190E","240",..: 49 56 9 1 6 24 54 74 73 35 ...
 $ Type              : Factor w/ 6 levels "Compact","Large",..: 4 3 1 3 3 3 2 2 ...
 $ Min.Price         : num  12.9 29.2 25.9 30.8 23.7 14.2 19.9 22.6 26.3 33 ...
 $ Price             : num  15.9 33.9 29.1 37.7 30 15.7 20.8 23.7 26.3 34.7 ...
 $ Max.Price         : num  18.8 38.7 32.3 44.6 36.2 17.3 21.7 24.9 26.3 36.3 ...
 $ MPG.city          : int  25 18 20 19 22 22 19 16 19 16 ...
 $ MPG.highway       : int  31 25 26 26 30 31 28 25 27 25 ...
 $ AirBags           : Factor w/ 3 levels "Driver & Passenger",..: 3 1 2 1 2 2 2 2 2 2 ...
 $ DriveTrain        : Factor w/ 3 levels "4WD","Front",..: 2 2 2 2 3 2 2 3 2 2 ...
 $ Cylinders         : Factor w/ 6 levels "3","4","5","6",..: 2 4 4 4 2 2 4 4 ...
 $ EngineSize        : num  1.8 3.2 2.8 2.8 3.5 2.2 3.8 5.7 3.8 4.9 ...
 $ Horsepower        : int  140 200 172 172 208 110 170 180 170 200 ...
 $ RPM               : int  6300 5500 5500 5500 5700 5200 4800 4000 4800 4100 ...
 $ Rev.per.mile      : int  2890 2335 2280 2535 2545 2565 1570 1320 1690 1510 ...
 $ Man.trans.avail   : Factor w/ 2 levels "No","Yes": 2 2 2 2 2 1 1 1 1 1 ...
 $ Fuel.tank.capacity: num  13.2 18 16.9 21.1 21.1 16.4 18 23 18.8 18 ...
 $ Passengers        : int  5 5 5 6 4 6 6 6 5 6 ...
 $ Length            : int  177 195 180 193 186 189 200 216 198 206 ...
 $ Wheelbase         : int  102 115 102 106 109 105 111 116 108 114 ...
 $ Width             : int  68 71 67 70 69 69 74 78 73 73 ...
 $ Turn.circle       : int  37 38 37 37 39 41 42 45 41 43 ...
 $ Rear.seat.room    : num  26.5 30 28 31 27 28 30.5 30.5 26.5 35 ...
 $ Luggage.room      : int  11 15 14 17 13 16 17 21 14 18 ...
 $ Weight            : int  2705 3560 3375 3405 3640 2880 3470 4105 3495 3620 ...
 $ Origin            : Factor w/ 2 levels "USA","non-USA": 2 2 2 2 2 1 1 1 1 1 ...
 $ Make              : Factor w/ 93 levels "Acura Integra",..: 1 2 4 3 5 6 7 9 8 10 ...

 

 

 

 

ggplot2는 별도의 설치 및 호출이 필요하므로 아래의 절차를 먼저 거치고 히트맵을 그려보겠습니다.

 

 
> install.packages("ggplot2")
> library(ggplot2)
 

 

 

 

x축에 차종(Type), y축에 실린더개수(Cylinders)별로 고속도로연비(MPG.highway)에 따라서 색을 달리하여 히트맵을 geom_tile() 함수를 사용해 그려보겠습니다.

 

 
> # Type, Cylinders 별 MPG.highway Heatmap : geom_tile()
> a1 <- ggplot(Cars93, aes(x=Type, y=Cylinders, fill=MPG.highway)) +
+   geom_tile()
> 
> a1

 

 

 

 

 

위의 히트맵을 보면 x축에 차종(Type)이 차의 크기 순서가 아니라 알파벳 순서로 되어 있다보니 색깔이 경향성이 없이 무작위하게 채워져있어 보입니다.  x축을 차의 크기를 감안한 순서대로, 즉, "Small", "Compact", "Midsize", "Sporty", "Large", "Van" 의 순서대로 scale_x_discrete(limits=...) 를 사용해 바꾸어보겠습니다.

 

 
> # x축 순서 바꾸기 : scale_x_discrete(limits=...)
> a2 <- a1 + 
+   scale_x_discrete(limits=c("Small", "Compact", "Midsize", "Sporty", "Large", "Van"))
> 
> a2

 

 

 

 

 

위의 히트맵을 보니 크기가 작을 수록, 실린더 개수가 작을 수록 고속도로 연비가 높으며, 그 반대는 고속도로 연비가 낮아짐을 한눈에 단박에 파악할 수 있게 되었습니다.

 

 

이번에는 geom_raster() 함수를 사용해 히트맵을 그려보겠습니다.  결과적으로 geom_tile()과 차이가 거의 없다는 것을 알 수 있습니다.

 

 
> # Type, Cylinders 별 MPG.highway Heatmap : geom_raster()
> ggplot(Cars93, aes(x=Type, y=Cylinders, fill=MPG.highway)) +
+   geom_raster() + 
+   scale_x_discrete(limits=c("Small", "Compact", "Midsize", "Sporty", "Large", "Van"))

 

 

 

 

 


연속형 숫자형 값을 가지는 히트맵의 색상을 scale_fill_gradient(low = "colour 1", high = "colour 2") 옵션을 사용해서 다르게 설정해보도록 하겠습니다. (kusscd 님, 댓글로 방법 공유해주셔서 감사합니다 ^^)



> ggplot(Cars93, aes(x=Type, y=Cylinders, fill=MPG.highway)) + # filling with numeric value

+   geom_tile() +

+   scale_x_discrete(limits = c("Small", "Compact", "Midsize", "Sporty", "Large", "Van")) +

+   scale_fill_gradient(low = "yellow", high = "red") +

+   ggtitle("Heatmap of MPG.highway by Type & Cylinders")


 






다음으로, 범주형 자료로 히트맵의 색상을 채우는 경우에 scale_fill_manual(values = c("colour 1", "colour 2", ...) 을 옵션을 사용해서 색상을 사용자가 직접 지정해주는 방법을 2개 범주를 가지는 간단한 예시를 들어서 설명하겠습니다. 



> my.df <- data.frame(XCoord = c(1, 1, 2, 3, 3, 4, 4, 5, 5, 5), 

+                     YCoord = c(1, 4, 3, 1, 3, 1, 5, 2, 3, 5), 

+                     Seg = c("A", "A", "A", "A", "B", "A", "B", "B", "B", "B"))

> ggplot(my.df, aes(x=XCoord, y=YCoord, fill=Seg)) + # filling with categorical value

+   geom_tile(colour="white") +

+   scale_fill_manual(values = c("blue", "red")) +

+   ggtitle("Heatmap with 2 categories with scale_fill_manual()")




 



 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡' 단추를 꾸욱 눌러주세요.^^

 

Posted by R Friend R_Friend