首页 > 解决方案 > 尝试使用 Bokeh 绘制 TimeSlider 地图时出现内存问题

问题描述

我正在尝试使用 Bokeh 绘制 TimeSlider 地图,而我对使用这些工具还是很陌生。我正在研究 Jupyter 笔记本。

我需要给出 GeoDataFrame 的列名列表作为绘图函数的参数。问题是,当我尝试在我的 GeoDataFrame 中添加我想要的列时,我可以添加 6 列然后我的计算机崩溃(当尝试添加第 7 列时,RAM 准瞬间上升)。我尝试在 Google Collab 中运行我的笔记本,但在向我的 GeoDataFrame 添加第 7 列时,我的会话也崩溃了。我没有从 Python 中得到任何错误,除了重新启动计算机之外我什么也做不了。

当我尝试实现一个只有 6 年的 Slider 时,情节是正确的,但我想覆盖 50 年,但我离它还很远。

这是我的代码:

创建地理数据框

df_states = gpd.read_file("countries.geo.json")                    # the GeoDataFrame
frames = {i:dat for i, dat in meat_production.groupby('Year')}     # getting the useful info from another dataset

years = range(1961, 2017)

for y in years:
    frames[y] = frames[y].drop('Year', axis=1)
    df_states = df_states.merge(frames[y], on="id")
    df_states = df_states.rename(columns={'Value': 'Meat %d'%y})

for 循环非常适合第一次迭代并给出我想要的结果。

绘制地图

slider_columns = ["Meat %d"%i for i in years]

df_states.plot_bokeh(
    figsize = (900,600),
    simplify_shapes=10000,
    slider = slider_columns,
    slider_range = years,
    slider_name = 'Year',
    colormap = 'Inferno',
    hovertool_columns = ['id']+slider_columns,
    title='Meat production'
)

还有另一种方法来定义 plot_bokeh 的参数吗?你知道如何处理这样的问题吗?

提前致谢!

标签: python-3.xmemorybokehjupyter-lab

解决方案


plot_bokeh函数不是实际 Bokeh 库的一部分。也许它是建立在 Bokeh 之上的其他一些独立的第三方库的一部分?无论如何,我将假设它创建独立的输出,而不是 Bokeh 服务器应用程序。在这种情况下,所有数据都会预先发送到浏览器。地理数据尤其会迅速爆炸。您没有指定有关数据大小的任何详细信息,但作为一个假设示例:

50 yrs * 100 shapes/yr * 10k pt/shape * 2 coords/pt * 8 bytes/coord ~= 800 MB

而这仅仅是开始。这是原始数据空间坐标。所有这些坐标都必须转换为 2x 的屏幕(即像素)坐标,所以现在您看到的是 1.6GB。而且还没有完成。Bokeh 旨在提供高水平的交互性,因此它将所有这些数据放在一个省时的空间索引中(以支持悬停、点击工具等)。目前没有办法选择退出(虽然有一个提议的特性来添加一种方式),这是另一个随着数据大小快速扩展的巨大内存成本。我们甚至没有提到任何可能会发送的每个形状或每个顶点的属性数据。但简而言之,您很容易在浏览器中创建大约 3-6GB 的数据用这个例子。那是不可行的,事情会在这个水平之前开始下降。

我想说有几个选择:

  • 不要发送实际的形状数据。使用诸如 Datashader 和/或 GeoViz 之类的东西来预渲染可以在 Bokeh 中显示的图像。这将大大减少浏览器中的数据大小

  • 创建 Bokeh 服务器应用程序。那么浏览器一次只需要保存一年的数据。滑块的回调可以是一个真正的 Python 函数,它只挑选一年的数据,并更新绘图以仅使用较小的数据集。

  • 如果形状每年都没有变化,那么您也可以(可能)只发送一份形状副本,而不是每年发送一份副本。至少,您当然可以在纯 Bokeh 代码中实现它。(不确定这是在 Bokeh 上构建的任何库)


推荐阅读