📌3/15 영상 강의 인구분석 3 , MYSQL 기초 1,2
draw_korea_raw=pd.read_excel("../data/07_draw_korea_raw.xlsx")
draw_korea_raw
# 인덱스로 나타난 좌표를 데이터로 사용하기 위해 reset_index
draw_korea_raw_stack = pd.DataFrame(draw_korea_raw.stack())
draw_korea_raw_stack
stack & unstack
- stack : 컬럼 레벨에서 인덱스 레벨(row 레벨)로 dataframe 변경
즉, 데이터를 쌓아올리는 개념으로 이해하면 쉬움- unstack : 인덱스 레벨에서 컬럼 레벨로 dataframe 변경
stack의 반대 operation 둘은 역의 관계에 있음
# 엑셀 좌표 한땀한땀 적기
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)],
[(27,5),(27,6),(25,6)]
]
def plot_text_simple(draw_korea):
for idx, row in draw_korea.iterrows():
if len(row["ID"].split()) == 2:
dispname = "{}\n{}".format(row["ID"].split()[0],row["ID"].split()[1]) # id 두글자씩개행하기
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
plt.annotate( # 주석 기능(그래프안에 글자 쓰기 )
dispname,
(row["x"] + 0.5, row["y"] + 0.5),
weight="bold",
fontsize = fontsize,
linespacing=linespacing,
ha="center", #수평정렬
va="center" #수직정렬
)
def simpleDraw(draw_korea):
plt.figure(figsize=(8,11))
plot_text_simple(draw_korea)
for path in BORDER_LINES:
ys, xs = zip(*path) # ys, xs 변수 순서가 바뀌면 모인 숫자 위치가 달라져서 지도가 다르게 그려진다
plt.plot(xs, ys, c="black", lw=1.5)
plt.gca().invert_yaxis()
plt.axis("off")
plt.tight_layout()
plt.show()
simpleDraw(draw_korea)
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):
# 값이 음수, 양수 들어왔을 센터(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):
for idx, row in blockedMap.iterrows():
if len(row["ID"].split()) == 2:
dispname = "{}\n{}".format(row["ID"].split()[0],row["ID"].split()[1]) # id 두글자씩개행하기
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) # ys, xs 변수 순서가 바뀌면 모인 숫자 위치가 달라져서 지도가 다르게 그려진다
plt.plot(xs, ys, c="black", lw=1.5)
plt.gca().invert_yaxis()
plt.axis("off")
cb = plt.colorbar(shrink=0.1, aspect=10)
cb.set_label(targetData)
plt.tight_layout()
plt.show()
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)
#인구수 합계 시각화
mymap.choropleth(
geo_data=geo_str,
data=pop_folium["인구수합계"],
key_on="feature.id",
columns=[pop_folium.index, pop_folium["인구수합계"]],
fill_color="YlGnBu"
)
mymap
# 소멸위기지역 지도 시각화
mymap = folium.Map(location=[36.2002, 127.054], zoom_start=7)
mymap.choropleth(
geo_data=geo_str,
data=pop_folium["소멸위기지역"],
key_on="feature.id",
columns=[pop_folium.index, pop_folium["소멸위기지역"]],
fill_color="PuRd"
)
mymap
👍마무리
지도그리기 함수 ..넘 복잡하다
나중에 내가 이런걸 뚝딱 한다고? 세상에나.. 넘 멋잇는걸
갈 길이 한~참 멀지만 뚝딱뚝딱 일하는 내 모습을 상상하며 힘을 내본다