绘制大量数据
Graphing large amounts of data
在我工作的产品中,有一个迭代循环,它可以有几百到几百万次迭代。每次迭代计算一组统计变量(双精度),变量数量最多可达1000(通常为15-50)。
作为循环的一部分,我们绘制迭代过程中变量的变化图,因此X轴是迭代,y轴是变量(按颜色编码):
http://sawtoothsoftware.com/download/temp/walt/graph.jpg
当前数据存储在包含以下内容的文件中:
一个4字节整数,其变量
一个4字节的整数,对于该整数的迭代,
以及该值的8字节双字节。
y轴的总比例随着时间的推移而变化,需要调整图形大小以适应当前比例(这可以在图片中看到)。
以大约5秒的间隔,读取数据并将其绘制在位图上,然后将位图显示给用户。我们试图做一些优化来避免重新绘制整个东西,但如果迭代次数或变量数量变大,我们最终会得到一个需要超过5秒才能绘制的巨大文件。
我正在寻找如何在可能的情况下更有效、更快地处理这么多数据的想法。
在SQL术语中,您应该对结果进行分组和聚合。如果不在屏幕外滚动,就不可能在图形上显示所有10000个数据点。一种方法是,您可以按时间刻度(秒、分钟等)进行分组,并查询AVG()
、MAX()
或MIN()
,以将数据点缩小到较小的刻度。
MySQL示例,按秒分组:
select time_collected, AVG(value)
from Table
group by UNIX_TIMESTAMP(time_collected)
还可以考虑将聚合值与蜡烛图中的可视化相结合。
您应该问问自己,每次迭代显示数据的价值有多大,以及用户真正关心的数据是什么。我认为在这里你需要做的主要事情就是减少你向用户显示的数据量。
例如,如果用户只关心趋势,那么您可以很容易地每隔这么多次迭代(而不是每次迭代)评估这些函数。在上面的图表中,你可能会通过每100次迭代只在曲线上绘制一个值来获得同样丰富的信息,这将使数据集的大小(以及绘制算法的速度)减少100倍。显然,如果您碰巧需要更多细节,您可以对此进行调整。
为了避免在重新绘制时重新计算数据点,只需保留内存中已经绘制的一小部分点,而不是重新计算或重新加载所有数据。您可以避免以这种方式进入磁盘,并且您将不会做同样多的工作来再次渲染所有这些点。
如果你担心由于采样错误而丢失异常值,那么你可以做的一件简单的事情是基于滑动窗口而不是原始数据中的单个样本来计算样本点集。您可以将显示给用户的数据保持在最大值、最小值、平均值、中值附近,并可能计算误差条。
如果你需要变得非常积极,人们已经想出了很多有趣的方法来减少和显示时间序列数据。有关更多信息,您可以查看维基百科的文章,或者查看像R这样的工具包,这些工具包已经内置了很多这样的方法。
最后,这个stackoverflow问题似乎也很相关。
我从图中看到,你在几百个像素上绘制了10000次迭代,所以只需在图中使用百分之一的信息点,忽略其余信息点。对于用户来说,这看起来是一样的
为什么不生成位图(或像XPM这样的像素图)?每个列(或行)对应于迭代,相同颜色的高度(行的宽度)对应于变量值。XPM格式更简单,因为它是文本的(一个字符代表像素)和跨平台的。
- 如何在 Gnuplot 中分别绘制 2 个文件数据?我有一个文件"sin.txt",另一个文件"cos.txt",我想将它们分别绘制在一个图表上
- 使用C++绘制数据结构图
- 在 Mathematica 中绘制来自 c++ 的 2D 晶格数据
- 使用GDI 从ADB Framebuffer绘制数据
- 如何从文本中绘制这些数据
- 有没有办法将 EGL 绘制到 /dev/fb1 而不是 /dev/fb0,而无需在树莓派上复制数据
- 使用 Python 的 Matplotlib 绘制C++程序中生成的数据
- DirectX:从结构数组绘制多维数据集
- 使用gnuplot动态绘制易失性数据文件
- 通过统一缓冲区对象发送到 GLSL 的数据会泄漏到其他绘制调用中 (OpenGL 3.2)
- 用于绘制 QVector3D 数据的工具
- 在 qt 中绘制 dicom 原始数据
- 用 C++ 或 C 绘制图形数据
- C++ Qwt - 从矢量绘制数据
- 在QCustomPlot中,如何实时绘制相同数据的折线图和条形图
- 如何在Qt中绘制数据流图
- opengl =中缓冲区数据的问题仅在我缓冲比需要更多的字节时绘制
- 使用OpenGL在c++中绘制带有大量数据点的散点图的最佳方法
- 如何将framebuffer对象中的屏幕外数据绘制到QGLWidget
- 绘制财务数据