删除线图的冗余点
我正在尝试使用一些库来绘制大量点。这些点按时间排序,并且它们的值可以被认为是不可预测的。
我目前的问题是,点的数量过多使库需要很长时间才能渲染。许多点是多余的(也就是说,它们位于由函数 y = ax + b 定义的同一条线上)。有没有办法检测并删除冗余点以加快渲染速度?
谢谢您的宝贵时间。
I am trying to plot large amounts of points using some library. The points are ordered by time and their values can be considered unpredictable.
My problem at the moment is that the sheer number of points makes the library take too long to render. Many of the points are redundant (that is - they are "on" the same line as defined by a function y = ax + b). Is there a way to detect and remove redundant points in order to speed rendering ?
Thank you for your time.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
以下是 Ramer-Douglas-Peucker< 的变体/a> 1.5d 图的算法:
在 python 中,这可能是
输出为
[(0, 0), (30, 30), (50, 0)]
。关于可能不明显的数组的 python 语法:
x[a:b]
是数组从索引a
到索引b
的部分(不包括)x[n:]
是使用x
的元素组成的数组,从索引n
到末尾x[:n 使用
x
a+b
的前n
个元素组成的数组a
和 < 时 code>b 是数组,表示串联x[-1]
是数组的最后一个元素 在具有 100,000 个点且 < 值不断增加的图上运行此实现的结果示例code>eps 可以在此处查看。
The following is a variation on the Ramer-Douglas-Peucker algorithm for 1.5d graphs:
In python this could be
The output is
[(0, 0), (30, 30), (50, 0)]
.About python syntax for arrays that may be non obvious:
x[a:b]
is the part of array from indexa
up to indexb
(excluded)x[n:]
is the array made using elements ofx
from indexn
to the endx[:n]
is the array made using firstn
elements ofx
a+b
whena
andb
are arrays means concatenationx[-1]
is the last element of an arrayAn example of the results of running this implementation on a graph with 100,000 points with increasing values of
eps
can be seen here.在我有了这个想法之后,我遇到了这个问题。跳过绘图上的冗余点。我相信我想出了一个更好、更简单的解决方案,并且我很高兴将其作为我提出的第一个解决方案进行分享。我已经对其进行了编码,并且它对我来说效果很好。它还考虑了屏幕比例。这些绘图点之间的值可能有 100 个点,但如果用户的图表尺寸较小,他们将看不到它们。
因此,迭代数据/绘图循环,在绘制/添加下一个数据点之前,查看前面的下一个值并计算屏幕比例(或值,但我认为出于上述原因的屏幕比例更好) )。现在对前面的下一个值执行相同的操作(获取这些值只是在数组/集合/列表/等中提前查看,将 for 下一步增量(可能是 1/2)添加到循环中的当前 for 值中)。如果这两个值相同(或者根据您自己的喜好可能有很小的变化),您可以通过简单地在循环中添加“继续”来跳过图表中的这一点,跳过添加数据点,因为该点恰好位于其前后点之间的斜率。
例如,使用这种方法,我将图表从 963 个点减少到 427 个点,视觉变化绝对为零。
我认为您可能需要阅读几次才能理解,但它比这里提到的其他最佳解决方案简单得多,重量轻得多,并且对您的情节的视觉效果为零。
I came across this question after I had this very idea. Skip redundant points on plots. I believe I came up with a far better and simpler solution and I'm happy to share as my first proposed solution on SO. I've coded it and it works well for me. It also takes into account the screen scale. There may be 100 points in value between those plot points, but if the user has a chart sized small, they won't see them.
So, iterating through your data/plot loop, before you draw/add your next data point, look at the next value ahead and calculate the change in screen scale (or value, but I think screen scale for the above-mentioned reason is better). Now do the same for the next value ahead (getting these values is just a matter of peeking ahead in your array/collection/list/etc adding the for next step increment (probably 1/2) to the current for value whilst in the loop). If the 2 values are the same (or perhaps very minor change, per your own preference), you can skip this one point in your chart by simply adding 'continue' in the loop, skipping adding the data point as the point lies exactly on the slope between the point before and after it.
Using this method, I reduce a chart from 963 points to 427 for example, with absolutely zero visual change.
I think you might need to perhaps read this a couple of times to understand, but it's far simpler than the other best solution mentioned here, much lighter weight, and has zero visual effect on your plot.
我可能会应用“最小二乘”算法来获得最佳拟合线。然后,您可以遍历您的点并向下过滤靠近该线的连续点。您只需绘制离群值以及使曲线回到最佳拟合线的点。
编辑:您可能不需要使用“最小二乘法”;如果您的输入预计会像您所说的那样徘徊在“y=ax+b”附近,那么这已经是您的最佳拟合线,您可以使用它。 :)
I would probably apply a "least squares" algorithm to obtain a line of best fit. You can then go through your points and downfilter consecutive points that lie close to the line. You only need to plot the outliers, and the points that take the curve back to the line of best fit.
Edit: You may not need to employ "least squares"; if your input is expected to hover around "y=ax+b" as you say, then that's already your line of best fit and you can just use that. :)