Python-使用Holoviews Bokeh绘制大型数据集的特定子集

问题描述

我想做的是创建一个具有较大时间序列的平移和放大/缩小交互的交互式图。

考虑Jupyter Notebook中的下一种情况:

import numpy as np

import holoviews as hv
import holoviews.plotting.bokeh
from holoviews.operation import decimate

hv.extension('bokeh')

n_samples = 1_000 #100_000_000

x = np.linspace(0.0,10.0,n_samples)

y = np.zeros((64,n_samples))
r = np.random.rand(n_samples)

for i in range(64):
    y[i] = np.sin(r + np.random.rand(n_samples)*0.3)+i


curves = hv.Curve( (zip(x,y[0,:])) ).opts(height=400,width=800)
for i in range(1,64):
    curves *= hv.Curve( (zip(x,y[i,:])) ) 

curves = curves.options({'Curve': {'color': 'black'}})

curves = decimate(curves).collate()

curves.redim(x=hv.Dimension('x',range=(0,2)))

使用n_samples=1_000效果不错,但是当前的样本数量约为10-100百万个点,因此它的运行速度非常慢。

我认为这是因为它创建了所有图形元素并将它们存储在内存中。然后,当我使用“平移”工具更改x的范围时,它必须搜索所有需要绘制的元素中的哪一个,这是最慢的部分。

如果是这种情况,一种解决方案可能是考虑画布的范围,从阵列中仅绘制1k-5k点的子集。我不需要画布上的所有点,因此可以即时计算它们。

您知道解决此问题的另一种方法吗?我是使用bokeh和Holoviews的新手。

谢谢!

解决方法

好的。正如Sander所建议的那样,您可以使用Datashader在浏览器外部渲染数据,以提高速度和效率。定义curves后,只需执行以下操作:

import holoviews.operation.datashader as hd

hd.rasterize(curves)  # as the last line in your Jupyter notebook cell

您不需要进行抽取。