데이터/데이터 분석
[데이터시각화/Plotly] Colopleth로 지도에 정보 시각화하기
성장하기
2023. 9. 30. 21:04
Geojson으로 좌표값 불러온 후 geopandas 객체로 선언하기
미국 geojson 다운 받기
from urllib import request
url = '<https://github.com/PublicaMundi/MappingAPI/blob/master/data/geojson/us-states.json>'
savename = './data/us-states.json'
request.urlretrieve(url,savename)
print("저장되었습니다.")
https://github.com/PublicaMundi/MappingAPI/blob/master/data/geojson/us-states.json
json 불러와서 geo 파일 저장
import json
with open('./data/us-states.json', 'r') as f:
json_data = json.load(f)
geo = json.dumps(json_data, indent="\\t")
json dict 선언
geo_dict = eval(geo) # eval 함수로 dictionary형태 그대로 선언해버린다.
state_geo_dict = {}
for idx in range(len(geo_dict['features'])): # json 파일 내부를 들여다 본후 주 이름 : 좌표 형태로 넣어주기
tmp_key = geo_dict['features'][idx].get('properties').get('name')
tmp_value = geo_dict['features'][idx].get('geometry').get('coordinates')
state_geo_dict.setdefault(tmp_key, tmp_value)
state_geo_dict
데이터 프레임으로 선언한 후 값을 넣어준다.
geo_df = pd.DataFrame(index=state_geo_dict.keys(), columns = ['geometry'])
geo_df
for key, value in state_geo_dict.items():
geo_df.loc[key, 'geometry'] = value
[’Alaska’, ‘Hawaii’]등은 geometry 정보가 4차원으로 되어있다.
4차원 배열 (4d array to geometry)을 geomtry로 만들기 애먹었었는데, shapely에 있는 unary_union 메서드를 사용하면 쉽게 변환이 가능하다.
따라서, shapely의 메서드들을 이용해 3차원으로 쪼개 MultiPolygon으로 만든 뒤 다시 unary_union으로 합쳐준다.
import geopandas as gpd
from shapely.geometry import MultiPolygon, Polygon
from shapely.ops import unary_union
# 3d_array를 Multypolygon으로 변환
def to_polygon(coordinate):
polygons = [Polygon(coords) for coords in coordinate]
multi = MultiPolygon(polygons)
return multi
# 4차원 array를 geometry로 변환
def to_geo_4darray(array):
multi = []
for array_3d in tmp_geo:
polygons = [Polygon(coord) for coord in array_3d]
multi.append(MultiPolygon(polygons))
return unary_union(multi) # 각각의 MultiPolygon을 하나로 합쳐줌
for idx in geo_df.index:
coordinates = geo_df.loc[idx, 'geometry']
if idx not in ['Alaska', 'Hawaii', 'Maryland', 'Michigan', 'Rhode Island', 'Virginia', 'Washington']:
geo_df.loc[idx, 'geometry'] = to_polygon(coordinates)
else:
geo_df.loc[idx, 'geometry'] = to_geo_4darray(coordinates)
geopandas 의 DataFrame 객체로 선언해준다.
import geopandas as gpd
geo_df = gpd.GeoDataFrame(geo_df, geometry='geometry')
- MultiPolygon으로 정상적으로 입력되었다.
geopandas의 구조는 다음과 같다
geopandas.GeoDataFrame은 pandas.DataFrame의 subclass로서, geometry를 다를 수 있다. 일반적인 데이터와 geopandas.GeoSeries가 합쳐진 형태로, geometry와 함께 다른 데이터들을 담으면 된다.
따라서 방금 넣은 geometry컬럼을 geometry로 지정한 후, 다른 data를 넣어 시각화 해주면 된다.
- 이제 geometry DataFrame을 만들었으니, 시각화 해보겠다.
Plotly를 이용한 시각화
- geo_df에 시각화 하고자 하는 값을 추가한다.
geo_df['randint'] = 3 + 2.5 * np.random.randn(51) # 평균 3, 분산 2.5인 정규분포로 샘플값 넣었다.
# 시각화하고자 하는 값을 추가하여 넣으면 된다.
import plotly.io as pio
fig = px.choropleth(geo_df['randint'], locations=geo_df.index, geojson=geo_df['geometry'], color='randint', # color 인자로 색을 구분하고자 하는 인자를 넣어준다.
color_continuous_scale='Oranges',
hover_name=geo_df.index, hover_data='randint', title='randint by state')
fig.update_geos(fitbounds="locations", visible=True) # 요걸 해줘야 원하는 지점 지도를 그릴 수 있다.
# pio.write_html(fig, file='score_by_state_choropleth.html', auto_open=True)
# 필요시 html로 저장
fig.show()