通过采样/插值减小大型数据集的大小,以提高图表性能

时间:2015-01-15 19:32:24

标签: javascript math d3.js interpolation

我有一大套(> 2000)时间序列数据,我想在浏览器中使用d3显示。 D3非常适合向用户显示数据的子集(~100个点),但我也想要一个" context" view(like this)显示整个数据集并允许用户选择作为子区域进行详细查看。

然而,当尝试在d3中显示那么多点时,性能非常糟糕。我觉得一个很好的解决方案是选择一个数据样本,然后使用某种插值(样条,多项式等,这是我知道该怎么做的部分)来绘制一条与之类似的曲线。实际数据。

但是,我不清楚我应该如何选择子集。数据(如下所示)具有相当平坦的区域,其中适当插值需要较少的样本,而绝对导数非常高的其他区域需要更频繁的采样。

为了使问题更加复杂,数据存在间隙(生成它的传感器失效或超出范围),我希望保持图表中的这些间隙而不是插值通过他们。然而,检测间隙非常简单,只需用插值绘制整个数据集就可以将它们剪掉,这似乎是一种合理的解决方案。

我在JavaScript中这样做,但任何语言的解决方案或问题的数学答案都可以。

the data in question

3 个答案:

答案 0 :(得分:6)

您可以使用d3fc-sample模块,该模块提供了许多不同的数据采样算法。这是API的样子:

// Create the sampler
var sampler = fc_sample.largestTriangleThreeBucket();

// Configure the x / y value accessors
sampler.x(function (d) { return d.x; })
    .y(function (d) { return d.y; });

// Configure the size of the buckets used to downsample the data.
sampler.bucketSize(10);

// Run the sampler
var sampledData = sampler(data);

您可以在网站上看到它的一个示例:

http://d3fc.github.io/d3fc-sample/

最大三角形三桶算法可以很好地处理“不完整”的数据。它不会改变铲斗尺寸,但确保包含峰值/谷值,这样可以很好地表示采样数据。

答案 1 :(得分:3)

我知道这并没有完全回答你的问题,但是这个库可能会帮助你在渲染过程中简化你的线条。不确定他们是否处理数据缺口。

http://mourner.github.io/simplify-js/

答案 2 :(得分:1)

我的建议是在更长或更短的时间间隔内平均(而非子样本)并将这些平均值绘制为水平条。我认为这对用户来说非常容易理解 - 如果你尝试更好的东西,你可能会放弃准确解释发生了什么的能力。我假设您可以让用户选择放大或缩小以显示更多或更少的细节。

您或许可以让数据库引擎为您计算一段时间内的平均值,这样也可能会加快速度。

关于选择的时间间隔,您可以尝试(1)固定间隔,例如1秒,15秒,1分钟,15分钟,小时,天等等;这可能更容易让用户理解,或者(2)选择在整个时间范围内制作固定数量单位的间隔,例如:如果你决定以100个单位显示7小时的数据,那么每个单位= 252秒。