1

我在 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并且随着调用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 问题。为什么这种结构如此占用内存并且有更好的方法吗?顺便说一句,将生成的 Folium 地图保存为 HTML 文件map.save('map.html')会创建一个巨大的 22mb 的 HTML 文件。

4

1 回答 1

2

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

于 2016-08-24T14:54:35.867 回答