大数据量下的图表显示

如何解决数据量较大时,图表的视觉展示出现的性能问题?

1.提升图表控件性能。(UI,绘图)

重写控件(不会)

2.对数据进行采样,保留特征点。(减少数据)

使用采样算法


对于间隔一定的时序数据来说,通常以曲线图的方式来展现数据随时间变化的线性关系,进而通过视觉方式来直观判断整个采集过程中数据的波动情况,如上升,下降,陡然跳变等。

均匀采样。这是最容易想到的办法。从所有数据中,等间隔地获取我们想要的数据,然后将其他数据直接丢弃掉。但是,有一个问题:我们无法判断所丢弃的数据中是否存在特征点或异常值,数据在图表上的曲线“形状”被改变了,那些波峰,波谷,跳变可能被抹去了。显然,这样的结果不是我们所想要的。

RDP算法(拉默·道格拉斯·普克算法)[1]。通常,这种算法广泛地用于GIS中轨迹的压缩,保留原始曲线图形的形状。压缩曲线,降低绘制进度,减少点的数量,保留曲线形状,这是它的用途。我们的目的是什么呢?在保留图表上曲线形状的情况下,尽可能降低点的数量,从而解决图表控件因数据量太大所造成的性能问题。将它作为数据采样算法,应用到实际图表展示中,效果似乎也不错。但它也有一个问题:它的阈值设定是根据曲线波动的幅度来确定的,我们无法预测下一条曲线的波动情况进而确定采样算法的阈值,或者说在应用到图表展示时比较困难。它就像“玄学调参”般无法去确定一个具体的阈值设定。因为采集的数据在未展示时,必须再次通过计算方式来动态地判断它的局部或整体的波动状况,从而引入更多的不确定性。不确定意味着更多的时间,性能的下降。

LTTB算法[2][3][4]。根据这篇博客[5]的介绍,LTTB算法主要源于Visvalingam-Whyatt算法[6][7]。该算法能保留数据在图表坐标上的“形状”特征,最重要的是,算法的阈值设定是根据曲线预期得到的点的数量来确定。也就是说,我们可以在设定指定个数点的情况下,尽可能的保留原始数据在图表上的视觉特征。而数据采样的预期数目又可以根据图表在屏幕上的像素来确定。根据图像信号采样中的奈奎斯特频率[8][9]来说,绘制任何大于屏幕分辨率1/2的点数,是一种浪费[10]。这样,我们便可以通过图表在显示界面的实际宽度,进而确定数据的采样个数,得到一个相对比较好的图表显示效果。

如果你使用python,这里[11]也有对应的算法。


  1. https://en.wikipedia.org/wiki/Ramer–Douglas–Peucker_algorithm ↩︎

  2. https://blog.csdn.net/qq_37960007/article/details/109445735?spm=1001.2014.3001.5501 “【时间序列降维】一种领先国内的降维算法—LTTB降维拟合算法” ↩︎

  3. https://github.com/sveinn-steinarsson/flot-downsample/ “LTTB 算法作者的 Github 代码示例” ↩︎

  4. https://skemman.is/handle/1946/15343 “LTTB 算法作者的原始论文” ↩︎

  5. https://www.cnblogs.com/T-ARF/p/14624698.html ↩︎

  6. https://en.wikipedia.org/wiki/Visvalingam–Whyatt_algorithm ↩︎

  7. https://blog.csdn.net/sinat_41310868/article/details/114500282 "常用的地图数据概化算法:Douglas-Peucker 与 Visvalingam-Whyatt " ↩︎

  8. https://en.wikipedia.org/wiki/Nyquist_frequency ↩︎

  9. https://blog.csdn.net/qq_36763031/article/details/104020114 “奈奎斯特采样定理—以二维图像为例” ↩︎

  10. https://stackoverflow.com/questions/952657/most-performant-way-to-graph-thousands-of-data-points-with-wpf “Most performant way to graph thousands of data points with WPF?” ↩︎

  11. https://pypi.org/project/lttb/ ↩︎