2016-08-24 3 views
1

Jupyter 노트북에서 Folium과 Bokeh를 함께 사용하고 있습니다. 나는 데이터 프레임을 순환하고, 각 행마다 Folium 맵에 마커를 삽입하고, 별도의 데이터 프레임에서 일부 데이터를 가져 와서 데이터에서 Bokeh 차트를 만든 다음 Bokeh 차트를 Folium 맵 팝업 메뉴에 삽입합니다. IFrame. 코드는 다음과 같습니다 :Folium + Bokeh : 성능이 낮고 방대한 메모리 사용량이 있습니다.

map = folium.Map(location=[36.710021, 35.086146],zoom_start=6) 

for i in range (0,len(duty_station_totals)): 

    popup_table = station_dept_totals.loc[station_dept_totals['Duty Station'] == duty_station_totals.iloc[i,0]] 

    chart = Bar(popup_table,label=CatAttr(columns=['Department/Program'],sort=False),values='dept_totals', 
       title=duty_station_totals.iloc[i,0] + ' Staff',xlabel='Department/Program',ylabel='Staff',plot_width=350,plot_height=350) 

    hover = HoverTool(point_policy='follow_mouse') 
    hover.tooltips=[('Staff','@height'),('Department/Program','@{Department/Program}'),('Duty Station',duty_station_totals.iloc[i,0])] 
    chart.add_tools(hover) 

    html = file_html(chart, INLINE, "my plot") 

    iframe = folium.element.IFrame(html=html, width=400, height=400) 

    popup = folium.Popup(iframe, max_width=400) 

    marker = folium.CircleMarker(duty_station_totals.iloc[i,2], 
           radius=duty_station_totals.iloc[i,1] * 150, 
           color=duty_station_totals.iloc[i,3], 
           fill_color=duty_station_totals.iloc[i,3]) 

    marker.add_to(map) 

    folium.Marker(duty_station_totals.iloc[i,2],icon=folium.Icon(color='black',icon_color=duty_station_totals.iloc[i,3]),popup=popup).add_to(map) 


map 

이 루프는 매우 느리게 실행되며 약 10 초입니다. 루프의 실행 당 관련 파이썬 3.5 프로세스의 메모리 사용량에 200MB! 사실, 루프를 몇 번 실행 한 후 내 전체 맥북은 크롤링 속도를 늦추고 있습니다. 심지어 마우스가 뒤쳐져 있습니다. 관련지도는 스크롤 및 확대/축소시 너무 많이 걸리고 팝업이 느리게 열립니다. 명확하지 않은 경우, 저는 파이썬 분석과 웹 비주얼라이제이션 세계에 익숙하지 않습니다. 아마도 여기에 매우 비효율적 인 무언가가있을 것입니다.

나는 이것이 왜 있는지 그리고 Bokeh 차트를지도 팝업에 표시하는 더 좋은 방법이 있는지 궁금합니다. 약간의 기본 실험에서, 문제가 Bar에 대한 호출과 같이 보이지 않습니다. 메모리 사용이 file_html에 대한 호출을 포함하고 실제로 folium.element.IFrame에 대한 호출이 추가 될 때 실제로 급증하는 것처럼 보입니다. 동일한 코드를 다시 실행하면 메모리 사용량이 증가하기 때문에 메모리 누수가 발생하는 것처럼 보입니다.

보다 효과적인 방식으로 동일한 효과 (폴크스 마커를 클릭하면 열리는 Bokeh 차트)를 달성하는 방법에 대한 아이디어가 있다면 정말 감사하겠습니다. 일부 실험

내가 단계별로 루프 단계를 실행하고 더 많은 단계가 시도하고이 문제를 운전 코드의 어떤 부분 분리에 추가로 메모리 사용량의 변화를 관찰 한 다음

업데이트. 보케 (Bokeh) 측면에서 가장 큰 범인은 file_html()에 대한 호출 인 것 같습니다.이 단계를 통해 루프를 실행하면 관련된 Python 3.5 프로세스 (루프는 18 개 차트 생성 중임)에 약 5MB의 메모리 사용량을 추가합니다. bokeh.io.curdoc().clear().

그러나 더 큰 문제는 Folium이 주도하는 것으로 보입니다. Bokeh에서 생성 된 HTML과 IFrames에 연결된지도 마커를 사용하여 Folium IFrame을 만드는 등 전체 루프를 실행하면 실행 당 Python 프로세스의 메모리 사용량에 25-30MB가 추가됩니다.

이렇게 나는 Folium 질문에 더 많은 관심을 가지게되었다고 생각합니다. 이 구조가 왜 메모리 집약적이며 더 좋은 방법이 있습니까? 그런데 결과 Folium 맵을 map.save('map.html')으로 HTML 파일로 저장하면 거대한 22MB HTML 파일이 생성됩니다.

답변

0

많은 유스 케이스가 있으며, 그 중 일부는 피할 수없는 절충점이 있습니다. 다른 유스 케이스를 매우 간단하고 편리하게 만들기 위해 Bokeh는 암시 적 "현재 문서"를 가지고 거기에 물건을 축적합니다. 루프에서 순차적으로 일련의 플롯을 생성하는 특정 용도의 경우이 누적을 방지하기 위해 각각 bokeh.io.reset_output()을 호출해야합니다.

+0

조언을 주셔서 감사합니다. 그러나 이것은 완전히 문제를 해결하지 못합니다. Bokeh 측면에서 일부 테스트를 기반으로 차트 자체를 만드는 것은 너무 많은 메모리를 사용하지 않는 것입니다 (저는이 루프로 18 개만 만듭니다). 'file_html()'에 대한 호출은'bokeh.io.curdoc(). clear()'에 의해 지워지지 않는 메모리 사용을 추가하는 것 같습니다. Bokeh 차트에서 기본 HTML을 가져 오는 더 좋은 방법이 있습니까? 어느 쪽이든 문제는 Bokeh보다는 폴륨에 의해 더 많이 움직이기 때문에 내 질문을 편집 할 것입니다. –

+0

'bokeh.io.reset_output()'도 있는데 실제로 이런 종류의 시나리오에서 더 포괄적 일 것입니다.답변을 업데이트했습니다. – bigreddot