尝试使用 Bokeh 绘制 TimeSlider 地图时出现内存问题

Memory Issue when trying to plot a TimeSlider map using Bokeh

我正在尝试使用 Bokeh 绘制 TimeSlider 地图,我对使用这些工具还很陌生。我正在使用 Jupyter notebook。

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

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

这是我的代码:

创建 GeoDataFrame

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的参数吗?你知道如何处理这样的问题吗?

提前致谢!

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

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

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

我想说有几个选项:

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

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

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