(01.11) 수정됨.
matplotlib을 이용해 캔들스틱 차트를 그리고, 조회 영역 이동과 변경이 가능한 패키지를 만들었다.
누가 보더라도 개선해야할 부분 1개가 보인다. 그림을 그리는 속도다.
주가 정보의 수가 적다면 크게 문제되지는 않지만, 데이터의 수가 5,000~10,000개를 넘어가면 속도가 저하되는게 보이고, 40,000개의 데이터에서는 확연히 느리게 작동했다.
finplot은 왜 빠를까
pyqtgraph를 기반으로 만들어진 finplot은 이것과는 다르게 속도에 대한 부분은 문제없어보인다.
단지 연결 가능한 gui가 pyqt로 제한된다는 점을 단점으로 꼽을 수 있고, 조회 영역의 확대/축소를 마우스 휠을 사용해야 한다는 것이 단점일 것이다.
https://github.com/highfestiva/finplot/blob/master/finplot/__init__.py#L1228
finplot의 코드를 보면 picture라는 이름으로 그림이 그려진 widget을 생성하고, 필요한 경우 이것을 갱신하는 것으로 작업 시간을 단축하는 것으로 보인다.
또한 pyqtgraph를 잠깐이나마 만져본 느낌으로는 pyqtgraph와 matplotlib은 서로 그림을 구현하는 방식이 다르다.
어떤 느낌이냐면, pyqtgraph는 그림이 그려진 widget을 별도로 생성하고, 사용자가 이용하는 인터페이스에서는 이것을 보는 카메라를 조정하는 느낌이고, matplotlib은 카메라 == 그림이 그려진 widget이라는 느낌이 들었다.
pyqtgraph의 줌 인, 줌 아웃
pyqtgraph에서 줌 인을 하는 움짤을 한 번 보자.
pyqtgraph에서는 줌 인과 줌 아웃 작업이 매우 간단하다. 그리고 빠르다.
반면 matplotlib은 줌 인 기능이 기본 툴바에 제공되고 있지만, 느리다.
이를 그림으로 표현하자면 다음과 같이 표현할 수 있지 않을까 생각된다.
이미지 출처 : https://vispy.org/getting_started/modern-gl.html
이미지는 vispy의 문서에서 설명을 위해 제공하는 것이지만, 이것을 보고 pyqtgraph와 matplotlib이 떠올랐다.
왼쪽이 pyqtgraph, 오른쪽이 matplotlib이라는 느낌이다.
pyqtgraph는 한 번 그림을 그린 다음, 카메라의 위치만 움직이기 때문에 조회 영역만 바꾼다는 느낌이라면,
matplotlib은 카메라 앵글이 곧 그림판이기 때문에 카메라를 움직일 때마다 그림을 새로 그린다는 느낌이다.
단순히 opengl을 사용하고 있느냐, 없느냐의 차이일 수도 있지만, 저런 차이가 있다고 생각될 정도로 동작하는게 다르게 느껴진다.
https://github.com/matplotlib/matplotlib/blob/v3.10.0/lib/matplotlib/backend_bases.py#L3142
단적으로 matplotlib 기본 툴바에서 제공하는 zoom에서는 draw_idle을 사용하기 때문이다. 즉, 조회 영역에 맞춰 xlim과 ylim을 변경하고, 그림을 새로 그리고 있다.
matplotlib에서 이미지 생성한다면...?
한 가지 생각을 떠올렸는데, 차트를 그리고 조회 영역에 따라 그리는 것을 그만두는 것이다.
그 대신, 먼저 차트를 그리고 이미지로 저장한 다음, 조회 영역에 맞춰 이미지를 확대하면 속도를 개선할 수 있지 않을까 생각했다.
문제점
이 방법을 시도해보고 알게 된 2개의 문제가 있었다.
하나는 이미지를 만드는데 걸리는 시간이 굉장히 오래 걸린다는 것이었고,
다른 하나는 이미지를 만들어도 조회 영역에 따라 뭉개진 그림이 생성된다는 것이다.
이미지 확인해보기
다음은 각각 주가 데이터 100개와 8,000개로 그려진 차트를 이미지로 만든 것이다.
그리고 이것은 8,000개의 데이터로 만들어진 이미지를 확대한 것이다.
matplotlib으로 이미지를 생성하는 경우 좁은 공간에 많은 데이터가 존재하면 그림이 뭉개져서 그려진다.
내가 생각해낸 방법은 조회 범위를 좁혀 여러 장의 이미지를 생성하는 것으로 부분적으로 구현하는 것은 가능할지 몰라도, 이를 위한 사전 준비작업에 많은 시간이 소요될 것으로 예상된다.