1. 이제 앞서 만든 데이터(pop, 인구수와 인구소멸지수 데이터와 draw_korea, 대한민국 지역을 엑셀로 그린 데이터)를 검증한 후 merge할 것이다.



2. 그 다음에는 반대로 차집합을 확인하여 여집합을 삭제해준다.


3. 이제 pop와 draw_korea를 merge해준다.

4. 이제 색상을 표시하기 위한 함수를 만들어야 한다. 코드는 다음과 같다.
#### 그림을 그리기 위한 데이터를 계산하는 함수
- 색상을 만들 때, 최소값은 흰색
- blockedMap = 인구현황(pop)
- targetData = 그리고 싶은 컬럼
def get_data_info(targetData, blockedMap): # blockedMap은 pop데이터, targetData는 색이 입혀지는 컬럼 이름
whitelabelmin=( # 배경과 글자의 시인성을 위해 일정 값 이상부터는 글자 색을 바꿔주는 함수
max(blockedMap[targetData])-min(blockedMap[targetData])
) * 0.25 * min(blockedMap[targetData])
vmin = min(blockedMap[targetData])
vmax = max(blockedMap[targetData])
mapdata = blockedMap.pivot_table(index='y', columns='x', values=targetData) # 지역이름이 들어갈 자리에 targetData의 숫자가 들어감
return mapdata, vmax, vmin, whitelabelmin
def get_data_info_for_zero_center(targetData, blockedMap): # 값이 좌우대칭일 때, 0(가운데)의 위치(범위)를 정해 주는 함수
whitelabelmin = 5
tmp_max = max(
[np.abs(min(blockedMap[targetData])), np.abs(max(blockedMap[targetData]))]
)
vmin, vmax = -tmp_max, tmp_max
mapdata = blockedMap.pivot_table(index='y', columns='x', values=targetData)
return mapdata, vmax, vmin, whitelabelmin
def plot_text(targetData, blockedMap, whitelabelmin):
# 주석을 다는 부분은 위의 plot_text_simple함수와 똑같지만
for idx, row in blockedMap.iterrows():
if len(row['ID'].split()) == 2:
dispname = '{}\n{}'.format(row['ID'].split()[0], row['ID'].split()[1])
elif row['ID'][:2] == '고성':
dispname = '고성'
else:
dispname = row['ID']
if len(dispname.splitlines()[-1]) >=3:
fontsize, linespacing = 9.5, 1.5
else:
fontsize, linespacing = 11, 1.2
# font의 글자색을 정해주는 부분이 추가
annocolor = 'white' if np.abs(row[targetData]) > whitelabelmin else 'black'
plt.annotate( # matplotlib의 주석 기능
dispname,
(row['x'] + 0.5, row['y'] + 0.5),
color = annocolor,
weight = 'bold',
fontsize=fontsize,
linespacing = linespacing,
ha = 'center', # 수직 정렬
va = 'center', # 수평 정렬
)
def drawKorea(targetData, blockedMap, cmapname, zeroCenter=False): # zeroCenter 디폴트는 False
if zeroCenter: # 값의 범위가 음수~양수를 가질 때
masked_mapdata, vmax, vmin, whitelabelmin = get_data_info_for_zero_center(targetData, blockedMap) # masked_mapdata는 인덱스를 x좌표, column을 y좌표로 한 데이터
if not zeroCenter: # 값의 범위가 양수만 존재할 때
masked_mapdata, vmax, vmin, whitelabelmin = get_data_info(targetData, blockedMap)
# 데이터별로 색을 채우는 함수
plt.figure(figsize=(9, 11))
plt.pcolor(
masked_mapdata, vmax = vmax, vmin = vmin, cmap = cmapname, edgecolor = '#aaaaaa',
linewidth = 0.5,
)
plot_text(targetData, blockedMap, whitelabelmin)
for path in BORDER_LINES:
ys, xs = zip(*path)
plt.plot(xs, ys, c='black', lw=2)
plt.gca().invert_yaxis()
plt.axis('off')
cb=plt.colorbar(shrink=0.1, aspect=10)
cb.set_label(targetData)
plt.tight_layout()
plt.show()
5. 위의 함수를 한번 실행해보자. 먼저 '인구수합계'를 바탕으로 지도에 표시된 결과를 보자.
drawKorea('인구수합계', pop, 'Blues')

6. 다음에는 '인구소멸위기지역'을 표시해보자.
pop['인구소멸위기지역'] = [1 if con else 0 for con in pop['인구소멸위기지역']]
drawKorea('인구소멸위기지역', pop, 'Reds')

7. 다음은 강사님이 직접 해보신 부분이다. 전국의 '여성 비율'을 표시해보았다.
pop['여성비'] = (pop['인구수여자'] / pop['인구수합계'] - 0.5) * 100
drawKorea('여성비', pop, 'RdBu', zeroCenter = True)

8. 전반적으로 특정 몇 지역을 제외하면 크게 성비가 차이나지 않는 것처럼 보인다. 그러나 이는 착시효과다. 아래와 같이 계산식을 바꿔 보자.
pop['2030여성비'] = (pop['20~39세여자'] / pop['20~39세합계'] - 0.5) * 100
drawKorea('2030여성비', pop, 'RdBu', zeroCenter = True)

9. 다음엔 folium으로 접근해보자. 인덱스를 'ID'로 잡아 준다.
import folium
import json
pop_folium = pop.set_index('ID')
pop_folium.head()

geo_path = '../data/07_skorea_municipalities_geo_simple.json'
geo_str = json.load(open(geo_path, encoding='utf-8'))
mymap = folium.Map(location=[36.2002, 127.054], zoom_start=7)
folium.Choropleth(
geo_data=geo_str,
data=pop_folium['인구수합계'],
columns = [pop_folium.index, pop_folium['인구수합계']],
fill_color = 'YlGnBu', # PuRd, YlGnBu
key_on = 'feature.id'
).add_to(mymap)
mymap

10. 이번엔 folium으로 인구소멸위기지역을 표시해보자.
mymap = folium.Map(location=[36.2002, 127.054], zoom_start=7)
folium.Choropleth(
geo_data=geo_str,
data=pop_folium['인구소멸위기지역'],
columns = [pop_folium.index, pop_folium['인구소멸위기지역']],
fill_color = 'PuRd', # PuRd, YlGnBu
key_on = 'feature.id'
).add_to(mymap)
mymap

'데이터분석 > 미니프로젝트 06. 인구 분석' 카테고리의 다른 글
| 06-03-01. 카르토그램으로 인구현황 시각화하기(01) (1) | 2024.04.23 |
|---|---|
| 06-02. 인구현황데이터에 지도 ID 만들기 (2) | 2024.04.22 |
| 06-01. 인구소멸위기지역 파악하기 프로젝트 개요, 데이터 수집 및 정리 (2) | 2024.04.21 |