【问题标题】:Folium + Bokeh: Poor performance and massive memory usageFolium + Bokeh:性能不佳和大量内存使用
【发布时间】:2016-12-31 17:35:02
【问题描述】:

我在 Jupyter 笔记本中同时使用 Folium 和 Bokeh。我正在遍历一个数据框,并为每一行在 Folium 地图上插入一个标记,从单独的数据框中提取一些数据,从该数据中创建一个散景图,然后将散景图嵌入到 Folium 地图弹出窗口中框架。代码如下:

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

这个循环运行非常缓慢,并且增加了大约。每次运行循环,相关 python 3.5 进程的内存使用量为 200mb!事实上,在运行循环几次之后,我的整个 macbook 都在减速,甚至是鼠标滞后。相关地图在滚动和缩放时也会严重滞后,并且弹出窗口打开速度很慢。如果不是很明显,我对 python 分析和网络可视化世界还是很陌生,所以这里可能有一些明显非常低效的东西。

我想知道为什么会这样,以及是否有更好的方法让散景图出现在地图弹出窗口中。从我所做的一些基本实验来看,问题似乎并不在于对 Bar 的调用 - 当我包括对 file_html 的调用时,内存使用量似乎真的飙升,并且随着对 @987654324 的调用变得更糟@ 被添加。由于重新运行相同代码时内存使用量增加,似乎存在某种内存泄漏。

如果有人知道如何以更有效的方式实现相同的效果(单击 Folium 标记时会打开散景图),我将不胜感激!

经过一些实验后更新

我已逐步运行循环并观察到内存使用情况的变化,因为添加了更多步骤以尝试找出导致此问题的代码片段。在散景方面,最大的罪魁祸首似乎是对file_html() 的调用——当通过这一步运行循环时,每次运行它会为相关的 python 3.5 进程增加大约 5mb 的内存使用量(循环创建 18 个图表),甚至当包括bokeh.io.curdoc().clear()

然而,更大的问题似乎是由 Folium 驱动的。运行整个循环,包括使用 Bokeh 生成的 HTML 和链接到 IFrame 的地图标记创建 Folium IFrame,每次运行的 Python 进程的内存使用量会增加 25-30mb。

所以,我想这更像是一个 Folium 问题。为什么这种结构如此占用内存并且有更好的方法吗?顺便说一句,将生成的 Folium 地图保存为带有 map.save('map.html') 的 HTML 文件会创建一个 22mb 的巨大 HTML 文件。

【问题讨论】:

    标签: python-3.x jupyter-notebook bokeh folium


    【解决方案1】:

    有许多不同的用例,其中一些带有不可避免的权衡取舍。为了使其他一些用例变得非常简单和方便,Bokeh 有一个隐含的“当前文档”并在那里不断积累东西。对于在循环中顺序生成一堆图的特定用例,您需要在每个图之间调用bokeh.io.reset_output(),以防止这种累积。

    【讨论】:

    • 感谢您的建议 - 但是,这并不能完全解决问题。在散景方面,根据一些测试,创建图表本身似乎并没有使用太多内存(我只用这个循环制作了 18 个)。然而,似乎对file_html() 的调用增加了bokeh.io.curdoc().clear() 未清除的内存使用量。有没有更好的方法从 Bokeh 图表中获取底层 HTML?无论哪种方式,我都会编辑我的问题,因为现在看来这个问题更多地是由 folium 而不是 Bokeh 驱动的。
    • 还有bokeh.io.reset_output() 在这种情况下实际上可能更全面。我已经更新了答案。
    • 我最终会使用大量内存,同时还显示一个相当简单的(约 100 个标记)叶图。您找到有价值的答案了吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-02
    • 1970-01-01
    • 1970-01-01
    • 2019-02-26
    • 2018-09-09
    • 1970-01-01
    • 2012-09-21
    相关资源
    最近更新 更多