如何在所有缩放级别实时准确地绘制大数据向量?

发布于 2024-07-13 01:53:24 字数 334 浏览 10 评论 0原文

我有大量数据集(10 Hz 数据,因此每 24 小时 864k 个点),我需要实时绘制它们。 这个想法是用户可以缩放和平移到高度详细的散点图。

数据不是很连续并且存在尖峰。 由于数据集太大,我无法在每次绘图刷新时绘制每个点。

但我也不能只绘制每个第 n 个点,否则我会错过主要特征,例如大而短的尖峰。

Matlab 做得对。 您可以给它一个充满零的 864k 矢量,只需将任意一个点设置为 1,它就会通过缩放和平移实时正确绘制。

Matlab是如何做到的呢?

我的目标系统是 Java,因此我将在 Swing/Java2D 中生成该图的视图。

I have large data sets (10 Hz data, so 864k points per 24 Hours) which I need to plot in real time. The idea is the user can zoom and pan into highly detailed scatter plots.

The data is not very continuous and there are spikes. Since the data set is so large, I can't plot every point each time the plot refreshes.

But I also can't just plot every nth point or else I will miss major features like large but short spikes.

Matlab does it right. You can give it a 864k vector full of zeros and just set any one point to 1 and it will plot correctly in real-time with zooms and pans.

How does Matlab do it?

My target system is Java, so I would be generating views of this plot in Swing/Java2D.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

草莓酥 2024-07-20 01:53:24

您应该尝试 MATLAB Central 中的文件:

https://mathworks.com/matlabcentral /fileexchange/15850-dsplot-downsampled-plot

来自作者:

此版本的“绘图”将允许您可视化具有大量元素的数据。 绘制大型数据集会使图形变得缓慢,但大多数时候您不需要图中显示的所有信息。 您的屏幕只有这么多像素,您的眼睛将无法检测到屏幕上未捕获的任何信息。

此函数将对数据进行下采样并仅绘制数据的子集,从而提高内存要求。 当绘图放大时,会显示更多信息。 我们做了一些工作来确保捕获异常值。

语法:

dsplot(x, y)  
dsplot(y)  
dsplot(x, y, numpoints)  

示例:

x =linspace(0, 2*pi, 1000000);  
y1=sin(x)+.02*cos(200*x)+0.001*sin(2000*x)+0.0001*cos(20000*x);  
dsplot(x,y1);

You should try the file from MATLAB Central:

https://mathworks.com/matlabcentral/fileexchange/15850-dsplot-downsampled-plot

From the author:

This version of "plot" will allow you to visualize data that has very large number of elements. Plotting large data set makes your graphics sluggish, but most times you don't need all of the information displayed in the plot. Your screen only has so many pixels, and your eyes won't be able to detect any information not captured on the screen.

This function will downsample the data and plot only a subset of the data, thus improving the memory requirement. When the plot is zoomed in, more information gets displayed. Some work is done to make sure that outliers are captured.

Syntax:

dsplot(x, y)  
dsplot(y)  
dsplot(x, y, numpoints)  

Example:

x =linspace(0, 2*pi, 1000000);  
y1=sin(x)+.02*cos(200*x)+0.001*sin(2000*x)+0.0001*cos(20000*x);  
dsplot(x,y1);
辞别 2024-07-20 01:53:24

我不知道Matlab是如何做到的,但我会从四叉树开始。

将所有数据点转储到四叉树中,然后以给定的缩放级别进行渲染,您沿着四叉树走下去(从与您正在查看的内容重叠的区域开始),直到到达与像素大小相当的区域。 在该区域的中间粘贴一个像素。

补充:使用 OpenGL/JOGL 进行绘图也将帮助您更快地绘图。 特别是如果您可以预测平移,并建立要在显示列表或其他内容中显示的点,这样您就不必为新帧执行任何 CPU 工作。

I don't know how Matlab does it, but I'd start with Quadtrees.

Dump all your data points into the quadtree, then to render at a given zoom level, you walk down the quadtree (starting with the areas that overlap what you're viewing) until you reach areas which are comparable to the size of a pixel. Stick a pixel in the middle of that area.

added: Doing your drawing with OpenGL/JOGL will also help you get faster drawing. Especially if you can predict panning, and build up the points to show in a display list or something, so that you don't have to do any CPU work for the new frames.

街道布景 2024-07-20 01:53:24

10Hz 数据意味着您每秒只需绘制 10 帧。 这应该很容易,因为许多游戏都可以通过更复杂的图形达到 100 fps 以上。

如果您每秒为每个可能的数据点绘制 10 个像素,则可以使用 600 像素宽的小部件显示一分钟的数据。 如果保存倒数第 600 个样本的索引,则应该很容易仅绘制最新数据。

如果您没有每十分之一秒就有一个新数据点,您就必须想出一种方法来插入插值数据点。 我想到了三个选择:

  1. 重复最后一个数据点。
  2. 插入一个“空”数据点。 这将导致图表中出现间隙。
  3. 在下一个数据点到达之前不要更新图表。 然后插入所有未立即绘制的像素,并在数据点之间进行线性插值。

要使动画流畅,请使用双缓冲。 如果您的目标语言支持画布小部件,它可能支持双缓冲。

缩放时,您具有与上述相同的三个选择,因为即使原始数据点连续,缩放后的数据点也不连续。

可能有助于在 Java 中实现它。

10Hz data means that you only have to plot 10 frames per second. It should be easy, since many games achieve >100 fps with much more complex graphics.

If you plot 10 pixels per second for each possible data point you can display a minute worth of data using a 600 pixel wide widget. If you save the index of the 600th to last sample it should be easy to draw only the latest data.

If you don't have a new data-point every 10th of a second you have to come up with a way to insert an interpolated data-point. Three choices come to mind:

  1. Repeat the last data-point.
  2. Insert an "empty" data-point. This will cause gaps in the graph.
  3. Don't update the graph until the next data-point arrives. Then insert all the pixels you didn't draw at once, with linear interpolation between the data-points.

To make the animation smooth use double-buffering. If your target language supports a canvas widget it probably supports double-buffering.

When zooming you have the same three choices as above, as the zoomed data-points are not continuous even if the original data-points were.

This might help for implementing it in Java.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文