EDA 7 - 인구분석 (2)

subinii·2024년 4월 18일

DS 25기

목록 보기
28/46

07.Population

04. 지도 그리기(카르토그램)

사용할 엑셀 파일 불러오기

draw_korea_raw = pd.read_excel("../data/07_draw_korea_raw.xlsx")
draw_korea_raw

stack()

  • 데이터프레임 재구조화하기
draw_korea_raw_stacked = pd.DataFrame(draw_korea_raw.stack())
draw_korea_raw_stacked.reset_index(inplace=True)
  • 칼럼 이름 바꾸기
draw_korea_raw_stacked.rename(
    columns={
        "level_0": "y",
        "level_1": "x",
        0: "ID"
    }, inplace=True
)
# 변수에 담기 
draw_korea = draw_korea_raw_stacked
  • y ~ X까지 NaN 값

행과 열에 맞춰 지역 구별하기

test : 지역 이름 text 함수

test : 시각화

test

데이터 합치기

검증 작업하기 : set()

  • 차집합을 이용해 곂치는 데이터 정리하기
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)
print(set(pop["ID"].unique()) -set(draw_korea["ID"].unique()))

merge()

pop = pd.merge(pop, draw_korea, how="left", on="ID")

그림을 그리기 위한 데이터를 계산하는 함수

  • 색상을 만들 때, 최솟값을 흰색
  • blockedMap : 인구현황(pop)
  • targetData : 그리고 싶은 컬럼

지도 시각화하기

가져올 데이터 정리 함수

def get_data_info(targetData, blockedMap):
    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)
    
    return mapdata, vmax, vmin, whitelabelmin
def get_data_info_for_zero_center(targetData, blockedMap):
    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

text 함수

def plot_text(targetData, blockedMap, whitelabelmin):
    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

        # 주석
        annocolor = "white" if np.abs(row[targetData]) > whitelabelmin else "black"
        plt.annotate(
            dispname,
            (row["x"] + 0.5, row["y"] + 0.5),
            weight="bold",
            color=annocolor,
            fontsize=fontsize,
            linespacing=linespacing,
            ha="center", # 수평 정렬
            va="center", # 수직 정렬 
        )

시각화 함수

def drawKorea(targetData, blockedMap, cmapname, zeroCenter=False):
    if zeroCenter:
        masked_mapdata, vmax, vmin, whitelabelmin = get_data_info_for_zero_center(targetData, blockedMap)
    if not zeroCenter:
        masked_mapdata, vmax, vmin, whitelabelmin = get_data_info(targetData, blockedMap)
        
    plt.figure(figsize=(8, 11))
    plt.pcolor(masked_mapdata, vmin=vmin, vmax=vmax, 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=1.5)
    
    plt.gca().invert_yaxis()
    plt.axis("off")
    plt.tight_layout()
    cb = plt.colorbar(shrink=0.1, aspect=10)
    cb.set_label(targetData)
    plt.show()

카르토그램 지도 시각화

  • 사용할 데이터프레임
  1. 인구수합계에 따른 지도 시각화
drawKorea("인구수합계", pop, "Blues")

  1. 소멸위기지역에 따른 지도 시각화
  • bool 타입으로 0 또는 1로 표현
pop["소멸위기지역"] = [1 if con else 0 for con in pop["소멸위기지역"]]
drawKorea("소멸위기지역", pop, "Reds")

  1. 여성비에 따른 지도 시각화
pop["여성비"] = (pop["인구수여자"] / pop["인구수합계"] - 0.5) * 100 
drawKorea("여성비", pop, "RdBu", zeroCenter=True)

folium 지도 시각화

  • index를 ID로 지정
pop_folium = pop.set_index("ID")

import

import folium
import json

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["인구수합계"], 
    key_on="feature.id",
    columns=[pop_folium.index, pop_folium["인구수합계"]],
    fill_color="YlGnBu"
).add_to(mymap)
mymap

소멸위기 지역 시각화

mymap = folium.Map(location=[36.2002, 127.054], zoom_start=7)
folium.Choropleth(
    geo_data=geo_str,
    data = pop_folium["소멸위기지역"], 
    key_on="feature.id",
    columns=[pop_folium.index, pop_folium["소멸위기지역"]],
    fill_color="PuRd"
).add_to(mymap)
mymap

“이 글은 제로베이스 데이터 취업 스쿨의 강의 자료 일부를 발췌하여 작성되었습니다.”

profile
데이터 공부 기록

0개의 댓글