[부동산 | Phase3] 아파트 현황조사(고양시) - matplotlib 기본 (1부)
{금번 포스팅부터 경어체로 바꾸도록 하겠습니다. }
지난 포스팅까지 Phase2를 통해 데이터 가공작업을 완료하였고, 이번 포스팅부터는 가공된 데이터를 시각화해 보도록 하겠습니다.
matplotlib 소개
Python에서 널리 사용되는 시각화 라이브러리로는 matplotlib이 있습니다. matplotlib의 공식 사이트를 방문해 보시면 이 라이브러리가 얼마나 다양한 유형의 전문화된 통계 데이터 시각화 방법을 제공하는지 확인이 가능하신데요. 아래 링크를 걸어 드리니, 한 번 들르려서 참조해 보시면 좋겠습니다.
공식사이트 홈페이지 :
제공되는 도표 형식의 예제 Gallery:
https://matplotlib.org/gallery/index.html
이 사이트에서는 유저가 사용하고자 하는 그래프 형태별로 자세한 사용방법에 대한 document를 제공합니다. 영문으로 제공되는 점이 영문에 약하신 분들께는 다소 장애가 될 수 있겠지만 조금의 인내심을 가지고 찬찬히 살펴 보시면, matplotlib을 주물러 사용하시는데에는 크게 지장이 없으시리라 생각됩니다.
상세 소개는 별도의 포스팅으로 다뤄보도록 하고, 이제 우리의 주제로 넘어가 보도록 하겠습니다.
우리는 질문 3가지를 가지고 데이터 분석을 선행하였습니다.
(1) 행신동에 지은지 20년 이내 아파트 단지는 어떤 것이 있을까?
(2) 고양시 공동주택의 건물나이(건령)는 어느 정도 되었고, 어떤 분포를 가지고 있을까? 지은지 5년 이내 신규 아파트는 얼마나 될까?
(3) 공동주택 건물 유형별로 공급되어 있는 세대수는 얼마나 될까?
먼저 (1)번 질문에 대해서는 그래프로 표시할 필요까지는 없어 보입니다. 단지, 아파트 단지명만 확인할 목적이었으니깐요.
해서 (1)번 질문은 넘어가고 (2)번 주제를 살펴 보겠습니다.
우리는 (2)번 데이터분석을 통해 'a8'이라는 명칭을 가진 DataFrame을 이미 확보하였습니다. xlsx확장자의 엑셀파일로 Export도 해보았는데요. 이 엑셀파일을 다시 불러 들여 보겠습니다.
pandas 에서는 엑셀파일을 읽을 때엔, read_excel() 함수를 제공합니다.
b1 = pd.read_excel('C:\\Users\\USER\\Desktop\\example\\a8_APTstat_Goyang.xlsx')
print(b1)
파이참 터미널을 통해 확인된 결과는 아래와 같습니다.
import matplotlib.pyplot as plt
정상적으로 잘 읽어 들인 것이 확인되었습니다. 이제 우리는 matplotlib 라이브러리를 사용하기 위해 모듈을 import 하도록 하겠습니다. 아래의 코드를 pandas를 import한 코드라인 아래에 추가해 줍니다.
import pandas as pd
import matplotlib.pyplot as plt
이는 matplolib이라는 라이브러리안에 포함된 pyplot이라고 하는 모듈을 'plt'라는 약칭으로 코드를 사용하겠다는 것을 의미합니다. 따라서, 해당 모듈안에 포함된 메소드를 사용할 때엔 plt로 약칭하고, 필요 메소드를 호출하기만 하면 됩니다.
이제 막 matplotlib을 접하기 시작했으니, 복잡한 그래프는 차후 다루기로 하고 우선 간단한 2차원 막대그래프를 그려 보기로 하겠습니다. 우리의 데이터로 돌아가서 행정동별 단지수의 분포를 표현하기 위해, x축은 '행정동'을 y축은 '단지수'를 표현하도록 하겠습니다.
제가 작성한 기본코드는 아래와 같습니다.
x1 = b1['행정동']
y1 = b1['단지명']
plt.bar(x1, y1, width=0.5, align='center', color='blue', alpha=1.0, edgecolor='grey', linewidth=0.3)
plt.tick_params(axis="y", labelsize=9)
plt.grid(axis='y', linestyle='--', linewidth=0.5, color='black', alpha=0.3)
plt.show()
처음 접하는 것이니, 코드를 한 줄 한 줄 설명하도록 하겠습니다.
1) x1 = b1['행정동']
x1이라는 변수에 b1으로 불러들인 우리 데이터의 DataFrame 중 '행정동' series(열)을 대입해 줍니다.
2) y1 = b1['단지명']
y1이라는 변수에 b1 Data Frame 중 '단지명' series(열)을 대입해 줍니다.
plt.bar() matplotlib 수직막대그래프 그리기
3) plt.bar(x1, y1, width=0.5, align='center', color='blue', alpha=1.0, edgecolor='grey', linewidth=0.5)
앞선 내용처럼, matplotlib.pyplot.bar라고 호출하는 대신, plt.bar로 bar라는 메소드를 간단히 호출하였습니다.
bar메소드는 수직막대그래프를 그려줍니다.
그리고, 첫번째 인자로는 x축에 들어갈 데이터를 분배하는데 우리는 x1이라는 변수에 '행정동'을 배분했습니다.
두번째 인자로는 y축에 들어갈 데이터를 분배하는데 '단지명'데이터를 배분한 y1 변수를 넣습니다.
그외 bar라는 method는 그래프 모양을 modification하기 위한 옵션 인자들을 제공합니다. 요약은 다음과 같습니다.
width : 막대의 두께를 지정합니다.
align : 막대의 정렬위치를 지정합니다.
color : 막대의 색깔을 지정합니다.
alpha : 막대색깔의 투명도를 지정합니다.
edgecolor : 막대의 테두리선의 색을 지정합니다.
linewidth : 막대 테두리선의 두께를 지정합니다.
이 외에도 다양한 옵션을 통해 막대그래프 꾸미기가 가능합니다. 상세는 matplotlib 공식 사이트의 document를 참조하시면 되겠습니다.
* matplolib.pyplot.bar 공식문서 : https://matplotlib.org/api/_as_gen/matplotlib.pyplot.bar.html?highlight=bar#matplotlib.pyplot.bar
필자의 경험상 matplotlib을 가장 빠르게 익히는 방법은 갖가지 옵션들을 코드에 추가 삭제해 가면서 그 결과 그래프를 보고 직접 깨달아 보시는 것입니다. 쓰다 보면 익숙해 져서 속도가 배가 됩니다.
4) plt.tick_params(axis="y", labelsize=9)
tick_params라는 메소드는 그리려고 하는 그래프의 x축 또는 y축 상의 단위표시들에 대해 유저가 수동으로 modification할 수 있도록 설정 조정을 해줍니다. 따라서, 이 메소드의 내용만 잘 익혀도 그래프의 x축 또는 y축 꾸미기의 많은 부분을 수행할 수 있습니다.
필자의 코드로는 y축에 대해 축라벨의 크기를 9로 설정하도록 표현하였습니다.
plt.grid() matplotlib plot 눈금선 그리기
5) plt.grid(axis='y', linestyle='--', linewidth=0.5, color='black', fillstyle='bottom', alpha=0.3)
grid메소드는 그래프에서 눈금선을 수정하기 위해 사용됩니다.
사용된 옵션 인자의 내용은 아래와 같습니다.
axis : 어느 축 방향으로 눈금선을 설정할 것인지 지정합니다.
linestyle : 눈금선의 스타일을 지정합니다.
linewidth : 눈금선의 두께를 지정합니다.
color : 눈금선의 색깔을 지정합니다.
alpha : 눈금선의 투명도를 지정합니다.
이 외의 눈금선 옵션은 아래의 공식문서를 참조하여 주세요.
*matplolib.pyplot.grid 공식문서: https://matplotlib.org/api/_as_gen/matplotlib.pyplot.grid.html?highlight=pyplot%20grid#matplotlib.pyplot.grid
6) plt.show()
show()를 통해 파이썬에게 지정한 방식으로 그래프를 그리라는 명령을 하게 됩니다.
이제 결과를 확인해 보면 다음과 같습니다.
그래프는 의도한 데로 잘 그려진 것이 확인됩니다.
그런데, x축 행정동명이 모두 깨져 나오네요.. 무슨 일일까요? 이는 matplotlib이 한글을 지원하지 않기 때문입니다. 파이썬이라는 언어 자체가 한글 사용까지 염두에 두고 개발하는 것이 아니기 때문에, 지난 번 데이터분석 포스팅 때에도 한글에 관련한 문제가 발생했고, 해결법도 제시했었습니다. 여러분이 실제 데이터를 가지고 작업하실 때에도 이와 비슷한 언어 관련 문제를 자주 겪게 되실 겁니다. 해결법은 hascode와 같은 한글로 제공되는 개발자 사이트는 물론이고, 일반 구글링으로도 검색이 가능하시니 더 찾아 보신다면 언제든 해결 가능하실 거라 봅니다.
matplotlib.font_manager() 한글 폰트 불러들이기
이제 이 한글문제를 해결해 보겠습니다.
matplolib에서는 표현되는 문자 font를 처리하기 위해 font_manager라는 모듈을 제공합니다.
해서 아래와 같이, matplotlib을 import한 코드 라인 아래에 코드를 더 추가해 주세요.
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import font_manager, rc
font_name = font_manager.FontProperties(fname="c:/Windows/Fonts/batang.ttc").get_name()
rc('font', family=font_name)
font_manager는 fname에 지정된 경로에 있는 ttc확장자와 같은 font형식파일을 읽어 들여 표현하는 font형식을 적용해 줍니다. 경로를 보셔서 아시겠지만, 여러분 컴퓨터의 윈도우즈 운영체제를 통해 기본으로 인식되는 폰트가 지정되었습니다. 바탕체인데요. 한글을 위해 개발된 바탕체나 궁서체 같은 형식이면 적정하겠으며, 비록 원하시는 font가 한글을 지원하는 font일지라도 정상적으로 출력하지 못하는 경우도 있습니다. 필자도 그러하였기에, 울며 겨자먹기로 바탕체를 지정하였으니 참조하여 주십시요.
그럼 이제 다시 코드를 실행해 보겠습니다.
이번에는 한글명이 잘 나왔습니다. 하지만, 여전히 글자가 겹쳐 식별할 수가 없네요.
물론, 실행된 결과창의 가로늘리기를 하면 x축이 늘어나 식별이 가능합니다.
그러나 우리가 이 그래프를 여러분의 업무보고서에 사용하신다면 그래프 크기만 엄청나게 크게 늘려야 하니 보고서가 그다지 보기 좋지 않을 것입니다.
하여 x축 꾸미기 과정으로 x축 라벨사이즈를 줄여주는 과정을 추가로 해주는 것이 좋겠습니다.
아래의 코드를 plt.show()코드라인 위에 추가해 주겠습니다.
plt.tick_params(axis="x", labelsize=8, labelrotation=90)
plt.show()
labelsize 인자로 크기를 8로 지정해 주고, labelrotation 인자로 라벨을 90도 방향 전환하도록 설정했습니다.
그리고 결과를 보시면
이제 식별이 용이한 형태의 그래프가 완성되었습니다.
이번 포스팅에서는 (2)번 질문을 가지고 아주 기초적인 형태의 수직막대그래프를 그려보았습니다. 여전히 그래프를 아름답게(?) 꾸밀 여지가 많고, matplolib은 원하는 형태로 얼마든지 고칠 수 있도록 다양한 메소드와 옵션을 제공합니다. 다음 포스팅을 통해 matplotlib의 powerful한 기능들 몇가지를 더 살펴 보도록 하겠습니다.
# 이번 포스팅 학습 내용
a. matplotlib의 이해
b. plt.bar() 수직막대그래프 그리기
c. plt.grid() 눈금선 그리기
d. matplotlib 한글font 문제 해결하기. matplotlib.font_manager
(2부에 계속..)
'파이썬(Python) > 고양시 아파트 현황 조사' 카테고리의 다른 글
[부동산 | Phase3] 아파트 현황조사(고양시) - matplotlib 기본 (3부) (0) | 2020.06.11 |
---|---|
[부동산 | Phase3] 아파트 현황조사(고양시) - matplotlib 기본 (2부) (0) | 2020.06.11 |
[부동산 | Phase2] 아파트 현황조사(고양시) - Python pandas 기본 (4부) (0) | 2020.06.09 |
[부동산 | Phase2] 아파트 현황조사(고양시) - Python pandas 기본 (3부) (0) | 2020.06.09 |
[부동산 | Phase2] 아파트 현황조사(고양시) - Python pandas 기본 (2부) (0) | 2020.06.09 |