首页 > 解决方案 > Choroplethmapbox 渲染缓慢?

问题描述

在过去的几天里,我第一次使用 Plotly 和 Dash,希望为地理 NetCDF4 数据开发一个基于浏览器的数据浏览器。到目前为止,它的简单程度给我留下了深刻的印象,但是我发现与某些交互的choroplethmapbox更新和渲染时间比预期的要长。我相信这可能是这里讨论的同一个问题

以下引用此处提供的代码和示例数据,其中可以使用以下方式运行 Dash 应用程序: python choropleth.py(Python 3.7)。

我的数据来源来自一个 4D NetCDF4 文件(在本例中为海洋温度模型 - temp.nc),其维度为时间、深度、纬度和经度。在我的例子中,我只绘制了一个 2D 的叶绿素图,但我希望用户也可以交互地选择所需的时间间隔(以及最终的深度)(渲染将始终在 2D 空间中)。

使用此处的示例,我使用 2D 网格单元的 GeoJSON 文件和 Pandas DataFrame 来渲染海洋温度。一切都按预期工作,但是对滑块值(时间)的任何更改都需要很长时间才能更新(在我的机器上大约 6 秒)。似乎在选择滑块值和运行update_figure()回调之间有一秒钟左右的时间,然后在新的渲染开始在浏览器中发生之前的另外 4-5 秒钟。

回调直接从 NetCDF4 文件中update_figure()读取请求的数据,然后直接更新现有图形字典中的 Z 值并将其作为新图形返回(参见下面的代码片段)。起初我担心响应时间慢是由于从 NetCDF4 读取,但是一个基本的计时函数显示,update_figure()在大多数情况下,回调运行时间不到 0.01 秒。因此,延迟似乎来自Dash 中的@app.callback或渲染函数(post )?update_figure()

# Create the callback and callback function (update_figure)
@app.callback(Output('plot', 'figure'),
              [Input('slide', 'value')],
              [State('plot','relayoutData'),State('plot', 'figure')])
def update_figure(x,r,f):
    t0 = tme.time()
    f['layout']['mapbox']['center']['lat'] = f['layout']['mapbox']['center']['lat']
    f['layout']['mapbox']['center']['lon'] = f['layout']['mapbox']['center']['lon']
    f['layout']['mapbox']['zoom'] = f['layout']['mapbox']['zoom']

    # If the map window has been panned or zoomed, grab those values for the new figure
    if r is not None:
        if 'mapbox.center' in r:
            f['layout']['mapbox']['center']['lat'] = r['mapbox.center']['lat']
            f['layout']['mapbox']['center']['lon'] = r['mapbox.center']['lon']
            f['layout']['mapbox']['zoom'] = r['mapbox.zoom']

    # Extract the new time values from the NetCDF file
    tmp = nc['temp'][x, -1, :, :].values.flatten()
    # Repace the Z values in the original figure with the updated values, leave everything else (e.g. cell geojson and max/min ranges) as-is
    f['data'][0]['z'] = np.where(np.isnan(tmp), None, tmp).tolist()
    print("update_figure() time: ",tme.time()-t0)
    return f

我怀疑缓慢的渲染时间在某种程度上与每个单元多边形的 GeoJSON 相关(总共渲染了 47k 网格单元多边形,每个多边形由 6 个点定义(即总共 284k 点)),不幸的是这不能进一步简化。

我正在寻求有关如何在用户与应用程序交互时加快更新/渲染的建议。我有两个想法包括:

  1. 如果可能,使用 WebGL?从文档中我不清楚是否choroplethmapbox已经使用 WebGL?如果没有,是否有一种途径可以利用它来加快渲染速度?
  2. 实现某种形式的客户端回调,虽然我不知道这是否可能,因为我需要在用户请求时直接从 NetCDF 文件中读取值?也许可以只读取/返回新的 Z 值,然后将其与客户端现有的 GeoJSON 合并?

建议表示赞赏。

标签: pythongeojsonplotly-dashchoropleth

解决方案


推荐阅读