2016-08-24 147 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 

這個循環運行非常緩慢,大約增加。 200mb到相關python 3.5進程的內存使用量,每循環運行一次!事實上,在循環運行幾次之後,我的整個macbook正在放慢速度 - 即使鼠標滯後。滾動和縮放時,關聯的地圖也很滯後,而且彈出窗口打開速度很慢。如果不是很明顯,我對Python分析和Web可視化世界很陌生,所以也許在這裏顯然是非常低效的。

我想知道這是爲什麼,如果有一個更好的方式讓地圖彈出窗口中出現Bokeh圖表。從我已經完成的一些基本實驗來看,問題似乎並沒有出現Bar的調用 - 當我添加對file_html的呼叫時,內存使用情況似乎真的急劇上升,並且隨着添加對folium.element.IFrame的調用而變得更糟。似乎存在某種內存泄漏,這是由於重新運行相同代碼時內存使用量的增加。

如果有人對如何以更高效的方式達到相同的效果(點擊Folium標記時打開散焦圖表)有所瞭解,我將非常感激!

更新以下一些實驗

我已經通過一步一步循環運行,併爲多個步驟被添加在試圖隔離什麼一段代碼使得該問題在內存使用觀察到的變化。在散景方面,最大的罪魁禍首似乎是對file_html()的調用 - 當通過該步驟運行循環時,每運行一次,相關的python 3.5進程就會增加大約5mb的內存使用量(循環創建18個圖表),即使在包含bokeh.io.curdoc().clear()

然而,更大的問題似乎是由Folium驅動的。運行整個循環,包括使用Bokeh生成的HTML創建Folium IFrame,並且鏈接到IFrame的地圖標記將每次運行的Python進程的內存使用量增加25-30mb。

所以,我想這是向更多的大葉問題。爲什麼這個結構如此內存密集,有沒有更好的方法?順便說一下,將生成的Folium地圖保存爲HTML文件map.save('map.html')會創建一個巨大的22MB HTML文件。

回答

0

有許多不同的使用情況,其中一些使用情況有不可避免的折衷。爲了讓其他用例變得非常簡單和方便,Bokeh有一個隱含的「當前文檔」並且在那裏積累東西。對於循環中依次生成一堆圖的特定用例,您需要在每個循環之間調用bokeh.io.reset_output()以防止這種累積。

+0

感謝您的建議 - 但是,這並不完全解決問題。在散景方面,基於一些測試,創建圖表本身似乎沒有使用太多的內存(我只用這個循環制作了18個)。看起來,調用'file_html()'然而增加了內存使用情況,雖然沒有被'bokeh.io.curdoc()。clear()'清除掉。是否有更好的方式從Bokeh圖表獲取底層HTML?無論哪種方式,我要編輯我的問題,因爲現在似乎該問題更多地受葉片而不是Bokeh驅動。 –

+0

也有'bokeh.io.reset_output()'這實際上可能更全面的這種情況。我已經更新了答案。 – bigreddot