데이터 사이언스 05 지도데이터 처리1
1. 도구들
1) Pandas 데이터 핸들링
2) 시각화 도구 1 : matplotlib
3) 시각화 도구 2: seaborn
4) 지도 시각화
(1) folium
folium 공식문서 지도시각화 갤러리 서울지도 시각화 - 임재곤의 블로그 Python으로 만드는 시각화::공간시각화::지도시각화 만들기 D3를 이용한 서울시내 맛집 시각화 (feat. 식신로드) - Lucy Park
(2) SHP 포맷
SHP(Shape file) 포맷 : GIS(지리정보시스템) : ESRI 개발
(3) SHP to GeoJSON
GeoJSON포맷으로 바꾸기 for Web ⬅ SHP(Shape file) 포맷
(4) grid map (Square Tile Grid Map)
ESRI 혜식이의 떼로 보는 세상 A semi-automatic way to create your own grid map Square Tile grid map
5) 웹 페이지 정보 읽어오기 1 - BeautifulSoup
6) 웹 페이지 정보 읽어오기 2 - Selenium
2. 한국 인구 소멸 위기 지역 - 지도 시각화
1) 개념 정의 - 인구소멸위기지역
- 65세 이상 인구가 19세에서 39세 여성 인구보다 두 배 이상 많은 지역
2) folium으로 지도 시각화 하기
- ➀ 지역별 고유 id 부여하기
- ➁ 지역 경계선 json 파일 얻기
- ➂ 이에 대응하는 인구현황 데이터에 지역별 고유 id를 부여하기
3) 지역별 인구 데이터 얻기
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
# 한글폰트 적용
import matplotlib.font_manager as fm
font_location = '/usr/share/fonts/truetype/nanum/NanumBarunGothic.ttf'
font_name = fm.FontProperties(fname=font_location).get_name()
from matplotlib import rc
rc('font', family=font_name)
population = pd.read_excel('./data_science/05. population_raw_data.xlsx', header=1)
population.head()
행정구역(동읍면)별(1) | 행정구역(동읍면)별(2) | 항목 | 계 | 20 - 24세 | 25 - 29세 | 30 - 34세 | 35 - 39세 | 65 - 69세 | 70 - 74세 | 75 - 79세 | 80 - 84세 | 85 - 89세 | 90 - 94세 | 95 - 99세 | 100+ | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 전국 | 소계 | 총인구수 (명) | 51696216.0 | 3541061.0 | 3217367.0 | 3517868 | 4016272.0 | 2237345.0 | 1781229.0 | 1457890 | 909130.0 | 416164.0 | 141488.0 | 34844 | 17562.0 |
1 | NaN | NaN | 남자인구수 (명) | 25827594.0 | 1877127.0 | 1682988.0 | 1806754 | 2045265.0 | 1072395.0 | 806680.0 | 600607 | 319391.0 | 113221.0 | 32695.0 | 7658 | 4137.0 |
2 | NaN | NaN | 여자인구수 (명) | 25868622.0 | 1663934.0 | 1534379.0 | 1711114 | 1971007.0 | 1164950.0 | 974549.0 | 857283 | 589739.0 | 302943.0 | 108793.0 | 27186 | 13425.0 |
3 | 서울특별시 | 소계 | 총인구수 (명) | 9930616.0 | 690728.0 | 751973.0 | 803507 | 817467.0 | 448956.0 | 350580.0 | 251961 | 141649.0 | 66067.0 | 24153.0 | 7058 | 5475.0 |
4 | NaN | NaN | 남자인구수 (명) | 4876789.0 | 347534.0 | 372249.0 | 402358 | 410076.0 | 211568.0 | 163766.0 | 112076 | 54033.0 | 19595.0 | 6146.0 | 1900 | 1406.0 |
# Nan 부분을 채우기
population.fillna(
method='pad',
inplace=True
)
# column 제목 바꾸기
population.rename(
columns = {
'행정구역(동읍면)별(1)' : '광역시도',
'행정구역(동읍면)별(2)' : '시도',
'계' : '인구수'
},
inplace=True
)
population.head()
광역시도 | 시도 | 항목 | 인구수 | 20 - 24세 | 25 - 29세 | 30 - 34세 | 35 - 39세 | 65 - 69세 | 70 - 74세 | 75 - 79세 | 80 - 84세 | 85 - 89세 | 90 - 94세 | 95 - 99세 | 100+ | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 전국 | 소계 | 총인구수 (명) | 51696216.0 | 3541061.0 | 3217367.0 | 3517868 | 4016272.0 | 2237345.0 | 1781229.0 | 1457890 | 909130.0 | 416164.0 | 141488.0 | 34844 | 17562.0 |
1 | 전국 | 소계 | 남자인구수 (명) | 25827594.0 | 1877127.0 | 1682988.0 | 1806754 | 2045265.0 | 1072395.0 | 806680.0 | 600607 | 319391.0 | 113221.0 | 32695.0 | 7658 | 4137.0 |
2 | 전국 | 소계 | 여자인구수 (명) | 25868622.0 | 1663934.0 | 1534379.0 | 1711114 | 1971007.0 | 1164950.0 | 974549.0 | 857283 | 589739.0 | 302943.0 | 108793.0 | 27186 | 13425.0 |
3 | 서울특별시 | 소계 | 총인구수 (명) | 9930616.0 | 690728.0 | 751973.0 | 803507 | 817467.0 | 448956.0 | 350580.0 | 251961 | 141649.0 | 66067.0 | 24153.0 | 7058 | 5475.0 |
4 | 서울특별시 | 소계 | 남자인구수 (명) | 4876789.0 | 347534.0 | 372249.0 | 402358 | 410076.0 | 211568.0 | 163766.0 | 112076 | 54033.0 | 19595.0 | 6146.0 | 1900 | 1406.0 |
# '소계' 부분 없애기
population = population[ population['시도'] != '소계' ]
population.head()
광역시도 | 시도 | 항목 | 인구수 | 20 - 24세 | 25 - 29세 | 30 - 34세 | 35 - 39세 | 65 - 69세 | 70 - 74세 | 75 - 79세 | 80 - 84세 | 85 - 89세 | 90 - 94세 | 95 - 99세 | 100+ | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
6 | 서울특별시 | 종로구 | 총인구수 (명) | 152737.0 | 11379.0 | 11891.0 | 10684 | 10379.0 | 7411.0 | 6636.0 | 5263 | 3104.0 | 1480.0 | 602.0 | 234 | 220.0 |
7 | 서울특별시 | 종로구 | 남자인구수 (명) | 75201.0 | 5620.0 | 6181.0 | 5387 | 5034.0 | 3411.0 | 3009.0 | 2311 | 1289.0 | 506.0 | 207.0 | 89 | 73.0 |
8 | 서울특별시 | 종로구 | 여자인구수 (명) | 77536.0 | 5759.0 | 5710.0 | 5297 | 5345.0 | 4000.0 | 3627.0 | 2952 | 1815.0 | 974.0 | 395.0 | 145 | 147.0 |
9 | 서울특별시 | 중구 | 총인구수 (명) | 125249.0 | 8216.0 | 9529.0 | 10332 | 10107.0 | 6399.0 | 5313.0 | 4127 | 2502.0 | 1260.0 | 469.0 | 158 | 160.0 |
10 | 서울특별시 | 중구 | 남자인구수 (명) | 62204.0 | 4142.0 | 4792.0 | 5192 | 5221.0 | 3113.0 | 2405.0 | 1752 | 929.0 | 414.0 | 132.0 | 56 | 51.0 |
population.loc[ population['항목'] == '총인구수 (명)', '항목' ] = '합계'
population.loc[ population['항목'] == '여자인구수 (명)', '항목' ] = '여자'
population.loc[ population['항목'] == '남자인구수 (명)', '항목' ] = '남자'
population.head()
광역시도 | 시도 | 항목 | 인구수 | 20 - 24세 | 25 - 29세 | 30 - 34세 | 35 - 39세 | 65 - 69세 | 70 - 74세 | 75 - 79세 | 80 - 84세 | 85 - 89세 | 90 - 94세 | 95 - 99세 | 100+ | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
6 | 서울특별시 | 종로구 | 합계 | 152737.0 | 11379.0 | 11891.0 | 10684 | 10379.0 | 7411.0 | 6636.0 | 5263 | 3104.0 | 1480.0 | 602.0 | 234 | 220.0 |
7 | 서울특별시 | 종로구 | 남자 | 75201.0 | 5620.0 | 6181.0 | 5387 | 5034.0 | 3411.0 | 3009.0 | 2311 | 1289.0 | 506.0 | 207.0 | 89 | 73.0 |
8 | 서울특별시 | 종로구 | 여자 | 77536.0 | 5759.0 | 5710.0 | 5297 | 5345.0 | 4000.0 | 3627.0 | 2952 | 1815.0 | 974.0 | 395.0 | 145 | 147.0 |
9 | 서울특별시 | 중구 | 합계 | 125249.0 | 8216.0 | 9529.0 | 10332 | 10107.0 | 6399.0 | 5313.0 | 4127 | 2502.0 | 1260.0 | 469.0 | 158 | 160.0 |
10 | 서울특별시 | 중구 | 남자 | 62204.0 | 4142.0 | 4792.0 | 5192 | 5221.0 | 3113.0 | 2405.0 | 1752 | 929.0 | 414.0 | 132.0 | 56 | 51.0 |
4) 데이터 가공 - 인구소멸위기지역
- 20 ~ 39세 여성 인구
- 65세 이상 인구
- pandas.pivot_table( data, index=[ '광역시도', '시도' ], columns=[ '항목' ], values=[ '인구수', '20-39세', '65세 이상' ] )
- data.reset_index( inplace=True )
population['20-39세'] = population['20 - 24세'] + population['25 - 29세'] + population['30 - 34세'] + population['35 - 39세']
population['65세 이상'] = population['65 - 69세'] + population['70 - 74세'] + population['75 - 79세'] + population['80 - 84세'] \
+ population['85 - 89세'] + population['90 - 94세'] + population['95 - 99세'] + population['100+']
population.head()
광역시도 | 시도 | 항목 | 인구수 | 20 - 24세 | 25 - 29세 | 30 - 34세 | 35 - 39세 | 65 - 69세 | 70 - 74세 | 75 - 79세 | 80 - 84세 | 85 - 89세 | 90 - 94세 | 95 - 99세 | 100+ | 20-39세 | 65세 이상 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
6 | 서울특별시 | 종로구 | 합계 | 152737.0 | 11379.0 | 11891.0 | 10684 | 10379.0 | 7411.0 | 6636.0 | 5263 | 3104.0 | 1480.0 | 602.0 | 234 | 220.0 | 44333.0 | 24950.0 |
7 | 서울특별시 | 종로구 | 남자 | 75201.0 | 5620.0 | 6181.0 | 5387 | 5034.0 | 3411.0 | 3009.0 | 2311 | 1289.0 | 506.0 | 207.0 | 89 | 73.0 | 22222.0 | 10895.0 |
8 | 서울특별시 | 종로구 | 여자 | 77536.0 | 5759.0 | 5710.0 | 5297 | 5345.0 | 4000.0 | 3627.0 | 2952 | 1815.0 | 974.0 | 395.0 | 145 | 147.0 | 22111.0 | 14055.0 |
9 | 서울특별시 | 중구 | 합계 | 125249.0 | 8216.0 | 9529.0 | 10332 | 10107.0 | 6399.0 | 5313.0 | 4127 | 2502.0 | 1260.0 | 469.0 | 158 | 160.0 | 38184.0 | 20388.0 |
10 | 서울특별시 | 중구 | 남자 | 62204.0 | 4142.0 | 4792.0 | 5192 | 5221.0 | 3113.0 | 2405.0 | 1752 | 929.0 | 414.0 | 132.0 | 56 | 51.0 | 19347.0 | 8852.0 |
pop = pd.pivot_table(
population,
index=['광역시도', '시도'],
columns=['항목'],
values=['인구수', '20-39세', '65세 이상']
)
pop.head()
20-39세 | 65세 이상 | 인구수 | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
항목 | 남자 | 여자 | 합계 | 남자 | 여자 | 합계 | 남자 | 여자 | 합계 | |
광역시도 | 시도 | |||||||||
강원도 | 강릉시 | 26286.0 | 23098.0 | 49384.0 | 15767.0 | 21912.0 | 37679.0 | 106231.0 | 107615.0 | 213846.0 |
고성군 | 4494.0 | 2529.0 | 7023.0 | 2900.0 | 4251.0 | 7151.0 | 15899.0 | 14215.0 | 30114.0 | |
동해시 | 11511.0 | 9753.0 | 21264.0 | 6392.0 | 8732.0 | 15124.0 | 47166.0 | 46131.0 | 93297.0 | |
삼척시 | 8708.0 | 7115.0 | 15823.0 | 5892.0 | 8718.0 | 14610.0 | 35253.0 | 34346.0 | 69599.0 | |
속초시 | 9956.0 | 8752.0 | 18708.0 | 5139.0 | 7613.0 | 12752.0 | 40288.0 | 41505.0 | 81793.0 |
pop['소멸비율'] = 2 * pop['20-39세', '여자'] / ( pop['65세 이상', '합계'] )
pop.head()
20-39세 | 65세 이상 | 인구수 | 소멸비율 | ||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
항목 | 남자 | 여자 | 합계 | 남자 | 여자 | 합계 | 남자 | 여자 | 합계 | ||
광역시도 | 시도 | ||||||||||
강원도 | 강릉시 | 26286.0 | 23098.0 | 49384.0 | 15767.0 | 21912.0 | 37679.0 | 106231.0 | 107615.0 | 213846.0 | 1.226041 |
고성군 | 4494.0 | 2529.0 | 7023.0 | 2900.0 | 4251.0 | 7151.0 | 15899.0 | 14215.0 | 30114.0 | 0.707314 | |
동해시 | 11511.0 | 9753.0 | 21264.0 | 6392.0 | 8732.0 | 15124.0 | 47166.0 | 46131.0 | 93297.0 | 1.289738 | |
삼척시 | 8708.0 | 7115.0 | 15823.0 | 5892.0 | 8718.0 | 14610.0 | 35253.0 | 34346.0 | 69599.0 | 0.973990 | |
속초시 | 9956.0 | 8752.0 | 18708.0 | 5139.0 | 7613.0 | 12752.0 | 40288.0 | 41505.0 | 81793.0 | 1.372647 |
pop['소멸위기지역'] = pop['소멸비율'] < 1.0
pop.head()
20-39세 | 65세 이상 | 인구수 | 소멸비율 | 소멸위기지역 | ||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
항목 | 남자 | 여자 | 합계 | 남자 | 여자 | 합계 | 남자 | 여자 | 합계 | |||
광역시도 | 시도 | |||||||||||
강원도 | 강릉시 | 26286.0 | 23098.0 | 49384.0 | 15767.0 | 21912.0 | 37679.0 | 106231.0 | 107615.0 | 213846.0 | 1.226041 | False |
고성군 | 4494.0 | 2529.0 | 7023.0 | 2900.0 | 4251.0 | 7151.0 | 15899.0 | 14215.0 | 30114.0 | 0.707314 | True | |
동해시 | 11511.0 | 9753.0 | 21264.0 | 6392.0 | 8732.0 | 15124.0 | 47166.0 | 46131.0 | 93297.0 | 1.289738 | False | |
삼척시 | 8708.0 | 7115.0 | 15823.0 | 5892.0 | 8718.0 | 14610.0 | 35253.0 | 34346.0 | 69599.0 | 0.973990 | True | |
속초시 | 9956.0 | 8752.0 | 18708.0 | 5139.0 | 7613.0 | 12752.0 | 40288.0 | 41505.0 | 81793.0 | 1.372647 | False |
pop.reset_index( inplace=True )
pop.head()
광역시도 | 시도 | 20-39세 | 65세 이상 | 인구수 | 소멸비율 | 소멸위기지역 | |||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
항목 | 남자 | 여자 | 합계 | 남자 | 여자 | 합계 | 남자 | 여자 | 합계 | ||||
0 | 강원도 | 강릉시 | 26286.0 | 23098.0 | 49384.0 | 15767.0 | 21912.0 | 37679.0 | 106231.0 | 107615.0 | 213846.0 | 1.226041 | False |
1 | 강원도 | 고성군 | 4494.0 | 2529.0 | 7023.0 | 2900.0 | 4251.0 | 7151.0 | 15899.0 | 14215.0 | 30114.0 | 0.707314 | True |
2 | 강원도 | 동해시 | 11511.0 | 9753.0 | 21264.0 | 6392.0 | 8732.0 | 15124.0 | 47166.0 | 46131.0 | 93297.0 | 1.289738 | False |
3 | 강원도 | 삼척시 | 8708.0 | 7115.0 | 15823.0 | 5892.0 | 8718.0 | 14610.0 | 35253.0 | 34346.0 | 69599.0 | 0.973990 | True |
4 | 강원도 | 속초시 | 9956.0 | 8752.0 | 18708.0 | 5139.0 | 7613.0 | 12752.0 | 40288.0 | 41505.0 | 81793.0 | 1.372647 | False |
# coloumn title 다듬기
tmp_columns = [
pop.columns.get_level_values(0)[n] + pop.columns.get_level_values(1)[n]
for n in range(0, len(pop.columns.get_level_values(0)))
]
tmp_columns
['광역시도',
'시도',
'20-39세남자',
'20-39세여자',
'20-39세합계',
'65세 이상남자',
'65세 이상여자',
'65세 이상합계',
'인구수남자',
'인구수여자',
'인구수합계',
'소멸비율',
'소멸위기지역']
pop.columns = tmp_columns
pop.head()
광역시도 | 시도 | 20-39세남자 | 20-39세여자 | 20-39세합계 | 65세 이상남자 | 65세 이상여자 | 65세 이상합계 | 인구수남자 | 인구수여자 | 인구수합계 | 소멸비율 | 소멸위기지역 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 강원도 | 강릉시 | 26286.0 | 23098.0 | 49384.0 | 15767.0 | 21912.0 | 37679.0 | 106231.0 | 107615.0 | 213846.0 | 1.226041 | False |
1 | 강원도 | 고성군 | 4494.0 | 2529.0 | 7023.0 | 2900.0 | 4251.0 | 7151.0 | 15899.0 | 14215.0 | 30114.0 | 0.707314 | True |
2 | 강원도 | 동해시 | 11511.0 | 9753.0 | 21264.0 | 6392.0 | 8732.0 | 15124.0 | 47166.0 | 46131.0 | 93297.0 | 1.289738 | False |
3 | 강원도 | 삼척시 | 8708.0 | 7115.0 | 15823.0 | 5892.0 | 8718.0 | 14610.0 | 35253.0 | 34346.0 | 69599.0 | 0.973990 | True |
4 | 강원도 | 속초시 | 9956.0 | 8752.0 | 18708.0 | 5139.0 | 7613.0 | 12752.0 | 40288.0 | 41505.0 | 81793.0 | 1.372647 | False |
len(pop['시도'])
264
5) 시각화 전 처리 - 지역에 고유 id 부여하기
- 시/군 개념을 유지하되, 광역시는 구로 나누고, 광역시 아닌 시 중 구를 가진 곳 또한 구로 단위를 나눈다.
- 예) 서울 중구 / 서울 서초 / 통영 / 남양주 / 포항 북구 / 인천 남동 / 안양 만안 / 안산 단원
si_name = []
tmp_gu_list = ['장안구', '권선구', '팔달구', '영통구',
'수정구', '중원구', '분당구',
'만안구', '동안구',
'상록구', '단원구',
'덕양구', '일산동구', '일산서구',
'처인구', '기흥구', '수지구',
'상당구', '서원구', '흥덕구', '청원구',
'동남구', '서북구',
'완산구', '덕진구',
'남구', '북구',
'의창구', '성산구', '진해구',
'마산합포구', '마산회원구',
'오정구', '원미구', '소사구']
for n in pop.index:
if pop['광역시도'][n][-3:] not in ['광역시', '특별시', '자치시']:
if pop['시도'][n] in tmp_gu_list:
#['장안구', '권선구', '팔달구', '영통구']:
if pop['시도'][n] in tmp_gu_list[:4]:
si_name.append('수원' + ' ' + pop['시도'][n][:-1])
#['수정구', '중원구', '분당구']:
elif pop['시도'][n] in tmp_gu_list[4:7]:
si_name.append('성남' + ' ' + pop['시도'][n][:-1])
#['만안구', '동안구']:
elif pop['시도'][n] in tmp_gu_list[7:9]:
si_name.append('안양' + ' ' + pop['시도'][n][:-1])
#['상록구', '단원구']:
elif pop['시도'][n] in tmp_gu_list[9:11]:
si_name.append('안산' + ' ' + pop['시도'][n][:-1])
#['덕양구', '일산동구', '일산서구']:
elif pop['시도'][n] in tmp_gu_list[11:14]:
si_name.append('고양' + ' ' + pop['시도'][n][:-1])
#['처인구', '기흥구', '수지구']:
elif pop['시도'][n] in tmp_gu_list[14:17]:
si_name.append('용인' + ' ' + pop['시도'][n][:-1])
#['상당구', '서원구', '흥덕구', '청원구']:
elif pop['시도'][n] in tmp_gu_list[17:21]:
si_name.append('청주' + ' ' + pop['시도'][n][:-1])
#['동남구', '서북구']:
elif pop['시도'][n] in tmp_gu_list[21:23]:
si_name.append('천안' + ' ' + pop['시도'][n][:-1])
#['완산구', '덕진구']:
elif pop['시도'][n] in tmp_gu_list[23:25]:
si_name.append('전주' + ' ' + pop['시도'][n][:-1])
#['남구', '북구']:
elif pop['시도'][n] in tmp_gu_list[25:27]:
si_name.append('포항' + ' ' + pop['시도'][n])
#['의창구', '성산구', '진해구']:
elif pop['시도'][n] in tmp_gu_list[27:30]:
si_name.append('창원' + ' ' + pop['시도'][n][:-1])
#['마산합포구', '마산회원구']:
elif pop['시도'][n] in tmp_gu_list[30:32]:
si_name.append('창원' + ' ' + pop['시도'][n][2:-1])
#['소사구', '오정구', '원미구']:
elif pop['시도'][n] in tmp_gu_list[32:35]:
si_name.append('부천' + ' ' + pop['시도'][n][:-1])
else:
if pop['시도'][n][:-1]=='고성' and pop['광역시도'][n]=='강원도':
si_name.append('고성(강원)')
elif pop['시도'][n][:-1]=='고성' and pop['광역시도'][n]=='경상남도':
si_name.append('고성(경남)')
else:
si_name.append(pop['시도'][n][:-1])
elif pop['광역시도'][n] == '세종특별자치시':
si_name.append('세종')
else:
if len(pop['시도'][n])==2:
si_name.append(pop['광역시도'][n][:2] + ' ' + pop['시도'][n])
else:
si_name.append(pop['광역시도'][n][:2] + ' ' + pop['시도'][n][:-1])
len(si_name)
264
pop.tail()
광역시도 | 시도 | 20-39세남자 | 20-39세여자 | 20-39세합계 | 65세 이상남자 | 65세 이상여자 | 65세 이상합계 | 인구수남자 | 인구수여자 | 인구수합계 | 소멸비율 | 소멸위기지역 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
259 | 충청북도 | 진천군 | 9391.0 | 7622.0 | 17013.0 | 4731.0 | 6575.0 | 11306.0 | 36387.0 | 33563.0 | 69950.0 | 1.348311 | False |
260 | 충청북도 | 청원구 | 32216.0 | 27805.0 | 60021.0 | 8417.0 | 11914.0 | 20331.0 | 97006.0 | 93807.0 | 190813.0 | 2.735232 | False |
261 | 충청북도 | 청주시 | 128318.0 | 115719.0 | 244037.0 | 37882.0 | 53671.0 | 91553.0 | 419323.0 | 415874.0 | 835197.0 | 2.527913 | False |
262 | 충청북도 | 충주시 | 26600.0 | 22757.0 | 49357.0 | 14407.0 | 20383.0 | 34790.0 | 104877.0 | 103473.0 | 208350.0 | 1.308249 | False |
263 | 충청북도 | 흥덕구 | 40933.0 | 37675.0 | 78608.0 | 9788.0 | 13671.0 | 23459.0 | 127647.0 | 125916.0 | 253563.0 | 3.211987 | False |
pop['ID'] = si_name
pop.head()
광역시도 | 시도 | 20-39세남자 | 20-39세여자 | 20-39세합계 | 65세 이상남자 | 65세 이상여자 | 65세 이상합계 | 인구수남자 | 인구수여자 | 인구수합계 | 소멸비율 | 소멸위기지역 | ID | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 강원도 | 강릉시 | 26286.0 | 23098.0 | 49384.0 | 15767.0 | 21912.0 | 37679.0 | 106231.0 | 107615.0 | 213846.0 | 1.226041 | False | 강릉 |
1 | 강원도 | 고성군 | 4494.0 | 2529.0 | 7023.0 | 2900.0 | 4251.0 | 7151.0 | 15899.0 | 14215.0 | 30114.0 | 0.707314 | True | 고성(강원) |
2 | 강원도 | 동해시 | 11511.0 | 9753.0 | 21264.0 | 6392.0 | 8732.0 | 15124.0 | 47166.0 | 46131.0 | 93297.0 | 1.289738 | False | 동해 |
3 | 강원도 | 삼척시 | 8708.0 | 7115.0 | 15823.0 | 5892.0 | 8718.0 | 14610.0 | 35253.0 | 34346.0 | 69599.0 | 0.973990 | True | 삼척 |
4 | 강원도 | 속초시 | 9956.0 | 8752.0 | 18708.0 | 5139.0 | 7613.0 | 12752.0 | 40288.0 | 41505.0 | 81793.0 | 1.372647 | False | 속초 |
6) Square Tile Grid Map 만들기
- 각 행정구역의 화면상 좌표를 얻기위해 pivot_table의 반대개념으로
.stack()
명령을 사용한다 - 그리고 인덱스를 재설정하고
- 컬럼의 이름을 다시 설정한다.
draw_korea_raw = pd.read_excel(
'./data_science/05. draw_korea_raw.xlsx',
encoding='EUC-KR'
)
draw_korea_raw
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 철원 | 화천 | 양구 | 고성(강원) | NaN | NaN | NaN |
1 | NaN | NaN | NaN | 양주 | 동두천 | 연천 | 포천 | 의정부 | 인제 | 춘천 | 속초 | NaN | NaN | NaN |
2 | NaN | NaN | NaN | 고양 덕양 | 고양 일산동 | 서울 도봉 | 서울 노원 | 남양주 | 홍천 | 횡성 | 양양 | NaN | NaN | NaN |
3 | NaN | NaN | 파주 | 고양 일산서 | 김포 | 서울 강북 | 서울 성북 | 가평 | 구리 | 하남 | 정선 | 강릉 | NaN | NaN |
4 | NaN | NaN | 부천 소사 | 안양 만안 | 광명 | 서울 서대문 | 서울 종로 | 서울 동대문 | 서울 중랑 | 양평 | 태백 | 동해 | NaN | NaN |
5 | NaN | 인천 강화 | 부천 원미 | 안양 동안 | 서울 은평 | 서울 마포 | 서울 중구 | 서울 성동 | 서울 강동 | 여주 | 원주 | 삼척 | NaN | NaN |
6 | NaN | 인천 서구 | 부천 오정 | 시흥 | 서울 강서 | 서울 동작 | 서울 용산 | 서울 광진 | 서울 송파 | 이천 | 평창 | 울진 | NaN | NaN |
7 | NaN | 인천 동구 | 인천 계양 | 안산 상록 | 서울 양천 | 서울 관악 | 서울 서초 | 성남 중원 | 과천 | 광주 | 영월 | 영덕 | NaN | NaN |
8 | NaN | NaN | 인천 부평 | 안산 단원 | 서울 영등포 | 서울 금천 | 서울 강남 | 성남 분당 | 성남 수정 | 용인 수지 | 문경 | 봉화 | NaN | 울릉 |
9 | NaN | 인천 중구 | 인천 남구 | 화성 | 서울 구로 | 군포 | 의왕 | 수원 영통 | 용인 기흥 | 용인 처인 | 안동 | 영양 | NaN | NaN |
10 | 인천 옹진 | 인천 연수 | 인천 남동 | 오산 | 안성 | 수원 권선 | 수원 장안 | 제천 | 예천 | 영주 | 구미 | 청송 | 포항 북구 | NaN |
11 | 태안 | 아산 | 천안 동남 | 천안 서북 | 평택 | 음성 | 수원 팔달 | 단양 | 상주 | 김천 | 군위 | 의성 | 포항 남구 | NaN |
12 | NaN | 당진 | 홍성 | 예산 | 공주 | 진천 | 충주 | 청주 흥덕 | 괴산 | 칠곡 | 영천 | 경산 | 경주 | NaN |
13 | NaN | 서산 | 보령 | 청양 | 세종 | 대전 대덕 | 증평 | 청주 청원 | 보은 | 고령 | 청도 | 성주 | 울산 북구 | NaN |
14 | NaN | NaN | 부여 | 논산 | 계룡 | 대전 동구 | 청주 상당 | 청주 서원 | 대구 북구 | 대구 중구 | 대구 수성 | 울산 울주 | 울산 동구 | NaN |
15 | NaN | NaN | 서천 | 금산 | 대전 유성 | 대전 중구 | 옥천 | 영동 | 대구 서구 | 대구 남구 | 대구 동구 | 울산 중구 | 울산 남구 | NaN |
16 | NaN | NaN | 군산 | 익산 | 대전 서구 | 무주 | 거창 | 합천 | 대구 달서 | 대구 달성 | 부산 금정 | 부산 동래 | 부산 기장 | NaN |
17 | NaN | NaN | 부안 | 김제 | 완주 | 장수 | 함양 | 창녕 | 밀양 | 부산 북구 | 부산 부산진 | 부산 연제 | 부산 해운대 | NaN |
18 | NaN | 고창 | 정읍 | 전주 덕진 | 진안 | 남원 | 진주 | 의령 | 부산 강서 | 부산 사상 | 부산 동구 | 부산 중구 | NaN | NaN |
19 | NaN | 영광 | 장성 | 전주 완산 | 임실 | 산청 | 함안 | 양산 | 창원 합포 | 부산 서구 | 부산 사하 | 부산 남구 | NaN | NaN |
20 | NaN | 함평 | 담양 | 순창 | 구례 | 하동 | 창원 의창 | 창원 성산 | 창원 진해 | 김해 | 부산 영도 | 부산 수영 | NaN | NaN |
21 | 신안 | 무안 | 광주 광산 | 곡성 | 화순 | 광양 | 사천 | 창원 회원 | 통영 | NaN | NaN | NaN | NaN | NaN |
22 | 목포 | 나주 | 광주 서구 | 광주 북구 | 순천 | 고흥 | 남해 | 고성(경남) | 거제 | NaN | NaN | NaN | NaN | NaN |
23 | 해남 | 영암 | 광주 남구 | 광주 동구 | 여수 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
24 | 진도 | 강진 | 장흥 | 보성 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
25 | NaN | NaN | 완도 | NaN | NaN | 제주 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
26 | NaN | NaN | NaN | NaN | NaN | 서귀포 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
# 행정구역상 좌표 얻기 : .stack()
draw_korea_raw_stacked = pd.DataFrame( draw_korea_raw.stack() )
draw_korea_raw_stacked.head()
0 | ||
---|---|---|
0 | 7 | 철원 |
8 | 화천 | |
9 | 양구 | |
10 | 고성(강원) | |
1 | 3 | 양주 |
# 인덱스 재설정
draw_korea_raw_stacked.reset_index( inplace=True )
draw_korea_raw_stacked.head()
level_0 | level_1 | 0 | |
---|---|---|---|
0 | 0 | 7 | 철원 |
1 | 0 | 8 | 화천 |
2 | 0 | 9 | 양구 |
3 | 0 | 10 | 고성(강원) |
4 | 1 | 3 | 양주 |
# column 이름 재설정
draw_korea_raw_stacked.rename(
columns = {
'level_0' : 'y',
'level_1' : 'x',
0 : 'ID'
},
inplace=True
)
draw_korea = draw_korea_raw_stacked
draw_korea.head()
y | x | ID | |
---|---|---|---|
0 | 0 | 7 | 철원 |
1 | 0 | 8 | 화천 |
2 | 0 | 9 | 양구 |
3 | 0 | 10 | 고성(강원) |
4 | 1 | 3 | 양주 |
# 저장
draw_korea.to_csv('./data_ouput/05.draw_korea.csv', encoding='utf-8', sep=',' )
BORDER_LINES = [
# 인천
[(5, 1), (5,2), (7,2), (7,3), (11,3), (11,0)],
# 서울
[(5,4), (5,5), (2,5), (2,7), (4,7), (4,9), (7,9),
(7,7), (9,7), (9,5), (10,5), (10,4), (5,4)],
# 경기도
[(1,7), (1,8), (3,8), (3,10), (10,10), (10,7),
(12,7), (12,6), (11,6), (11,5), (12, 5), (12,4),
(11,4), (11,3)],
# 강원도
[(8,10), (8,11), (6,11), (6,12)],
# 충청북도
[(12,5), (13,5), (13,4), (14,4), (14,5), (15,5),
(15,4), (16,4), (16,2)],
# 전라북도
[(16,4), (17,4), (17,5), (16,5), (16,6), (19,6),
(19,5), (20,5), (20,4), (21,4), (21,3), (19,3), (19,1)],
# 대전시
[(13,5), (13,6), (16,6)],
#세종시
[(13,5), (14,5)],
#광주
[(21,2), (21,3), (22,3), (22,4), (24,4), (24,2), (21,2)],
#전라남도
[(20,5), (21,5), (21,6), (23,6)],
#충청북도
[(10,8), (12,8), (12,9), (14,9), (14,8), (16,8), (16,6)],
#경상북도
[(14,9), (14,11), (14,12), (13,12), (13,13)],
#대구
[(15,8), (17,8), (17,10), (16,10), (16,11), (14,11)],
#부산
[(17,9), (18,9), (18,8), (19,8), (19,9), (20,9), (20,10), (21,10)],
#울산
[(16,11), (16,13)],
# [(9,14), (9,15)],
[(27,5), (27,6), (25,6)],
]
plt.figure( figsize=(8, 11) )
# 지역 이름 표시
for idx, row in draw_korea.iterrows():
# 광역시는 구 이름이 겹치는 경우가 많아서 시단위 이름을 같이 표시한다.
if len( row['ID'].split() ) ==2:
display_name = '{}\n{}'.format(row['ID'].split()[0], row['ID'].split()[1])
elif row['ID'][:2] =='고성':
display_name = '고성'
else:
display_name = row['ID']
# 서대문구, 서귀포시 같이 이름이 3자 이상인 경우에 작은 글자로 표시한다
if len(display_name.splitlines()[-1]) >= 3:
fontsize, linespacing = 9.5, 1.5
else:
fontsize, linespacing = 11, 1.2
plt.annotate(
display_name,
(row['x']+0.5, row['y']+0.5),
weight='bold',
fontsize=fontsize,
ha='center',
va='center',
linespacing=linespacing
)
# 시도 경계를 그린다.
for path in BORDER_LINES:
ys, xs = zip(*path)
plt.plot(xs, ys, c='black', lw=1.5)
plt.gca().invert_yaxis()
plt.axis('off')
plt.tight_layout()
plt.show()
# 지역 ID 고유성 유지
set(draw_korea['ID'].unique()) - set(pop['ID'].unique())
set()
set(pop['ID'].unique()) - set(draw_korea['ID'].unique())
{'고양', '부천', '성남', '수원', '안산', '안양', '용인', '전주', '창원', '천안', '청주', '포항'}
tmp_list = list(
set(pop['ID'].unique()) - set(draw_korea['ID'].unique())
)
for tmp in tmp_list:
pop = pop.drop(
pop[ pop['ID'] == tmp ].index
)
pop.head()
광역시도 | 시도 | 20-39세남자 | 20-39세여자 | 20-39세합계 | 65세 이상남자 | 65세 이상여자 | 65세 이상합계 | 인구수남자 | 인구수여자 | 인구수합계 | 소멸비율 | 소멸위기지역 | ID | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 강원도 | 강릉시 | 26286.0 | 23098.0 | 49384.0 | 15767.0 | 21912.0 | 37679.0 | 106231.0 | 107615.0 | 213846.0 | 1.226041 | False | 강릉 |
1 | 강원도 | 고성군 | 4494.0 | 2529.0 | 7023.0 | 2900.0 | 4251.0 | 7151.0 | 15899.0 | 14215.0 | 30114.0 | 0.707314 | True | 고성(강원) |
2 | 강원도 | 동해시 | 11511.0 | 9753.0 | 21264.0 | 6392.0 | 8732.0 | 15124.0 | 47166.0 | 46131.0 | 93297.0 | 1.289738 | False | 동해 |
3 | 강원도 | 삼척시 | 8708.0 | 7115.0 | 15823.0 | 5892.0 | 8718.0 | 14610.0 | 35253.0 | 34346.0 | 69599.0 | 0.973990 | True | 삼척 |
4 | 강원도 | 속초시 | 9956.0 | 8752.0 | 18708.0 | 5139.0 | 7613.0 | 12752.0 | 40288.0 | 41505.0 | 81793.0 | 1.372647 | False | 속초 |
# pop와 draw_korea를 merge함
pop = pd.merge(
pop, draw_korea,
how='left',
on=['ID']
)
pop.head()
광역시도 | 시도 | 20-39세남자 | 20-39세여자 | 20-39세합계 | 65세 이상남자 | 65세 이상여자 | 65세 이상합계 | 인구수남자 | 인구수여자 | 인구수합계 | 소멸비율 | 소멸위기지역 | ID | y | x | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 강원도 | 강릉시 | 26286.0 | 23098.0 | 49384.0 | 15767.0 | 21912.0 | 37679.0 | 106231.0 | 107615.0 | 213846.0 | 1.226041 | False | 강릉 | 3 | 11 |
1 | 강원도 | 고성군 | 4494.0 | 2529.0 | 7023.0 | 2900.0 | 4251.0 | 7151.0 | 15899.0 | 14215.0 | 30114.0 | 0.707314 | True | 고성(강원) | 0 | 10 |
2 | 강원도 | 동해시 | 11511.0 | 9753.0 | 21264.0 | 6392.0 | 8732.0 | 15124.0 | 47166.0 | 46131.0 | 93297.0 | 1.289738 | False | 동해 | 4 | 11 |
3 | 강원도 | 삼척시 | 8708.0 | 7115.0 | 15823.0 | 5892.0 | 8718.0 | 14610.0 | 35253.0 | 34346.0 | 69599.0 | 0.973990 | True | 삼척 | 5 | 11 |
4 | 강원도 | 속초시 | 9956.0 | 8752.0 | 18708.0 | 5139.0 | 7613.0 | 12752.0 | 40288.0 | 41505.0 | 81793.0 | 1.372647 | False | 속초 | 1 | 10 |
map_data = pop.pivot_table(
index='y',
columns='x',
values='인구수합계'
)
masked_map_data = np.ma.masked_where(
np.isnan(map_data),
map_data
)
map_data
x | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
y | ||||||||||||||
0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 48013.0 | 26264.0 | 24010.0 | 30114.0 | NaN | NaN | NaN |
1 | NaN | NaN | NaN | 205513.0 | 98277.0 | 45907.0 | 154763.0 | 438457.0 | 32720.0 | 280707.0 | 81793.0 | NaN | NaN | NaN |
2 | NaN | NaN | NaN | 446233.0 | 292612.0 | 348220.0 | 567581.0 | 662154.0 | 70076.0 | 45991.0 | 27218.0 | NaN | NaN | NaN |
3 | NaN | NaN | 430781.000000 | 300839.0 | 363443.0 | 327195.0 | 450355.0 | 62448.0 | 193763.0 | 211101.0 | 38718.0 | 213846.0 | NaN | NaN |
4 | NaN | NaN | 283793.333333 | 252353.0 | 339484.0 | 314194.0 | 152737.0 | 355069.0 | 411005.0 | 111367.0 | 47070.0 | 93297.0 | NaN | NaN |
5 | NaN | 68010.0 | 283793.333333 | 345061.0 | 491476.0 | 379892.0 | 125249.0 | 299259.0 | 444168.0 | 111563.0 | 337979.0 | 69599.0 | NaN | NaN |
6 | NaN | 510733.0 | 283793.333333 | 402888.0 | 595485.0 | 400997.0 | 230241.0 | 357215.0 | 657831.0 | 210359.0 | 43318.0 | 51738.0 | NaN | NaN |
7 | NaN | 71014.0 | 330284.000000 | 375857.0 | 477739.0 | 506851.0 | 447192.0 | 237909.0 | 63778.0 | 327723.0 | 40073.0 | 39052.0 | NaN | NaN |
8 | NaN | NaN | 549716.000000 | 314002.0 | 370613.0 | 235386.0 | 567115.0 | 503830.0 | 232841.0 | 347833.0 | 74702.0 | 33539.0 | NaN | 10001.0 |
9 | NaN | 115249.0 | 417103.000000 | 640890.0 | 417551.0 | 284890.0 | 156763.0 | 340654.0 | 417163.0 | 226130.0 | 168798.0 | 17713.0 | NaN | NaN |
10 | 21351.0 | 328627.0 | 530982.000000 | 208656.0 | 182896.0 | 358393.0 | 296479.0 | 136517.0 | 46166.0 | 109247.0 | 419891.0 | 26301.0 | 272027.0 | NaN |
11 | 63900.0 | 302929.0 | 258919.000000 | 359036.0 | 470832.0 | 97787.0 | 198515.0 | 30503.0 | 101799.0 | 142256.0 | 24171.0 | 54014.0 | 244748.0 | NaN |
12 | NaN | 166630.0 | 99971.000000 | 81339.0 | 109931.0 | 69950.0 | 208350.0 | 253563.0 | 38973.0 | 123199.0 | 100521.0 | 258037.0 | 259452.0 | NaN |
13 | NaN | 170788.0 | 103873.000000 | 32753.0 | 243048.0 | 192688.0 | 37308.0 | 190813.0 | 34221.0 | 34257.0 | 43564.0 | 45205.0 | 195285.0 | NaN |
14 | NaN | NaN | 70187.000000 | 123213.0 | 42634.0 | 234959.0 | 173701.0 | 217120.0 | 440383.0 | 79712.0 | 447011.0 | 219255.0 | 174514.0 | NaN |
15 | NaN | NaN | 56012.000000 | 54612.0 | 343222.0 | 252490.0 | 52267.0 | 50552.0 | 199507.0 | 156433.0 | 351352.0 | 242536.0 | 340714.0 | NaN |
16 | NaN | NaN | 277551.000000 | 300479.0 | 491011.0 | 24949.0 | 63308.0 | 48026.0 | 591891.0 | 218268.0 | 244624.0 | 272745.0 | 158527.0 | NaN |
17 | NaN | NaN | 57005.000000 | 87782.0 | 95480.0 | 23628.0 | 40241.0 | 63982.0 | 108354.0 | 310202.0 | 376526.0 | 207268.0 | 419853.0 | NaN |
18 | NaN | 60597.0 | 115173.000000 | 289899.0 | 26069.0 | 84188.0 | 346739.0 | 28111.0 | 108909.0 | 232800.0 | 89826.0 | 45208.0 | NaN | NaN |
19 | NaN | 55618.0 | 46104.000000 | 361845.0 | 30197.0 | 36098.0 | 68937.0 | 317037.0 | 181797.0 | 112973.0 | 334603.0 | 278779.0 | NaN | NaN |
20 | NaN | 34397.0 | 47229.000000 | 29949.0 | 27412.0 | 49622.0 | 252435.0 | 231571.0 | 187313.0 | 529422.0 | 126362.0 | 179324.0 | NaN | NaN |
21 | 42652.0 | 82109.0 | 403049.000000 | 30400.0 | 65303.0 | 155580.0 | 114912.0 | 210791.0 | 138160.0 | NaN | NaN | NaN | NaN | NaN |
22 | 237739.0 | 104376.0 | 309579.000000 | 441066.0 | 278548.0 | 67656.0 | 45129.0 | 54703.0 | 257183.0 | NaN | NaN | NaN | NaN | NaN |
23 | 75121.0 | 57045.0 | 219729.000000 | 95791.0 | 288988.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
24 | 32078.0 | 37753.0 | 40669.000000 | 44469.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
25 | NaN | NaN | 52668.000000 | NaN | NaN | 470665.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
26 | NaN | NaN | NaN | NaN | NaN | 170932.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
def draw_Korea(target_data, blocked_map, c_map_name):
gamma = 0.75
white_label_min = (
max(blocked_map[target_data]) - min(blocked_map[target_data]) * 0.25 + min( blocked_map[target_data] )
)
data_label = target_data
vmin = min( blocked_map[target_data] )
vmax = max( blocked_map[target_data] )
BORDER_LINES = [
# 인천
[(5, 1), (5,2), (7,2), (7,3), (11,3), (11,0)],
# 서울
[(5,4), (5,5), (2,5), (2,7), (4,7), (4,9), (7,9), (7,7), (9,7), (9,5), (10,5), (10,4), (5,4)],
# 경기도
[(1,7), (1,8), (3,8), (3,10), (10,10), (10,7), (12,7), (12,6), (11,6), (11,5), (12, 5), (12,4), (11,4), (11,3)],
# 강원도
[(8,10), (8,11), (6,11), (6,12)],
# 충청북도
[(12,5), (13,5), (13,4), (14,4), (14,5), (15,5), (15,4), (16,4), (16,2)],
# 전라북도
[(16,4), (17,4), (17,5), (16,5), (16,6), (19,6), (19,5), (20,5), (20,4), (21,4), (21,3), (19,3), (19,1)],
# 대전시
[(13,5), (13,6), (16,6)],
#세종시
[(13,5), (14,5)],
#광주
[(21,2), (21,3), (22,3), (22,4), (24,4), (24,2), (21,2)],
#전라남도
[(20,5), (21,5), (21,6), (23,6)],
#충청북도
[(10,8), (12,8), (12,9), (14,9), (14,8), (16,8), (16,6)],
#경상북도
[(14,9), (14,11), (14,12), (13,12), (13,13)],
#대구
[(15,8), (17,8), (17,10), (16,10), (16,11), (14,11)],
#부산
[(17,9), (18,9), (18,8), (19,8), (19,9), (20,9), (20,10), (21,10)],
#울산
[(16,11), (16,13)],
# [(9,14), (9,15)],
[(27,5), (27,6), (25,6)],
]
map_data = blocked_map.pivot_table(
index='y',
columns='x',
values=target_data
)
masked_map_data = np.ma.masked_where(
np.isnan(map_data),
map_data
)
plt.figure( figsize=(9, 11) )
plt.pcolor(masked_map_data, vmin=vmin, vmax=vmax, cmap=c_map_name, edgecolor='#aaaaaa', linewidth=0.5 )
# 지역 이름 표시
for idx, row in blocked_map.iterrows():
# 광역시는 구 이름이 겹치는 경우가 많아서 시단위 이름을 같이 표시한다.
if len( row['ID'].split() ) ==2:
display_name = '{}\n{}'.format(row['ID'].split()[0], row['ID'].split()[1])
elif row['ID'][:2] =='고성':
display_name = '고성'
else:
display_name = row['ID']
# 서대문구, 서귀포시 같이 이름이 3자 이상인 경우에 작은 글자로 표시한다
if len(display_name.splitlines()[-1]) >= 3:
fontsize, linespacing = 9.5, 1.5
else:
fontsize, linespacing = 11, 1.2
annocolor = 'white' if row[target_data] > white_label_min else 'black'
plt.annotate(
display_name,
(row['x']+0.5, row['y']+0.5),
weight='bold',
fontsize=fontsize,
ha='center',
va='center',
color=annocolor,
linespacing=linespacing
)
# 시도 경계를 그린다.
for path in BORDER_LINES:
ys, xs = zip(*path)
plt.plot(xs, ys, c='black', lw=2)
plt.gca().invert_yaxis()
plt.axis('off')
plt.tight_layout()
plt.show()
draw_Korea('인구수합계', pop, 'Blues')
pop['소멸위기지역'] = [ 1 if con else 0 for con in pop['소멸위기지역'] ]
draw_Korea('소멸위기지역', pop, 'Reds')
7) folium으로 Map을 그리기
(1) JSON 파일(2013년 자료)에서 반영되지 않은 것
- 부천시의 구가 사라짐 - [행정구](https://ko.wikipedia.org/wiki/%EA%B5%AC_(%ED%96%89%EC%A0%95_%EA%B5%AC%EC%97%AD)
- 2014년 생긴 청주 서원구는 반영되지 않음
pop[ pop['ID'] == '청주 서원' ]
광역시도 | 시도 | 20-39세남자 | 20-39세여자 | 20-39세합계 | 65세 이상남자 | 65세 이상여자 | 65세 이상합계 | 인구수남자 | 인구수여자 | 인구수합계 | 소멸비율 | 소멸위기지역 | ID | y | x | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
242 | 충청북도 | 서원구 | 31810.0 | 29168.0 | 60978.0 | 9950.0 | 14237.0 | 24187.0 | 107866.0 | 109254.0 | 217120.0 | 2.411874 | 0 | 청주 서원 | 14 | 7 |
# 청주 서원 index 삭제
pop_folium = pop.drop( pop[ pop['ID'] == '청주 서원' ].index )
pop_folium = pop_folium.set_index('ID')
pop_folium.head()
광역시도 | 시도 | 20-39세남자 | 20-39세여자 | 20-39세합계 | 65세 이상남자 | 65세 이상여자 | 65세 이상합계 | 인구수남자 | 인구수여자 | 인구수합계 | 소멸비율 | 소멸위기지역 | y | x | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ID | |||||||||||||||
강릉 | 강원도 | 강릉시 | 26286.0 | 23098.0 | 49384.0 | 15767.0 | 21912.0 | 37679.0 | 106231.0 | 107615.0 | 213846.0 | 1.226041 | 0 | 3 | 11 |
고성(강원) | 강원도 | 고성군 | 4494.0 | 2529.0 | 7023.0 | 2900.0 | 4251.0 | 7151.0 | 15899.0 | 14215.0 | 30114.0 | 0.707314 | 1 | 0 | 10 |
동해 | 강원도 | 동해시 | 11511.0 | 9753.0 | 21264.0 | 6392.0 | 8732.0 | 15124.0 | 47166.0 | 46131.0 | 93297.0 | 1.289738 | 0 | 4 | 11 |
삼척 | 강원도 | 삼척시 | 8708.0 | 7115.0 | 15823.0 | 5892.0 | 8718.0 | 14610.0 | 35253.0 | 34346.0 | 69599.0 | 0.973990 | 1 | 5 | 11 |
속초 | 강원도 | 속초시 | 9956.0 | 8752.0 | 18708.0 | 5139.0 | 7613.0 | 12752.0 | 40288.0 | 41505.0 | 81793.0 | 1.372647 | 0 | 1 | 10 |
import folium
import json
import warnings
warnings.simplefilter(
action='ignore',
category=FutureWarning
)
geo_path = './data_science/05. skorea_municipalities_geo_simple.json'
geo_string = json.load(
open(geo_path, encoding='utf-8')
)
fmap = folium.Map(
location=[36.2002, 127.054],
zoom_start=7
)
fmap.choropleth(
geo_data = geo_string,
data=pop_folium['소멸위기지역'],
columns = [ pop_folium.index, pop_folium['소멸위기지역'] ],
fill_color = 'PuRd',
key_on = 'feature.id'
)
fmap
# 파일 저장
draw_korea.to_csv("./data_output/05.draw_korea.csv", encoding='utf-8', sep=',')