将大型数据集的大小减少 sampling/interpolation 以提高图表性能
Reduce the size of a large data set by sampling/interpolation to improve chart performance
我想在浏览器中使用 d3 显示大量 (>2000) 时间序列数据。 D3 非常适合向用户显示数据子集(~100 点),但我还想要一个 "context" 视图 (like this) 来显示整个数据集并允许用户 select 作为要详细查看的子区域。
但是,当尝试在 d3 中显示那么多点时,性能很糟糕。我觉得一个好的解决方案是 select 数据样本,然后使用某种插值(样条、多项式等,这是我知道该怎么做的部分)来绘制一条曲线与实际数据相当相似。
但是,我不清楚应该如何处理 select 子集。数据(如下所示)具有相当平坦的区域,在这些区域需要较少的样本才能进行适当的插值,而其他区域的绝对导数非常高,需要更频繁的采样。
更复杂的是,数据存在间隙(生成数据的传感器出现故障或超出范围),我想在图表中保留这些间隙而不是通过它们进行插值。不过,检测间隙相当简单,在使用插值绘制整个数据集后简单地将它们剪掉似乎是一个合理的解决方案。
我在 JavaScript 中这样做,但是任何语言的解决方案或问题的数学答案都可以。
我的建议是在更长或更短的时间间隔内取平均值(而不是子样本),并将这些平均值绘制为水平条。我认为这对用户来说是非常容易理解的——如果你尝试一些更花哨的东西,你可能会放弃准确解释正在发生的事情的能力。我假设您可以让用户选择放大或缩小以显示更多或更少的细节。
您或许能够让数据库引擎为您计算间隔内的平均值,因此这也是一个潜在的加速。
至于选择的时间间隔,你可以试试(1)固定的时间间隔,比如1秒、15秒、1分钟、15分钟、小时、天等等;这可能更容易让用户理解,或者 (2) 选择间隔以在整个时间范围内制作固定数量的单位,例如如果您决定以 100 个单位显示 7 小时的数据,则每个单位 = 252 秒。
我知道这并不能完全回答您的问题,但是这个库 可能 可以帮助您在渲染过程中简化您的线条。不确定他们是否处理数据差距。
您可以使用 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);
您可以在网站上看到它的示例 运行:
https://d3fc.io/examples/sample/
最大三角形三桶算法在 'patchy' 的数据上效果很好。它不会改变桶的大小,但会确保包含波峰/波谷,从而很好地表示采样数据。
我想在浏览器中使用 d3 显示大量 (>2000) 时间序列数据。 D3 非常适合向用户显示数据子集(~100 点),但我还想要一个 "context" 视图 (like this) 来显示整个数据集并允许用户 select 作为要详细查看的子区域。
但是,当尝试在 d3 中显示那么多点时,性能很糟糕。我觉得一个好的解决方案是 select 数据样本,然后使用某种插值(样条、多项式等,这是我知道该怎么做的部分)来绘制一条曲线与实际数据相当相似。
但是,我不清楚应该如何处理 select 子集。数据(如下所示)具有相当平坦的区域,在这些区域需要较少的样本才能进行适当的插值,而其他区域的绝对导数非常高,需要更频繁的采样。
更复杂的是,数据存在间隙(生成数据的传感器出现故障或超出范围),我想在图表中保留这些间隙而不是通过它们进行插值。不过,检测间隙相当简单,在使用插值绘制整个数据集后简单地将它们剪掉似乎是一个合理的解决方案。
我在 JavaScript 中这样做,但是任何语言的解决方案或问题的数学答案都可以。
我的建议是在更长或更短的时间间隔内取平均值(而不是子样本),并将这些平均值绘制为水平条。我认为这对用户来说是非常容易理解的——如果你尝试一些更花哨的东西,你可能会放弃准确解释正在发生的事情的能力。我假设您可以让用户选择放大或缩小以显示更多或更少的细节。
您或许能够让数据库引擎为您计算间隔内的平均值,因此这也是一个潜在的加速。
至于选择的时间间隔,你可以试试(1)固定的时间间隔,比如1秒、15秒、1分钟、15分钟、小时、天等等;这可能更容易让用户理解,或者 (2) 选择间隔以在整个时间范围内制作固定数量的单位,例如如果您决定以 100 个单位显示 7 小时的数据,则每个单位 = 252 秒。
我知道这并不能完全回答您的问题,但是这个库 可能 可以帮助您在渲染过程中简化您的线条。不确定他们是否处理数据差距。
您可以使用 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);
您可以在网站上看到它的示例 运行:
https://d3fc.io/examples/sample/
最大三角形三桶算法在 'patchy' 的数据上效果很好。它不会改变桶的大小,但会确保包含波峰/波谷,从而很好地表示采样数据。