https://mjs1995.tistory.com/169?category=802136
앞에서 만든 geojson 파일을 가지고 Python folium을 이용한 지도 시각화를 하려고 합니다.
import pandas as pd
import folium
from folium import plugins
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
fontpath = '/usr/share/fonts/truetype/nanum/NanumBarunGothic.ttf'
font = fm.FontProperties(fname=fontpath, size=9)
plt.rc('font', family='NanumBarunGothic')
mpl.font_manager._rebuild()
먼저 필요한 라이브러리를 인포트 합니다.
데이터는 Kosis에 있는 2018년도 시군구별 인구수 데이터를 이용하려고 합니다.
df = pd.read_csv('2018인구수.csv', encoding='cp949')
df['sigun_code']=df['sigun_code'].astype(str)
df.head()
2018년도의 인구수 데이터를 다운받은뒤 encoding을 cp949로 하고 sigun_code를 str형태로 바꾸어 줍니다.
state_geo ='map (7).zip.geojson'
state_geo2 = json.load(open(state_geo, encoding='utf-8'))
다음은 앞 포스팅에서 만든 geojson 파일을 json.load를 이용하여 불러와 들입니다.
시각화 방법에는 여러가지가 있는데 다양한 방법들을 시도해보려고 합니다.
folium의 경우 지도그래프를 그리게 되면 전체적인 부분만 알수있고 그 안에 내용에 대한 설명을 잘 모를 수가 있습니다.
예를 들어 간단한 지도 그래프를 그려보게 되면
지역에 대한 설명이나 어떤 피처에 대한 설명도 알 수 없기때문에 코드를 통해서 이를 보완하려고 합니다.
for idx, sigun_dict in enumerate(state_geo1['features']):
sigun_id = sigun_dict['properties']['merged']
sigun_nmm = df.loc[(df.sigun_code == sigun_id), 'sigun_nm'].iloc[0]
risk = df.loc[(df.sigun_code == sigun_id), '총인구수 (명)'].iloc[0]
people = df.loc[(df.sigun_code == sigun_id), '남자인구수 (명)'].iloc[0]
people_w = df.loc[(df.sigun_code == sigun_id), '여자인구수 (명)'].iloc[0]
txt = f'<b><h4>{sigun_nmm}</h4></b>총인구수(명) :{risk:.2f}<br>남자인구수(명) : {people}<br>여자인구수(명) : {people_w}'
state_geo1['features'][idx]['properties']['tooltip1'] = txt
geojson파일과 내 dataset에 sigun_code를 기준으로 코드를 짜줍니다.
#지도 불러들어오기 중심점 좌표 서울
m = folium.Map(location=[35.8, 127.6], tiles="OpenStreetMap", zoom_start=8)
#지도에 색 적용 및 데이터 연결
choropleth = folium.Choropleth(
geo_data=state_geo1,
name='sigun_people',
data=df,
columns=('sigun_code', '총인구수 (명)'),
key_on='feature.properties.merged',
fill_color='RdYlGn',
fill_opacity=0.7,
line_opacity=0.5,
legend_name='people index'
).add_to(m)
#지도 전체화면 추가코드
plugins.Fullscreen(position='topright',
title='Click to Expand',
title_cancel='Click to Exit',
force_separate_button=True).add_to(m)
#지도 스크롤 가능
plugins.MousePosition().add_to(m)
#지도에 원하는 변수 이름 나오게 하는 코드
choropleth.geojson.add_child(folium.features.GeoJsonTooltip(['tooltip1'], labels=False))
title_html = '<h3 align="center" style="font-size:20px"><b>people index </b></h3>'
m.get_root().html.add_child(folium.Element(title_html))
folium.LayerControl().add_to(m)
m
이렇게 내가 원하는 형태의 지도를 그릴 수 있습니다. 또한 다양한 기능들이 있는데 왼쪽 상단의 +와 -는 지도의 확대 및 축소를 가능하게 합니다. 그리고 마우스를 통해서 스크롤을 할 수 있으며 우측 상단에는 전체화면의 기능이 있습니다.
이를 통해서 내가 지도를 통해 어떤 것을 도출해 낼지 생각할 수 있습니다.
DualMap
#비교 연도 데이터 추가
df1 = pd.read_csv('2017인구수.csv', encoding='cp949')
df1['sigun_code']=df1['sigun_code'].astype(str)
from folium.features import DivIcon
m = folium.plugins.DualMap(location=[35.8, 127.6], tiles="OpenStreetMap", zoom_start=8)
#지도에 색 적용 및 데이터 연결
text_19="2017년 인구수"
text_20="2018년 인구수"
text_lat, text_lng=34,130
choropleth = folium.Choropleth(
geo_data=state_geo1,
name='people',
data=df,
columns=('sigun_code', '총인구수 (명)'),
key_on='feature.properties.merged',
fill_color='RdYlGn',
fill_opacity=0.7,
line_opacity=0.5,
legend_name='people count index'
).add_to(m.m1)
folium.map.Marker( [text_lat + 0.5, text_lng - 1.6],icon=DivIcon(icon_size=(150,36),icon_anchor=(0,0), html= text_19)).add_to(m.m1)
choropleth1 = folium.Choropleth(
geo_data=state_geo1,
name='people diff',
data=df1,
columns=('sigun_code', '총인구수 (명)'),
key_on='feature.properties.merged',
fill_color='YlGnBu',
fill_opacity=0.7,
line_opacity=0.5,
legend_name='people count index'
).add_to(m.m2)
folium.map.Marker( [text_lat + 0.5, text_lng - 1.6],icon=DivIcon(icon_size=(150,36),icon_anchor=(0,0), html= text_20)).add_to(m.m2)
plugins.Fullscreen(position='topright',
title='Click to Expand',
title_cancel='Click to Exit',
force_separate_button=True).add_to(m)
plugins.MousePosition().add_to(m)
choropleth.geojson.add_child(folium.features.GeoJsonTooltip(['tooltip1'], labels=False))
title_html = '<h3 align="center" style="font-size:20px"><b>people count index </b></h3>'
m.get_root().html.add_child(folium.Element(title_html))
folium.LayerControl().add_to(m)
m
DualMap을 이용해서 두 지도를 비교 할 수도 있습니다.
크루스터
ma = pd.read_csv('시군구별좌표.csv',encoding = 'cp949')
regional_count = ma[['latitude','longitude']]
ma.head()
원하는 지역의 위경도 데이터가 있다면 이를 지도로 표시할 수 있습니다.
m = folium.Map(location=[37.55, 127], tiles="OpenStreetMap", zoom_start=10)
choropleth = folium.Choropleth(
geo_data=state_geo1,
name='sigun_people',
data=df,
columns=('sigun_code', '총인구수 (명)'),
key_on='feature.properties.merged',
fill_color='BuPu',
fill_opacity=0.7,
line_opacity=0.5,
legend_name='people index'
).add_to(m)
plugins.Fullscreen(position='topright',
title='Click to Expand',
title_cancel='Click to Exit',
force_separate_button=True).add_to(m)
plugins.MousePosition().add_to(m)
plugins.MarkerCluster(regional_count).add_to(m)
m
Circle
df = pd.read_csv('시군구별좌표1.csv', encoding='cp949')
df.head()
m = folium.Map(location=[37.55, 127], tiles="OpenStreetMap", zoom_start=10)
m.choropleth(
geo_data=state_geo1,
name='people',
data=df,
columns=('sigun_code' , '총인구수 (명)'),
key_on='feature.properties.merged',
fill_color='PuRd',
fill_opacity=0.7,
line_opacity=0.5,
legend_name='people count index'
)
plugins.Fullscreen(position='topright',
title='Click to Expand',
title_cancel='Click to Exit',
force_separate_button=True).add_to(m)
for n in f.index:
folium.CircleMarker([f['latitude'][n],f['longitude'][n]],
radius = df['총인구수 (명)'][n]*20, color = '#3186cc',fill_color='#3186cc').add_to(m)
plugins.MousePosition().add_to(m)
m
CircleMarker를 통해서 지도 시각화를 할 수 도있습니다.
Python에서 folium을 통해서 지도 시각화 하는 여러 방법에 대해 알아보았습니다.
해당 데이터의 목적에 맞게 지도 시각화를 이용하여 인사이트를 얻는다면 데이터 분석에 있어서 좋은 시각화 툴인거 같다는 생각이 들었습니다. 프로젝트를 진행하면서 시군구별로 시각화를 하기 위해서 서치하던중에 folium을 알게 되었으며 공부를 하는데 시간이 그렇게 오래 걸리지 않았으며 하는 내내 재미있었습니다. folium을 더 잘 이용한다면 해당 데이터 분석에서 유익한 인사이트를 창출해 내지 않을까 생각됩니다.
'BI > Python' 카테고리의 다른 글
[python][plotly] geojson을 이용한 지도그리기 (4) (0) | 2021.01.13 |
---|---|
[python][Mapbox] geojson을 이용한 지도그리기 (3) (12) | 2021.01.12 |
[python][지도시각화] 일본 도도부현 시각화 (0) | 2021.01.11 |
[python] 레이더차트 시각화 (2) | 2020.09.23 |
[python][folium] geojson을 이용한 지도그리기 (1) (7) | 2020.09.02 |