본문 바로가기

시행착오 노트

folium HeatMapWitheTime 쓸 때 좀 빡치는거.

1. 디스플레이 인덱스가 1부터 시작한다.

이 녀석의 사용 새부터 잠깐 살펴보자.

HeatMapWithTime(data, index=None, name=None, radius=15, min_opacity=0, max_opacity=0.6, scale_radius=False, gradient=None, use_local_extrema=False, auto_play=False, display_index=True, index_steps=1, min_speed=0.1, max_speed=10, speed_step=0.1, position='bottomleft', overlay=True, control=True, show=True)

요렇게 되어있다.
뭐 간단히 예시를 들면, 아래와 같이 사용한다.

map = folium.Map(location=[37.56071136, 126.91485473], zoom_start=14)

lat_lng_by_hour = [
    [[37.56071136, 126.91485473, 0.3]], # 0 
    [[37.56071136, 126.91485473, 0.4]], # 1
    [[37.56071136, 126.91485473, 0.5]], # 2
    [[37.56071136, 126.91485473, 0.6]], # 3
    [[37.56071136, 126.91485473, 0.1]], # 4
]

plugins.HeatMapWithTime(lat_lng_by_hour,
                            radius=20
                            ).add_to(map)
map

주목할 부분은, data 인자로 들어가는 저 3차원 배열이다.
바깥쪽 차원부터, 시간 - 포인트들 - 해당 포인트의 좌표(위도, 경도)와 가중치(0~1 값)으로 구성되어있다.
예를 들어,
lat_lng_by_hour[0] 은 0번째 시간의 모든 점들을 담고 있으며,
lat_lng_by_hour[0][1] 은 0번째 시간의 점 중, 첫 번째 점을 나타낸다.
lat_lng_by_hour[0][1][0] 은 0번째 시간의 점 중, 첫 번째 점의 위도를 나타낸다.

뭐 아무튼, 지금 보려고 하는 것은, 이를 출력하면

위와 같이 나온다.

뭐가 문제인가? 싶을 수 있는데, 좌단 하측 시간 디스플레이 바를 보면, 1부터 시작함을 알 수 있다.
우리는 배열에서 0-4 의 인덱스 범위를 가지는데, 지도의 디스플레이 바에서는 1-5 로 등장하는 것이다.

이게 언제 문제가 되냐?
lat_lng_by_hour 의 배열이 정확한 시간 순으로 저장되어있는 경우에 문제다.

예를 들어, lat_lng_by_hour[0] 은 0시의 데이터를 담는데, 지도 디스플레이 바에서는 1로 시작하니, 사실 0시의 데이터인데 1시의 데이터처럼 보일 수 있다는 것이다.

쉽게 말해, 0-23시 데이터가 1-24시로 등장하니 ,,, 아무튼 이를 해결해주려면, 0번째 인덱스를 강제로 맨 뒤로 넣는 수밖에 없는 듯하다. (디스플레이 인덱스 바의 시작을 1이 아니라 0으로 조정하는 방법을 찾아봤는데, 잘 모르겠다. 왜 이렇게 만들었지??)
예를 들어 아래와 같은 방법으로 말이다.

# 맨 처음 0시 데이터를 제일 마지막으로 보내기
lat_lng_by_hour.append(lat_lng_by_hour.pop(0))

2. data 파라미터는 파이썬 리스트 자료형만 인식한다.

numpy 배열 넣으면 안 된다.
그냥 파이썬 리스트형으로 넣어야 한다.

만약, pandas DataFrame에서 [위도, 경도, 가중치] 를 뽑아올 경우, 기본은 numpy로 되어있는데, tolist() 메쏘드를 이용하여 파이썬 리스트형으로 바꿔줘야 한다.

HeatMapWitheTime 을 쓰는데 조금의 데이터도 렌더링이 안된다면, 이 자료형을 의심해보자. 내가 numpy 자료형을 인자로 준건 아닌지.