Python Mapboxgl로 지도 시각화하기

PNG

mapboxgl은 WGL과 Mapbox 벡터 타일을 사용하는 큰 규모의 데이터를 다루는 경우에 지도 시각화에 주로 사용하는 Folium 보다 훨씬 더 높은 성능을 자랑한다고 한다. mapboxgl에서 지원하는 여러 클래스들을 살펴보고 구체적으로 어떻게 지도를 시각화할 수 있는지 알아보자.


Mapbox Access Token 발급하기

PNG


Mapbox Access Token을 설정파일(config.py)에 추가

프로젝트 경로에 config.py 파일을 만든다. 이 파일을 열어 Mapbox에서 발급받은 Access Token을 아래와 같이 token의 값으로 할당한다.

config.py

token = "mapbox access token"


Mapboxgl 설치

공간정보를 Python으로 시각화할 수 있도록 도와주는 Mapboxgl 라이브러리를 아래와 같이 설치한다.

pip install mapboxgl

pandasjupyter가 설치되어 있지 않다면 같이 설치한다.

# 이미 설치된 경우 아래 설치 명령어는 패스
pip install pandas jupyter


모듈 임포트하기

설치한 mapboxgl, pandas 그리고 설장파일(config.py)에 저장해둔 Mapbox의 인증키(mapbox_key) 값을 불러온다.

import mapboxgl
import pandas as pd
from config import token

print(f"Mapboxgl Version: {mapboxgl.__version__}")
Mapboxgl Version: 0.10.2


샘플 데이터 가져오기

mapboxgl-jupyter GitHub에서 제공하는 샘플 데이터(examples-data-points.csv)를 가져와 시각화해보자. 샘플 데이터는 아래와 같이 Pandas DataFrame으로 바로 가져올 수 있다.

data_url = 'https://raw.githubusercontent.com/mapbox/mapboxgl-jupyter/master/examples/data/points.csv'
df = pd.read_csv(data_url)
df.head()
Avg Total Payments Avg Covered Charges Total Discharges Avg Medicare Payments admin1_id Provider Id admin2_id lon lat date
0 8749.025109 35247.02815 58.750000 7678.214348 USA101 10001 USA201069 -85.362856 31.216215 1/1/14 12:00 AM
1 6812.131224 16451.09204 28.959184 5793.631429 USA101 10005 USA201119 -88.142797 32.452976 1/2/14 12:00 AM
2 8197.237907 36942.35744 45.360465 7145.959535 USA101 10006 USA201077 -87.682872 34.794052 1/3/14 12:00 AM
3 4860.829091 12079.53682 27.409091 4047.025455 USA101 10007 USA201039 -86.254597 31.291993 1/4/14 12:00 AM
4 5898.136667 16148.75222 17.888889 4963.547778 USA101 10008 USA201041 -86.265102 31.693554 1/5/14 12:00 AM


CircleViz

CircleViz 클래스는 원 모양의 지도를 생성하는 기능을 제공한다. mapboxgl에서 create_color_stops, df_to_geojson 그리고 CircleViz 를 아래와 같이 불러온다.

from mapboxgl.utils import create_color_stops, df_to_geojson
from mapboxgl.viz import CircleViz

mapboxgl을 이용해 지도 시각화를 하기 위해서는 DataFrame 형태의 데이터를 GeoJson 형태로 변환해주어야 한다. df_to_geojson 을 이용하면 간단하게 GeoJson 형태의 데이터를 얻을 수 있다.

# Pandas DataFrame을 GeoJson으로 변환하기
points = df_to_geojson(df, 
                       properties=['Avg Medicare Payments', 'Avg Covered Charges', 'date'],
                       lat='lat', lon='lon', precision=3)

지도 위에 시각화할 원 모양에 색상을 부여할 수도 있다. create_color_stops를 이용하면 미리 설정한 데이터 구간에 맞게 다양한 색상을 지정할 수 있다. 색상은 ColorBrewer로 검색해보면 다양한 색상 조합을 찾아볼 수 있다.

# 색상 설정하기
color_breaks = [0,10,100,1000,10000]
color_stops = create_color_stops(color_breaks, colors='YlOrRd')
color_stops
[[0, 'rgb(255,255,178)'],
 [10, 'rgb(254,204,92)'],
 [100, 'rgb(253,141,60)'],
 [1000, 'rgb(240,59,32)'],
 [10000, 'rgb(189,0,38)']]

이제 CircleViz 에 아래와 같이 적당한 인자들을 넣어주면 지도 위에 마법처럼 시각화가 끝난다.

# CircleViz 객체 만들기
viz = CircleViz(points,
                access_token=token,
                height='400px',
                color_property='Avg Medicare Payments',
                color_stops=color_stops,
                label_property='Avg Medicare Payments',
                stroke_color='black',
                center=(-95, 40),
                zoom=3,
                below_layer='waterway-label')
viz.show()


ClusteredCircleViz

ClusteredCircleViz 클래스는 클러스터링된 원 모양 지도를 만들어 준다. 클러스터의 반경과 색상은 포인트 각각의 밀도에 따라 결정된다. 추가로 mapboxgl에서 ClusteredCircleViz 를 불러온다.

from mapboxgl.viz import ClusteredCircleViz

create_color_stops를 이용해 색상을 설정한다.

# 색상 설정하기
color_breaks = [1,10,50,100]
color_stops = create_color_stops(color_breaks, colors='YlOrRd')

이번에도 ClusteredCircleViz 에 아래와 같이 적당한 인자들을 넣어주면 시각화가 끝난다.

viz = ClusteredCircleViz(points,
                         access_token=token,
                         color_stops=color_stops,
                         radius_stops=[[1, 5], [10, 10], [50, 15], [100, 20]],
                         radius_default=2,
                         cluster_maxzoom=10,
                         cluster_radius=30,
                         label_size=12,
                         opacity=0.9,
                         center=(-95, 40),
                         zoom=3)

viz.show()


GraduatedCircleViz

GraduatedCircleViz 클래스는 값의 크기에 따라 점진적으로 커지는 원 모양을 시각화할 수 있다. mapboxgl에서 GraduatedCircleVizcreate_radius_stops 를 불러온다.

from mapboxgl.viz import GraduatedCircleViz
from mapboxgl.utils import create_radius_stops

이번에는 색상 설정도하고, 색상 설정에 사용한 데이터 외에 다른 데이터를 기준으로 원 모양 크기도 설정해보자.

# 색상 설정하기
measure_color = 'Avg Covered Charges'
color_breaks = [round(df[measure_color].quantile(q=x*0.1), 2) for x in range(2, 10)]
color_stops = create_color_stops(color_breaks, colors='YlOrRd')

# 원 모양 크기 설정하기
measure_radius = 'Avg Medicare Payments'
radius_breaks = [round(df[measure_radius].quantile(q=x*0.1), 2) for x in range(2,10)]
radius_stops = create_radius_stops(radius_breaks, 0.5, 10)

매직!

viz = GraduatedCircleViz(points,
                         access_token=token,
                         color_property='Avg Covered Charges',
                         color_stops=color_stops,
                         radius_property='Avg Medicare Payments',
                         stroke_color='black',
                         stroke_width=0.5,
                         radius_stops=radius_stops,
                         center=(-95, 40),
                         zoom=3,
                         below_layer='waterway-label')

viz.show()


HeatmapViz

HeatmapViz 클래스는 열 지도를 생성하는 기능을 제공한다. mapboxgl에서 HeatmapVizcreate_weight_stops 를 불러온다.

from mapboxgl.viz import HeatmapViz
from mapboxgl.utils import create_weight_stops
# 열 지도 설정하기
heatmap_color_stops = create_color_stops([0.01,0.25,0.5,0.75,1], colors='RdPu')
heatmap_radius_stops = [[0,1], [15, 40]]

color_breaks = [0,10,100,1000,10000]
color_stops = create_color_stops(color_breaks, colors='Spectral')

heatmap_weight_stops = create_weight_stops(color_breaks)

나와라 열 지도!

viz = HeatmapViz(points,
                 access_token=token,
                 weight_property='Avg Medicare Payments',
                 weight_stops=heatmap_weight_stops,
                 color_stops=heatmap_color_stops,
                 radius_stops=heatmap_radius_stops,
                 opacity=0.9,
                 center=(-95, 40),
                 zoom=3,
                 below_layer='waterway-label')

viz.show()


ChoroplethViz

ChoroplethViz 는 다각형 정보도 그려주고 그에 연결된 데이터를 시각화하는 기능을 제공한다. mapboxgl에서 ChoroplethViz를 불러오자.

from mapboxgl.viz import ChoroplethViz

이번에는 위에서 사용하던 데이터 말고 다른 GeoJson을 이용해보자.

geojson_url = 'https://raw.githubusercontent.com/mapbox/mapboxgl-jupyter/master/examples/data/us-states.geojson'

Easy

viz = ChoroplethViz(geojson_url,
                     access_token = token,
                     color_property='density',
                     color_stops=create_color_stops([0, 50, 100, 500, 1500], colors='YlOrRd'),
                     color_function_type='interpolate',
                     line_stroke='--',
                     line_color='rgb(128,0,38)',
                     line_width=1,
                     line_opacity=0.9,
                     opacity=0.8,
                     center=(-96, 37.8),
                     zoom=3,
                     below_layer='waterway-label')
viz.show()


ImageViz

ImageViz 클래스는 png 타입의 이미지 데이터를 지도 위에 올려주는 기능을 제공한다.

from mapboxgl.viz import ImageViz

img_url = 'https://raw.githubusercontent.com/mapbox/mapboxgl-jupyter/master/examples/data/mosaic.png'

# Coordinates must be an array in the form of [UL, UR, LR, LL]
coordinates = [[-123.40515640309, 38.534294809274336],
               [-115.92938988349292, 38.534294809274336],
               [-115.92938988349292, 32.08296982365502],
               [-123.40515640309, 32.08296982365502]]

# Create the viz
viz = ImageViz(img_url, coordinates, access_token=token,
               height='600px',
               center=(-119, 35),
               zoom=5,
               below_layer='waterway-label')
viz.show()


참고

댓글남기기