我正在测量一些系统性能数据以将其存储在数据库中。从这些数据点我随着时间的推移绘制线图。就其性质而言,这些数据点有点嘈杂,即。每个点都偏离本地平均值至少一点。当直线绘制线图从一个点到下一个点时,它会产生锯齿状图形。在很大的时间范围内,例如>每个像素10个数据点,这个噪声被压缩成一个宽的锯齿状线区域,比如20px高而不是1px,就像较小的比例一样。
我已经阅读过有关线条平滑,抗锯齿,简化以及所有这些内容的内容。但我发现的一切似乎都与其他事情有关。
我不需要消除锯齿功能,.NET在屏幕上绘制线条时已经为我做了这一点。
我不想简化。我需要极端值才能保持可见,至少大部分都是如此。
我认为它是在样条曲线的方向,但我找不到很多示例图像来评估所描述的东西是否是我想要的。我确实在谷歌图书上找到了一本高度科学的书,里面装满了半页长的公式,我现在不喜欢看完......
举个例子,看看Linux / Gnome的系统监视器应用程序。我使用平滑的线条绘制最近的CPU /内存/网络使用情况。这可能有点过于简单了,但我会试一试,看看我是否可以调整它。
我更喜欢C#代码,但其他语言的算法或代码也很好,只要我可以在没有外部引用的情况下将其移植到C#。
答案 0 :(得分:6)
您可以进行一些数据平滑。而不是使用真实数据,应用一个简单的平滑算法,使峰值像Savitzky-Golayfilter一样。
You can get the coefficients here
最容易做的是:
从我链接的网站获取顶级系数:
// For np = 5 = 5 data points
var h = 35.0;
var coeff = new float[] { 17, 12, -3 }; // coefficients from the site
var easyCoeff = new float[] {-3, 12, 17, 12, -3}; // Its symmetrical
var center = 2; // = the center of the easyCoeff array
//现在,对于数据中的每个点,您都可以计算出平滑点:
smoothed[x] =
((data[x - 2] * easyCoeff[center - 2]) +
(data[x - 1] * easyCoeff[center - 1]) +
(data[x - 0] * easyCoeff[center - 0]) +
(data[x + 1] * easyCoeff[center + 1]) +
(data[x + 2] * easyCoeff[center + 2])) / h;
当使用5分时,前2点和后2点你需要平滑。
如果您希望数据更加“平滑”,您可以尝试使用更大数据点的系数。
现在,您可以通过“平滑”数据绘制一条线。 np =点数越大,数据越平滑。但是你也放松了峰值准确度,但是在简单地将一些点平均在一起时并没有那么多。
答案 1 :(得分:2)
您无法在图形代码中修复此问题。如果您的数据有噪音,那么无论您使用何种线路平滑算法,图表都会产生噪音。您需要先过滤数据。使用从原始数据插值的点创建第二个数据集。最小二乘拟合是一种常见技术。平均化很容易实现,但往往隐藏极端。
答案 2 :(得分:1)
我认为您所寻找的是提供“样条”的常规。这是一个描述样条线的链接:
http://en.wikipedia.org/wiki/Spline_(mathematics)
如果是这种情况,我对样条库没有任何建议,但最初的谷歌搜索出现了一堆。
很抱歉没有代码,但希望知道这些术语可以帮助您进行搜索。
鲍勃
答案 3 :(得分:0)
在显示之前使用MIN / MAX / AVG减少数据点的数量。它会看起来更好,而且会更快
答案 4 :(得分:0)
网络流量图通常使用加权平均值。您可以每秒一次采样到长度为10的圆形列表中,对于图形,在每个样本中,绘制样本的平均值。
如果10还不够,你可以存储更多。您无需从头开始重新计算平均值:
new_average = (old_average*10 - replaced_sample + new_sample)/10
但是,如果您不想存储所有10个,则可以使用此方法进行近似:
new_average = old_average*9/10 + new_sample/10
许多路由器使用它来节省存储空间。这会以指数方式向当前的流量速率倾斜。
如果您确实实现了这一点,请执行以下操作:
new_average = old_average*min(9,number_of_samples)/10 + new_sample/10
number_of_samples++
避免最初的提升。您还应该调整9 / 10,1 / 10比率以实际反映每个样本的时间周期,因为您的计时器不会每秒完全一次。