簡體   English   中英

如何繪制平滑/圓角/曲線圖? (C#)

[英]How can I draw smoothed/rounded/curved line graphs? (C#)

我正在測量一些系統性能數據以將其存儲在數據庫中。 從這些數據點我隨着時間的推移繪制線圖。 就其性質而言,這些數據點有點嘈雜,即。 每個點都偏離本地平均值至少一點。 當直線繪制線圖從一個點到下一個點時,它會產生鋸齒狀圖形。 在每個像素大於10個數據點的大時間范圍內,這種噪聲被壓縮成寬的鋸齒狀線區域,例如,20px高而不是1px,如在較小的比例中。

我已經閱讀過有關線條平滑,抗鋸齒,簡化以及所有這些內容的內容。 但我發現的一切似乎都與其他東西有關。

我不需要抗鋸齒,.NET在屏幕上繪制線條時已經為我做了這個。

我不想簡化。 我需要極端值才能保持可見,至少大部分都是如此。

我認為它是在樣條曲線的方向,但我找不到很多示例圖像來評估所描述的東西是否是我想要的。 我確實在谷歌圖書上找到了一本高度科學的書,里面裝滿了半頁長的公式,我現在還不喜歡這本書......

舉個例子,看看Linux / Gnome的系統監視器應用程序。 我使用平滑的線條繪制最近的CPU /內存/網絡使用情況。 這可能有點過於簡單,但我會試一試,看看我是否可以調整它。

我更喜歡C#代碼,但其他語言的算法或代碼也很好,只要我可以在沒有外部引用的情況下將其移植到C#。

您可以進行一些數據平滑。 而不是使用真實數據,應用一個簡單的平滑算法,使峰值像Savitzky-Golayfilter一樣。

你可以在這里得到系數

最容易做的是:

從我鏈接到的網站獲取頂部系數:

// 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 =點數越大,數據越平滑。 但是你也放松了峰值准確度,但是在簡單地將一些點平均在一起時並沒有那么多。

您無法在圖形代碼中修復此問題。 如果您的數據有噪音,那么無論您使用何種線路平滑算法,圖表都會產生噪音。 您需要先過濾數據。 使用從原始數據插值的點創建第二個數據集。 最小二乘擬合是一種常見技術。 平均化很容易實現,但往往隱藏極端。

我認為你所尋找的是提供“樣條”的常規。 這是一個描述樣條線的鏈接:

http://en.wikipedia.org/wiki/Spline_(mathematics)

如果是這種情況我沒有任何關於樣條庫的建議,但最初的谷歌搜索出現了一堆。

很抱歉沒有代碼,但希望知道這些術語可以幫助您進行搜索。

短發

在顯示之前使用MIN / MAX / AVG減少數據點的數量。 它看起來更好,而且會更快

網絡流量圖通常使用加權平均值。 您可以每秒一次采樣到長度為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的比例實際上反映每個樣本的時間preiod因為你的計時器就不會觸發每秒一次

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM