GIS

QGIS 파이썬 콘솔에서 레이어 속성값을 이용하여 바 차트 그리기

유병혁 2017. 8. 5. 22:52

이번 글에서는 QGIS 파이썬 콘솔에서 벡터 레이어의 속성 테이블을

바로 접근해보고, 일부 속성값을 이용하여 바 차트를 그려보도록 하겠습니다.


바 차트를 그릴 때는 QGIS 파이썬 콘솔에서 가져올 수 있는(import),

'맷플롯립(Matplotlib, https://matplotlib.org/)' 예제 코드를 이용하도록 하겠습니다.


먼저, 학습을 위한 예제 데이터를 받아볼까요?! 이번 학습 데이터는

아일랜드 '특별보호구역(Special Area of Conservation, SAC)' 자료입니다.


아일랜드 국립공원 및 야생동물관리국(National Parks & Wildlife Service)
https://www.npws.ie/maps-and-data/designated-site-data/download-boundary-data


위 목록에서 첫 번째 SAC 데이터를 다운로드 받아 압축 해제한 후, QGIS에서 열어봤습니다.


해당 데이터의 속성 테이블은 아래와 같습니다. 본 학습에서는 '지역명(SITE_NAME)'과 '면적(HA)' 필드를 접근하려고 합니다.


먼저, 현재 QGIS 프로젝트에 추가된 벡터 레이어를 접근합니다. 확인을 위해 레이어명을 출력해 봅니다.


'지역명(SITE_NAME)' 필드의 색인을 확인합니다. 필드명 색인은 0부터 시작하므로 해당 값은 2입니다. 


만약 FID(FeatureID)를 정확히 알고 있다면, 해당 행과 필드명으로 속성값을 읽어올 수 있습니다.


FID가 다수인 경우, 아래와 같이 리스트로 속성값을 선택할 수도 있는데요,

아래는 FID가 0 ~ 4까지 5개 행에 대한 지역명 값을 출력해 주고 있습니다.


이번에는 배열에 지역명과 면적을 저장해 보겠습니다. 아래와 같이 특정 행과 열의 속성값을 확인해볼 수 있겠죠?!


QGIS에서는 넘파이(NumPy, http://www.numpy.org/) 라이브러리를 가져올 수도 있는데요,

앞서 속성값을 저장한 배열을 넘파이 배열로 만들고, 필드값 별로 출력해 보도록 하겠습니다.


이번에는 맷플롯립을 이용하여 지역별 면적 값을 수평 바 차트로 그려보겠습니다. 이 부분은 아래

웹사이트에서 제공하는 파이랩(pylab) 데모 코드를 적절히 변경한 것입니다. 파이랩은 맷플롯립 패키지의 모듈입니다.

pylab_examples example code: barh_demo.py | https://matplotlib.org/1.2.1/examples/pylab_examples/barh_demo.html


수평 바 차트를 그려본 결과는 아래와 같습니다. QGIS 파이썬 콘솔에서 넘파이와 맷플롯립 외부 라이브러리를 쓸 수 있기 때문에 가능합니다.

아래는 본 글에 사용한 코드입니다.

# 레이어 지정
layer = iface.activeLayer()
print layer.name()
# 필드명 색인
idx = layer.fieldNameIndex('SITE_NAME')
print idx
# 단일 행과 필드명으로 속성값 선택
fid = 0
request = QgsFeatureRequest().setFilterFid(fid)
f = next(layer.getFeatures(request)) # 0번째 행
print(f.attributes()[idx]) # 'SITE_NAME' 필드
# 다수 행과 필드명으로 속성값 선택
fids = [0, 1, 2, 3, 4]
request = QgsFeatureRequest().setFilterFids(fids)
fs = layer.getFeatures(request)
for f in fs:
    print(f.attributes()[idx])
# 속성값을 배열로 저장
arr = []
fids = [0, 1, 2, 3, 4]
request = QgsFeatureRequest().setFilterFids(fids)
fs = layer.getFeatures(request)
for f in fs:
    arr.append([f.attributes()[2], f.attributes()[5]])
print arr
print str(arr[0][0])
# 넘파이 배열로 변환
import numpy as np
np_arr = np.array(arr)
site_name = np_arr[:,0].astype('str')
print site_name #지역명
ha = np_arr[:,1].astype('float')
print ha # 면적(헥타르)
# 수평 바 차트 그리기(horizontal bar chart)
from pylab import *
pos = arange(5)+.5    # the bar centers on the y axis
barh(pos, ha, align='center')
yticks(pos, site_name)
xlabel('Area (Ha)')
title('Special Area of Conservation (SAC), Ireland')
grid(True)
show()