2010-12-08 2 views
7

일부 시스템 성능 데이터를 측정하여 데이터베이스에 저장합니다. 이러한 데이터 포인트에서 시간 경과에 따라 선 그래프를 그립니다. 본질적으로 이러한 데이터 포인트는 약간 시끄 럽습니다. 모든 단일 지점은 지역 평균값에서 적어도 약간 벗어납니다. 선 그래프를 한 점에서 다음 점으로 직선으로 그릴 때 톱니 모양의 그래프가 생성됩니다. 한 픽셀 당 10 개 이상의 데이터 포인트와 같은 큰 시간 규모에서이 노이즈는 작은 스케일처럼 1px 대신 20px라는 넓은 들쭉날쭉 한 라인 영역으로 압축됩니다.어떻게 평활화/둥근 곡선 그래프를 그릴 수 있습니까? (C#)

나는 라인 다듬기, 앤티 앨리어싱, 단순화 및이 모든 것들에 대해 읽었습니다. 그러나 내가 찾은 모든 것은 다른 것에 관한 것 같습니다.

앤티 앨리어싱이 필요하지 않습니다. .NET에서 화면에 선을 그릴 때 이미 .NET에서 해당 작업을 수행합니다.

단순화를 원하지 않습니다. 최소한 극단적 인 가치가 남아 있어야합니다.

스플라인 곡선의 방향으로가는 것 같지만 설명 된 것이 내가 원하는 것인지를 평가하기 위해 예제 이미지를 많이 찾을 수 없습니다. 나는 Google 도서에서 매우 과학적인 책을 찾았는데, 반 페이지 길이의 수식들로 가득 찼습니다. 지금은 독서가 마음에 들지 않았습니다 ...

예를 들어, Linux/Gnome의 시스템 모니터를 살펴보십시오. 신청. 필자는 최근 CPU/메모리/네트워크 사용량을 매끄러운 선으로 그립니다. 이것은 약간 단순화 될 수 있지만, 시도해보고 그것을 조정할 수 있는지 확인합니다.

나는 C# 코드를 선호하지만 다른 언어로 된 코드 나 코드는 외부 참조가없는 C#으로 포팅 할 수 있으면 좋습니다.

+0

Windows (및 .net)에 성능 카운터 시스템이 내장되어 있습니다. 나는 단지 당신이 바퀴를 재발 명하지 않고 있는지 확인하고 싶다. –

+0

내 데이터는 Linux 서버에서 수집되며 다른 코드가있는 수많은 소스로 구성되어 있습니다. 데이터는 데스크탑 (대화식) 또는 웹 응용 프로그램에서 사용하기 위해 시각화되거나 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)

하지만 초기 구글 검색을 잔뜩 설정 : 여기에 스플라인을 설명하는 링크입니다.

죄송합니다. 코드를 입력하지 마세요. 용어를 잘 아는 것이 도움이 될 것입니다. 밥

0

당신이 그들을 표시하기 전에 MIN/MAX/AVG를 사용하여 데이터 포인트의 수를 줄이십시오. 더 멋지게 보이고 더 빠를 것입니다.

2

그래픽 코드에서이를 수정할 수 없습니다. 데이터에 잡음이 많은 경우 어떤 종류의 라인 평활화 알고리즘을 사용하든 상관없이 그래프는 시끄 럽습니다. 먼저 데이터를 필터링해야합니다. 원래 데이터에서 보간 된 점으로 두 번째 데이터 세트를 만듭니다. 최소 사각형 맞춤은 일반적인 기술입니다. 평균화는 구현이 간단하지만 극단을 숨기는 경향이 있습니다.

0

네트워크 트래픽 그래프는 가중 평균을 사용하는 경우가 많습니다. 초당 1 회 샘플을 길이 10의 순환리스트로 만들 수 있으며 그래프의 경우 각 샘플에서 샘플의 평균을 그래프로 나타낼 수 있습니다.

10이 충분하지 않으면 더 많은 것을 저장할 수 있습니다. 당신은 그러나, 모두 10 저장하지 않으려면

new_average = (old_average*10 - replaced_sample + new_sample)/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++ 

은 초기 램프 업 (ramp-up)을 피하기 위해. 타이머가 정확히 초당 1 번 발사되지 않으므로 각 샘플의 시간을 실제로 반영하도록 9/10, 1/10 비율을 조정해야합니다.