이것저것 기록

[python, plotly] Choropleth 지도로 위치/속성 지도 데이터 시각화 하기 본문

코린이/실무를 위한 코딩 기록

[python, plotly] Choropleth 지도로 위치/속성 지도 데이터 시각화 하기

anweh 2021. 4. 12. 16:29

Choropleth 지도 예시

Choropleth 도란 색상이나 패턴을 사용하여 특정 통계에 대한 데이터를 사전 정의된 영역과 관련시켜 시각화 한 지도 유형이다. 

이러한 지도 시각화는 점 데이터로 표현된 정보 보다는, 특정 구역에 대한 통계 데이터를 시각화 하는 데에 적절하다. 

예를 들어, 서울시 구 별 교통사고 건수, 구 별 소득, 등등 '지역 별 통계'를 지도에 시각화 하기 좋다. 

 

 

최근 두 번의 데이터 분석 경진대회를 참가하면서, 의외로 이 choropleth map을 그릴 일이 많았다.

나는 plotly라는 라이브러리를 사용했는데, 이 라이브러리의 다큐멘트가 매우 불친절하다 ^^ 

그리고 이 라이브러리에서도 choropleth 함수를 샘플 데이터와 함께 업로드 한 포스팅을 찾을 수가 없어서, 

엄청 애먹으면서 습득했다... 

 

 

오늘 사용할 코드와, 데이터는 모두 깃헙에 올려놨습니다! 

데이터가 정확히 어떤 구조인지 살펴보고 싶으신 분들은 아래의 깃헙 링크를 참고해주세요~ 

github.com/henewsuh/choropleth_map_viz

 

henewsuh/choropleth_map_viz

plotly라이브러리를 활용하여 choropleth map 시각화. Contribute to henewsuh/choropleth_map_viz development by creating an account on GitHub.

github.com


 

1. 라이브러리 불러오기 

import plotly.express as px
import pandas as pd 
import os 
import json 

plotly는 px로 줄여서 쓰는 게 국룰 

 

 

 

2. 경로 설정 

# 경로 설정
root_path = os.getcwd() # 실행 코드가 있는 곳 
data_path = os.path.join(root_path, 'data') # 실험에 쓰일 데이터가 있는 곳 
os.chdir(data_path)

경로는 상대 경로로 설정해줬다. 

나는 정말.. 블로그에 포스팅 하면서 절대 경로로 올려주시는 분들이 가끔 있던데, 이게 너무 싫다ㅠ

코드랑 데이터가 다른 폴더에 있을 수도 있기 때문이다...

그래서 블로그에 글을 올릴 땐 상대 경로로 올려주는 편이, 제 3자가 이 코드를 reuse할 때 훨씬 편리하다 

 

 

 

3. 데이터 로드 

# 데이터 로드 
geometry_gj = json.load(open('용인시_법정경계(읍면동).geojson', encoding='utf-8'))
car_df = pd.read_csv('경기도_용인시_자동차 등록 현황_읍면동_20190331.csv', encoding='cp949')

여기서부터 꿀팁이다. 난 진짜 이거 몰라서 많이 해맸다. 

plotly의 choropleth로 시각화 하려면, 무조건 'FeatureCollection'형태로 불러와야 한다!!!!!!!!!!!!!!

그러기 위해선 1) 지오메트리가 geojson파일이어야하고 (shp 안됨), 2) json으로 불러와야한다.  (다른 방법이 있다면 댓글 부탁드립니다.)

FeatureCollection 형태로 불러온 geometry파일

 

 

 

4. 데이터 전처리 

# 데이터 전처리 
int_car = [] 
for i in range(len(car_df)): 
    cur_price = car_df.iloc[i]['자가용']
    int_price = int(cur_price.replace(',', ''))
    int_car.append(int_price)
car_df['자가용_int'] = int_car
car_df = car_df.rename(columns={'구  분':'EMD_KOR_NM'})

전처리라고 하긴 했는데, 별 거 없다. 

csv파일의 숫자 데이터가 예를 들어 15400이라면 '15,400' 이런식으로 문자열로 써져있어서, 

여기서 콤마를 제거하고, int 형태로 바꿔줬다. 

 

그리고 한 가지 중요한 것이 나온다. 바로 컬럼명 매칭!!!!

geometry 데이터와 속성정보가 있는 데이터에서 지역을 나타내는 컬럼명이 일치해야한다. (그래야 색이 칠해져요) 

우리는 geometry_gj의 properties안에 있는 'EMD_KOR_NM'과 car_df의 '구   분' 컬럼이 서로 같은 지역을 나타내는 것이므로, car_df의 '구   분' 컬럼명을 'EMD_KOR_NM'으로 변경해주었다. 

 

 

 

5. Choropleth 시각화 

# Choropleth 시각화
fig = px.choropleth(car_df, geojson=geometry_gj, locations='EMD_KOR_NM', color='자가용_int',
                                color_continuous_scale='Blues',
                                featureidkey='properties.EMD_KOR_NM')
fig.update_geos(fitbounds="locations", visible=False)
fig.update_layout(title_text='용인시 법정동 별 자가용 등록 대수', title_font_size=20)

자, 여기서 중요한 것이 또 있다. 바로 'update_geos'!!! 

만약에 update_geos를 해주지 않는다면, 지도가 제대로 안 보일수도 있다. 

그러니까, geometry를 내가 개인적으로 설정해준 경우는 항상 update_geos 코드 줄을 작성해주어야 한다. 

 

 

 

6. 시각화 파일 저장 

# 시각화 파일 저장 
os.chdir('../')
fig.write_image('choropleth.png')

결과 파일

Comments