2010-12-08 14 views
7

私はいくつかのシステムパフォーマンスデータを測定してデータベースに保存しています。これらのデータポイントから、私は時間の経過とともに線グラフを描いています。その性質上、これらのデータ点は少し騒々しいです。全ての単一点は、局所平均値から少なくとも少しずれている。折れ線グラフをあるポイントから次のポイントにまっすぐに描画すると、ギザギザのグラフが生成されます。 1ピクセルあたり> 10データポイントのような大きな時間スケールでは、このノイズは、小規模の場合と同じように1pxの代わりに、例えば20pxの高さの広いギザギザのライン領域に圧縮されます。スムージング/ラウンド/曲線グラフを描画するにはどうすればよいですか? (C#)

私は、ラインスムージング、アンチエイリアス、シンプル化、これらのすべてについて読んだことがあります。しかし、私が見つけたものは、何か他のもののようです。

アンチエイリアスは必要ありませんが、.NETはすでに画面上に線を描画するときにそれを行います。

私は単純化したくありません。私は極端な値が目に見えるようにする必要があります。

私はスプライン曲線の方向に向いていると思いますが、説明したものが私が望むものかどうかを評価するためのサンプル画像はあまり見つかりませんでした。私はGoogle Booksで非常に科学的な本を見つけましたが、半ページ長い数式がありましたが、今読んでいないのです...

Linux/Gnomeのシステムモニタを見てみましょう応用。私は最近のCPU /メモリ/ネットワークの使用量を滑らかな線で描きます。これは少し単純すぎるかもしれませんが、私はそれを試してみて、それを微調整できるかどうかを見ていきます。

私はC#コードが好きですが、他の言語のアルゴリズムやコードも、外部参照なしでC#に移植できる限り、問題ありません。

+0

Windows(および.net)にはパフォーマンスカウンタが組み込まれていますか?私はちょうどあなたが車輪を再発明していないことを確認したい(彼らが必ずあなたのケースに当てはまると言っているわけではない)。 –

+0

私のデータはLinuxサーバー上で収集され、他のコードを持っている多数の異なるソースから構成されています。データは、デスクトップ(インタラクティブ)アプリケーションまたはWebアプリケーション、またはMonoランタイムの下での電子メールによるレポートで使用するために可視化されます。開発はWindows上のVisual Studioで行います。 – ygoe

答えて

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; 

最初の2ポイントと最後の2ポイントは、5ポイントを使用すると滑らかになります。

データをよりスムーズにしたい場合は、より大きなデータポイントを持つ係数を試すことができます。

"平滑化"されたデータを使って線を描くことができます。あなたのnp =ポイント数が大きいほど、データはスムーズになります。しかし、あなたはまたピーク精度を失いますが、単純にいくつかの点を平均化するとそれほど多くはありません。

+1

私は今これの変形を実装しました。最初に、元のソースデータポイントをピクセルあたり〜3個の値に平均化しています。これにより、数秒から数分までのさまざまな解像度で数か月のデータをレンダリングすると、より均一なデータ密度が得られます。次に、他のサイトで見つかる最大の係数リストを使ってそれらの値を実行します。それは実際にグラフ内でより滑らかな線を生成します。しかし、非常に小さくて極端なピークは、グラフに面白い効果をもたらします。それは極端な曲線のまわりの他の方向に大きく振動する。私はそれが負の係数から来ていると思います。 – ygoe

1

私はあなたが探しているものは、 'スプライン'を提供するルーチンだと思います。ここではスプラインを記述したリンクです:

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

それは私がスプラインライブラリのための推奨事項はありませんが、最初のGoogle検索が大勢を上げた場合であれば。

申し訳ありませんが、コードはありませんが、この用語がわかっていれば、検索に役立ちます。ボブ

0

は、あなたがそれらを表示する前にMIN/MAX/AVGを使用して、データポイントの数を減らします。それはよりよく見え、より速くなります

2

これはグラフィックスコードでは修正できません。あなたのデータがノイズの多い場合は、どのような種類の線平滑化アルゴリズムを使用していても、グラフはノイズが多いようになります。まず、データをフィルタリングする必要があります。元のデータから補間された点を持つ第2のデータセットを作成します。最小2乗適合は一般的な手法です。平均化は実装が簡単ですが、極端なものを隠す傾向があります。

0

ネットワークトラフィックのグラフは、しばしば加重平均を使用します。 1秒間に1回、長さ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++ 

を。また、タイマーが正確に秒に1回発射されないため、実際に各サンプルの時間を反映するように9/10、1/10の比率を調整する必要があります。

関連する問題