개발2016. 7. 12. 11:11

그래프 그릴 때 엑셀이나 Matlab, OPNET 등에서는 적절한 간격과 값이 저절로 부여된다.

그런데 막상 스스로 그리려고 하니 그 값을 어떻게 만들어내는건지 방법을 금방 떠올리기 어려웠다.

뭐지 로그를 어떻게 잘 이용하나? 정도 밖에 딱히 구체적인 생각이 나지 않는다.

일단 창 크기만 가지고 일정한 간격으로 잘라 그리도록 해서 다른 테스트부터 먼저 해보고

적절한 간격을 구하는 방법에 대한 부분은 뒤로 미뤘는데 이제 다시 생각해볼 시간이 됐다.



일단 몇가지 스레드를 참고.


http://stackoverflow.com/questions/237220/tickmark-algorithm-for-a-graph-axis

http://stackoverflow.com/questions/326679/choosing-an-attractive-linear-scale-for-a-graphs-y-axis

http://stackoverflow.com/questions/361681/algorithm-for-nice-grid-line-intervals-on-a-graph


그런데 소숫점일 경우는 어떻게 처리해야할지 생각해보면 보다 효과적인 방법이 있을 것 같아서

더 찾아보니 이게 나왔다. ACM 알고리즘이라 꽤 모범적인 방법일거라고 보고 해석해본다.


http://lists.gnu.org/archive/html/octave-bug-tracker/2011-09/pdfJd5VVqNUGE.pdf




* Readability, Round-off 고려


반올림이라는 말이 적절한지 모르겠는데 확장적인 의미로 쓰이는 것 같다.

읽기 좋은 간격은 1, 2, 5, 10의 n승의 배수인게 좋다. 그리고 최소 최대값도 고려해야 한다.


좋은 간격:

-0.5, 0.0, 0.5, 1.0, ...

1.24, 1.26, 1.28, ...

100.0, 200.0, 300.0, ..., etc


안좋은 간격:

-1.0, 4.0, 9.0, ...

1.2, 1.31, 1.42, ...

0.0. 4.0, 5.0, 12.0, ..., etc


소개된 스케일 함수(scale1, scale2, scale3)를 보면 scale1은 인터벌 개수가 적절하게 바뀌고 scale2는 인터벌 개수가 주어진 대로이다. scale3은 logarithm 형태의 그래프에 사용한다.


scale1(xMin, xMax, n, xMinP, xMaxP, dist)

// xMin: 실제 최소값

// xMax: 실제 최대값

// n: 요청된 그리드 개수

// xMinP: 최소 바운드값

// xMaxP: 최대 바운드값

// dist: 간격


코드가 포트란이라서 적당히 C++ 코드로 변경해 봄.



제대로 바꾼건가...대충 값은 맞게 나오는거 같은데?


다만 이 Readability라는게 상당히 애매한 개념이라, 예를 들어 0~899 까지라면

0~1000으로 바뀌어 나오는데 난 0~900가 더 적당하다는 생각이 든다. 간격의 문제일까?

어쨌건 처음에 상당히 골치아픈 문제라고 생각했던 것에 비해

상당히 간단한 코드로 nice한 결과값이 나오긴 한다.


Dist를 구하기 위한 배열을 살짝 조정해주면 Round-off의 정도를 변경할 수도 있을 것 같고.

Posted by Maverick Unlimited