본문 바로가기

Analytics/Study

실전#5 미국의 대통령은 어떻게 뽑힐까(5)

이번 EDA는 Plotly에 대한 내용이다.
 
직관적인 이번 시간의 목표는 Pres_DEM에 대한 County별 현황을 아래와 같은 Geo정보를 활용한 Map 형태로 나타내는 것이다.

우선 위 예시는 plotly 관련 정보가 정리되어있는 

https://plotly.com/python/county-choropleth/#the-entire-usa

 

Usa

Detailed examples of USA County Choropleth Maps including changing color, size, log axes, and more in Python.

plotly.com

에서 참고한 예시이다.

관련 코드는 아래와 같고, plotly 중 figure_factory를 활용하였다.

import plotly.figure_factory as ff

import numpy as np
import pandas as pd

df_sample = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/laucnty16.csv')
df_sample['State FIPS Code'] = df_sample['State FIPS Code'].apply(lambda x: str(x).zfill(2))
df_sample['County FIPS Code'] = df_sample['County FIPS Code'].apply(lambda x: str(x).zfill(3))
df_sample['FIPS'] = df_sample['State FIPS Code'] + df_sample['County FIPS Code']

colorscale = ["#f7fbff","#ebf3fb","#deebf7","#d2e3f3","#c6dbef","#b3d2e9","#9ecae1",
              "#85bcdb","#6baed6","#57a0ce","#4292c6","#3082be","#2171b5","#1361a9",
              "#08519c","#0b4083","#08306b"]
endpts = list(np.linspace(1, 12, len(colorscale) - 1))
fips = df_sample['FIPS'].tolist()
values = df_sample['Unemployment Rate (%)'].tolist()

fig = ff.create_choropleth(
    fips=fips, values=values,
    binning_endpoints=endpts,
    colorscale=colorscale,
    show_state_data=False,
    show_hover=True, centroid_marker={'opacity': 0},
    asp=2.9, title='USA by Unemployment %',
    legend_title='% unemployed'
)

fig.layout.template = None
fig.show()

코드별 상세 설명은 아래 실제 데이터를 통해 이어갈 예정이다.

 

위 예시 코드를 언급한 이유는 바로 해당 샘플 데이터에서 참고가 되는 정보가 있기 때문인데,

FIPS 코드 라고 명명하는 County 및 State별 영역 구분 코드라고 생각하면 될 것 같다.

※ FIPS: 미국 지역별 Federal Information Processing Standards(FIPS) 코드 - 미국 내 각 지역의 고유한 코드

 

 

그래서! 첫번째 과정은 df_sample에서 데이터의 형태와 FIPS를 이해할 필요가 있다.

아래처럼 County Name과 State 약식 표현이 하나의 컬럼 안에 구성되어있다.

그럼 우리가 활용하고 있는 state_code는 어떤 형태였는지 다시 알아보자

데이터 형태가 동일했다면 정말 편했을테지만,

아쉽게 구조가 달라 통일하는 작업이 필요해졌다.

 

# 데이터 구조 통일을 위해 우선 State name/District와 Postal Code만으로 이루어진 index를 구성하자
state_map = state_code.set_index('State Name/District')['Postal Code']

index를 구성한 뒤 df_norm 테이블에 해당되는 정보가 mapping 될 수 있도록 작업을 이어간다.

counties = df_norm.reset_index()['county'] + ', ' + df_norm.reset_index()['state'].map(state_map)

df_sample에서 데이터 형태가 county, state 였기에 형태를 맞추도록 하였다.

이렇게 작업한 counties 의 형태는 아래처럼 나타난다.

 

 

이제 통일한 데이터들을 기준으로 FIPS를 붙여넣는 작업을 한다.

# df_sample에서 index로 정리하기
counties_to_fips = df_sample.set_index('County Name/State Abbreviation')['FIPS']

# counties에 fips 정보 맞추기
fips = counties.map(counties_to_fips)

# df_norm 데이터에 fips 정보 붙이기. 이 때 NaN 처리되는 데이터는 제외하기
data = df_norm.reset_index()['Pres_DEM'][fips.notna()]
fips = fips[fips.notna()]

여기까지가 FIPS를 붙여넣는 일련의 작업 과정이었다.

 

하나씩 직접 해보면서 결과를 비교하면 조금 더 이해가 쉬울텐데

정리하여 보려고하니 많은 과정이 생략된 것 같아 보이기도 한다.

 

이제 진짜 목표였던 choropleth map 시각화 과정으로 넘어가보자

fig = ff.create_choropleth(
    fips = fips, values = data,
    show_state_data = False,
    colorscale = colorscale,
    binning_endpoints = list(np.linspace(0.0, 1.0, len(colorscale) - 2)),
    show_hover = True, centroid_marker = {'opacity' : 0},
    asp = 2.9, title = 'USA by VOting for DEM President'
)


fig.layout.template = None
fig.show()

 

옵션 설정들을 하나씩 살펴보면

  • fips: 위에서 정리한 내용을 그대로 가져왔다.
  • shop_state_data: 각 주별 데이터를 표시할 것인지에 대한 옵션값으로, 시각화가 목적이기에 False로 설정하였다.
  • colorscale: 시각화할 데이터에 따른 색상 맵으로, 샘플 옵션의 색상 정보를 그대로 참고하였다.
  • binning_endpoints: 데이터를 색상 맵에 mapping할 때 사용할 구간을 지정할 수 있다.
    • np.linspace를 통해 0과 1 사이에 전체 colorscale 구간보다 2개 적게 구간을 나누도록 지정하였다.
  • show_hover: 호버링 기능을 활성화로 설정하였다.
    • 추가 정보 제공 유무에 관련된 기능으로, 지도 상에서 마우스 커서를 이동하면 추가 정보가 표시되도록 설정할 수 있다.
  • centroid_marker: 지역 중심에 표시되는 마커에 대한 설정이다.
    • 여기서 사용한 opacity는 마커의 불투명도 설정으로, 값을 0으로 설정하면 완전한 투명으로 화면에서 보이지 않도록 하는 효과가 있다.
  • asp: 가로,세로 비율을 2.9로 설정하였다.
  • title: 시각화 결과 제목 설정이다.
  • 마지막에 fig.layout.template = None의 의미는 기존 탬플릿을 사용하지 않도록 설정한 것이다.

 

이렇게 설정을 통해 나타난 결과는 아래와 같다!

(저 하나의 이미지를 구현하기 위해 얼마의 시간과 과정이 녹여들었던것인가...!)

데이터를 간략히 해석해보면

서부쪽 해안가와 중부 기준 아래쪽, 동부 끝부분과 해안가를 따라 남쪽까지의 흐름 정도로

민주당 지지자들이 많이 나타나고 있다.

 

보다 자세하고 모델링 관점의 내용은 이후 추가로 살펴보도록 하자.

 

 

http://bit.ly/3Y34pE0

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.