기술 제원 및 공개 범위

웹 브라우저와 주피터 노트북, 정적 파일 내보내기를 지원하는 파이썬 시각화 라이브러리 XY가 알파 버전으로 공개됐다. HTML, PNG, SVG, PDF 형식의 내보내기를 지원하며, 차트 구성은 선언적 방식이나 기존 matplotlib의 관례를 따르는 방식으로 수행한다. 스타일링은 파이썬 코드뿐 아니라 CSS와 Tailwind CSS를 통해 세부 제어가 가능하다.

기존 pyplot 워크플로우와의 호환성을 위해 임포트 문만 변경하면 기존 플로팅 코드를 그대로 사용할 수 있도록 설계됐다. 다만 모든 차트 유형과 기능이 아직 지원되는 것은 아니며, 상세 내용은 공식 호환성 가이드(Compatibility Guide)를 통해 확인할 수 있다. 현재는 2D 커버리지를 우선적으로 제공하며, 향후 지리 정보(Geographic), 3D, 볼륨 시각화 기능을 추가할 계획이다.

데이터 처리 구조 및 벤치마크

데이터 전송 효율을 높이기 위해 XY는 일반적인 차트 스택이 사용하는 JSON 직렬화 방식을 버리고 ColumnStore에 정확한 값을 유지하며 Rust 코어에서 계산된 타입 지정 바이너리 버퍼(Typed Binary Buffers)를 전송한다. 렌더링 부하를 줄이는 핵심은 데이터 크기에 따른 가변적 처리 방식에 있다. 20만 행 미만의 소규모 차트는 모든 포인트를 브라우저로 전송하지만, 20만 행을 초과하면 화면 해상도에 기반해 필요한 정보만 계산하는 밀도 표면(Density Surface) 방식으로 전환한다. 사용자가 줌(Zoom) 기능을 통해 범위를 좁히면 해당 구간에 대해 다시 정밀한 페이로드를 요청해 정확한 행 데이터를 표시한다.

Apple M5 Pro 환경에서 진행된 벤치마크 결과, XY는 데이터 포인트 1만 개일 때 0.071초, 1억 개일 때 0.081초의 렌더링 시간을 기록했다. 이는 데이터 규모가 4자릿수 배 증가해도 렌더링 시간이 거의 일정하게 유지됨을 보여준다. 반면 모든 마커를 개별적으로 그리는 방식(`density=False`)으로 1억 개의 포인트를 렌더링했을 때는 1.34초가 소요됐으며, 이때 파이썬 측의 피크 메모리 점유율은 5.26 GiB였다.

타 라이브러리와의 비교에서는 데이터 규모가 커질수록 격차가 벌어졌다. Matplotlib은 약 300만 포인트에서 렌더링 시간이 1초를 넘어섰으며, 5,000만 포인트에서는 13.4초가 소요됐다. Plotly는 5,000만 포인트 규모에서 피규어(Figure) 구성 단계에서 렌더링을 완료하지 못했다. 벤치마크 측정 기준은 캔버스가 정확하게 그려지고 10개의 바이트 동일 프레임이 안정화될 때까지의 시간을 측정했다.

구현 방식과 실무 도입 영향

웹 애플리케이션 통합은 `reflex-xy` 어댑터를 통해 수행한다. 별도의 자바스크립트 작성이나 iframe, 외부 차트 서비스 없이 XY 차트를 일반적인 Reflex 컴포넌트로 변환해 사용할 수 있다.

bash
pip install reflex-xy

python
import reflex as rx
from reflex_xy import XYChart

class MyComponent(rx.Component):
 def render(self):
 return rx.vstack(
 XYChart(data=my_data, marks=[...])
 )

이 구조를 통해 호버, 팬, 줌 등의 인터랙티브 기능이 유지되며, Reflex 상태(State)나 라이브 스트림으로 구동되는 차트를 구현할 수 있다. 데이터의 원본 f64 값은 파이썬 쪽에 유지되므로, 브라우저에서 밀도 뷰로 요약된 화면을 보더라도 호버나 선택 시에는 원본 행 데이터를 정확히 반환한다.

실무자가 도입 시 판단해야 할 핵심은 데이터의 '정밀도'와 '응답 속도' 사이의 트레이드오프다. 20만 행 이상의 대규모 데이터셋을 다룰 때, 전체적인 분포를 빠르게 확인해야 한다면 밀도 표면 방식을 활용하고, 모든 개별 포인트의 정확한 렌더링이 필수적이라면 `density=False` 설정과 함께 5GiB 이상의 메모리 여유 공간을 확보해야 한다.