지도 시각화2

2024. 11. 9. 21:40python study/sw와 ai 데이터 분석

Geojson

  • 위치 정보를 기반으로 지형을 표현하기 위해 설계된 개방형 공개 표준 형식
  • 위치 정보는 경도, 위도, 고도 순으로 저장된다.
  • 확장자: *. geojson, *. json

단계 구분도

  • 지역에 따라서 통계치의 차이를 색상으로 구분한 지도

Geojson & 단계 구분도를 활용한 시각화 순서
1. folium을 활용하여서 간단하게 Map 그려주기
2. Geojson으로 구역마다 경계를 확인해 줌
3. Choropleth를 지도에 추가해 줌

Geojson 불러오기

  • 라이브러리 선언하기
import json
  • Geojson파일 읽어 오기
변수명=json.load(open("Geojson파일 경로", encoding="인코딩 방식"))
(인코딩 방식과 같은 경우에는 euc-kr(한글 인코딩), cp949(MS office), utf-8(유니코드 인코딩))

Geojson으로 행정구역 구별하기

  • folium.Geojson("Geojson파일 경로"). add_to(지도 변수명)

지도에 단계 구분선 표시하기

folium.Choropleth(속성). add_to(지도 변수명)

geo_data="지도 데이터": json형식의 데이터
data="시각화하려는 데이터": DataFrame형식

columns=(열 이름 1, 열 이름 2)
열 이름 1: 문자열 데이터로 지도 데이터와 이름이 동일해야 한다.
열 이름 2: 수치 데이터로 시각화하고자 하는 열 이름

key_on="매핑할 geo데이터": geojson 데이터에서 시각화하고자하는 데이터와 동일한 값
fill_color="색상": 색상 이름 혹은 rgb
fill_opacity=실수: 색상의 투명도(0~1 사이)
line_weight=정수: 경계선의 두께
nan_fill_color="색상": 통계 수치가 없는 구역의 색상 지정

단계 구분도 그려보기

  1. 서울시 지도를 folium.Map()을 활용하여서 불러오기
  2. 지도 데이터를 불러오기
  3. 수치 데이터, 즉 공공 데이터를 불러오기

행정구역 경계를 나타내는 지도 데이터

  • 2022년 서울시 자치구별 데이터를 가져온다.
https://www.data.go.kr/data/15046995/fileData.do?recommendDataYn=Y# 에서 자치구별 데이터를 가져오면 된다.

데이터를 가져올 때 시점을 2020년으로 맞춰준다.
 

서울특별시_자치구별 대학교 학령인구 (추계인구) 통계_20200904

서울시 통계정보시스템에서 제공하는 자치구별 대학교 학령인구(추계인구)에 대한 통계정보로, 기간, 행정구역별, 합계, 남자, 여자의 항목으로 구성되어 있습니다.

www.data.go.kr

  • Geojson의 데이터의 크기가 커서 가져오는데 시간이 많이 걸리기 때문에 드라이브 마운트를 해제해 준 다음에 대학교 데이터와 Geojson데이터를 가져와야 한다.

  • 마운트를 해제한 뒤에 drive를 클릭해 준다.

  • MyDrive를 클릭해 주고 옆에 점 세 개를 눌러서 새 폴더를 생성해 준다.

  • 마지막으로 만든 파일 옆에 점 세 개를 클릭해 주고 Geojson파일과 다른 데이터를 업로드해준다.

  • 여기까지 해준다면 데이터를 준비해 주는 것은 끝났다.

데이터 시각화 하기

  • 판다스를 활용하여서 엑셀데이터를 불러와서 df 변수에 저장해 준다.
  • 단 2행을 header로 지정해 줄 필요가 있다.
import pandas as pd

df=pd.read_excel('/content/drive/MyDrive/DATA/자치구별+대학교+학령인구(추계인구)_20241109200504.xlsx',
                 header=[2])
df

 

  • 다음으로는 json파일을 부분을 위에서 본 것처럼 가져오면 된다.
import json

geo_json=json.load(open('/content/drive/MyDrive/Data Files/서울시군구.geojson'))
geo_json
{'type': 'FeatureCollection',
 'name': '서울시군구',
 'crs': {'type': 'name',
  'properties': {'name': 'urn:ogc:def:crs:OGC:1.3:CRS84'}},
 'features': [{'type': 'Feature',
   'properties': {'SIG_CD': '11110',
    'SIG_ENG_NM': 'Jongno-gu',
    'SIG_KOR_NM': '종로구'},
   'geometry': {'type': 'MultiPolygon',
    'coordinates': [[[[127.00864326221884, 37.580468252047105],
       [127.00871274905404, 37.58045116513156],
       [127.00876564011087, 37.580443107078565],
       [127.00890785297045, 37.580424231608646],
       [127.00913781377908, 37.58039352939572],
       [127.00916523299747, 37.58039071654549],
여기서 잘 보면 종로구가 SIG_KOR_NM에 종로구가 있고, 이는 properties안에 존재한다는 것을 확인할 수 있습니다. 그렇기 때문에 다음과 같은 코드를 작성해 주면 '종로구'를 얻을 수 있습니다.
geo_json['features'][0]['properties']['SIG_KOR_NM']​
'종로구'

이러한 방식은 나중에 단계 구분선을 표시하면서 사용하기 때문에 이 정도는 알아두는 것이 좋다.

  • 다음으로는 folium()을 활용하여서 지도를 생성해 준다.
import folium

Map=folium.Map(location=[37.4965,126.9572],
               zoom_start=11,
               tiles='cartodbpositron')
Map

  • 그런 다음에 Geojson의 좌표를 지도에 나타내주면 된다.
import folium

Map=folium.Map(location=[37.4965,126.9572],
               zoom_start=11,
               tiles='cartodbpositron')

folium.GeoJson(geo_json).add_to(Map)
Map

  • 그런 다음 df에 있는 데이터와 geo_json에 있는 데이터를 종합해 주면 된다.
1. geo_data 속성에는 geo_json 데이터를 가져오면 된다.
2. data 속성에는 df에 있는 데이터를 가져오면 되는 데 이때 조심해야 하는 부분은 우리가 df에 저장한 데이터는 모든 데이터의 합계가 포함되어 있기 때문에 합계(첫 번째 행)를 제외한 나머지 부분을 가져와야 한다.
3. key_on 속성과 같은 경우는 위에서 종로구가 json파일에서 어디 있는지 확인해 보았는데 거기에서 대괄호를 제거하여서 표시해 주면 된다. 그리고 위에서 [][0][]...으로 했는 데 0과 같은 경우는 index를 표시해 주는 용도이기 때문에 제거해 주어도 된다. (아래 코드 참고)
4. 나머지 속성들을 알맞게 채워주시면 된다!
import folium

Map = folium.Map(location=[37.4965, 126.9572], 
                 zoom_start=11, 
                 tiles='cartodbpositron')

folium.GeoJson(geo_json).add_to(Map)

folium.Choropleth( geo_data=geo_json,
    data=df[1:],
    columns=['자치구별(2)', '소계'],  #열1: 구 이름, 열2: 소계(수치 데이터)
    key_on='feature.properties.SIG_KOR_NM', #json데이터 구 이름 위치
    fill_color='Blues', #Blues는 파랑색을 활용한 빈도 시각화(구글링 해보면 몇가지 더 존재..)
    fill_opacity=0.5, #fill_color의 투명도
    line_weight=3, #선의 굵기
    line_opacity=0.5 #선의 투명도
).add_to(Map)

Map

깔끔~

나중에 여기에 Marker도 활용하여서 대학교도 표시하여도 나쁘지 않을 것 같다.

'python study > sw와 ai 데이터 분석' 카테고리의 다른 글

동작구 버스 데이터 분석  (1) 2025.01.12
MarkerClsuter+Geojson  (5) 2024.11.10
지도 시각화  (1) 2024.11.08
WordCloud 더 나아가기  (0) 2024.11.07
WorldCloud 시각화분석  (1) 2024.11.07