
2026/07/29 0:54
Show HN: XY – 高速でモジュール化可能で GPU 加速されたインタラクティブ描画ライブラリ
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
元のサマリーは強く、簡潔で正確です。しかし、キーポイントリストに基づいてそれを完全に包括的にするために、出力形式、具体的な統合方法(Reflex)、およびより正確なロードマップリストを含めるように強化しました。
改善されたサマリー:
XY は、Web、ノートブック、および静的エクスポート(HTML、PNG、SVG、PDF)向けの高性能な Python グラフィクリブラリです。その核心的な強みは、Rust エンジンを採用し、表示されているデータポイントのみを処理することにあります。これにより、1 万点から 1 億点以上までのスケール(および OpenStreetMap の数十億点のデータセットを成功裏にレンダリング)を数ミリ秒で処理でき、Matplotlib や Plotly などの伝統的なツールを大幅に上回ります。チャートは宣言的に定義するか、標準的な
matplotlib.pyplot 規約を用いて定義でき(Python、CSS、または Tailwind を用いた完全なカスタマイズが可能)、シンプルな pip または uv インストールにより既存のワークフローとシームレスに統合されます。XY は初期に全てのデータをロードせずにパン、ズーム、ホバーなどのインタラクティブ機能をサポートし、JavaScript も iFrame も使用せずに高忠実度の可視化を届けるために Reflex と統合されます。今後の展開として、ライブラリは Python データサイエンスとインタラクティブな Web 配信のギャップを埋めるために高度な分析ドメインへと拡大しており、今後の機能には 3D ボリューム可視化、回帰診断、カテゴリー分布(boxen、rug)などが含まれます。本文
XY:高速かつ対話型の Python チャート描画ライブラリ
XY は、ウェブ、ノートブック、そして静的エクスポート用に最適化された、極めて高速で対話可能かつカスタマイズ可能なPython チャート描画ライブラリです。
チャートの構成は宣言的に行うか、matplotlib の慣習に沿って行うことができます。Python、CSS、あるいは Tailwind を使用して完全にカスタマイズが可能です。
特徴とパフォーマンス
- 小規模データ: 小さなチャートでは、すべての点がブラウザに送信されます。
- 大規模データ: 大きなチャートの場合、Rust コアがスクリーンの解像度に基づいて表示に必要な部分のみを計算し処理します。
- パン(画面移動)、ズーム、ホバー、および選択操作により、新しい範囲に対して同一のプロセスを実行することで詳細を表示できます。
- 選択結果には元の行データが返されます。
- 超大規模データ対応: XY を使用すれば、OpenStreetMap の全データを可視化することが可能です(約 100 億点)。
重要: XY はアルファ版であり、頻繁な機能追加が行われています。⭐️ リポジトリをスターして進捗状況をご確認ください。
インストールと使用方法
XY は日常的なプロットから大規模データセットまで、あらゆる用途に対応します。一度作成したチャートは、ノートブックやウェブアプリで使用し、HTML、PNG、SVG、あるいは PDF としてエクスポートすることもできます。
インストール
pip install xy # または、uv を使用する場合 uv add xy
はじめに:基本的な描画
チャートは、その内部に含まれるマーク(描画対象)を備えたコンテナーです。シーケンスであればどのようなものでも動作し、NumPy の利用はオプションです。
import xy chart = xy.line_chart(xy.line([1, 2, 3, 4, 5], [120, 180, 165, 240, 310])) # エクスポート # chart.to_html("chart.html") # chart.to_png("chart.png") # chart.to_svg("chart.svg") # ノートブック内では自動的に描画されます chart
大規模データ:密度表面への対応
同様の API を使用することで、1 億点ものデータもスケールさせられるです(密度マップ機能):
import numpy as np import xy rng = np.random.default_rng(7) n = 100_000_000 r = 6.0 * rng.beta(1.2, 3.0, n) theta = 2.9 * np.log1p(r) + rng.integers(0, 4, n) * (np.pi / 2) + rng.normal(0, 0.045 + 0.016 * r, n) chart = xy.scatter_chart( xy.scatter( r * np.cos(theta), r * np.sin(theta), color=np.exp(-r / 2.2), colormap="magma_r", density=True, opacity=0.85, # ビューが実質的な行にズームインした際にマーカーを大きくし、不透明度を増加させます。 size=2.5, zoom_size_factor=2.6, zoom_opacity=0.95, ), xy.theme( background="#ffffff", plot_background="#ffffff", grid_color="#e6e6e1", axis_color="#c3c2b7", text_color="#0b0b0b", ), title="1 億点", ) chart
matplotlib から移行する場合
一般的な pyplot ワークフローであれば、インポート语句を変更し、描画コード自体はそのまま利用できます:
import numpy as np import xy.pyplot as plt x = np.linspace(0, 10, 200) fig, ax = plt.subplots() ax.plot(x, np.sin(x), "r--", label="signal") ax.legend() plt.show()
互換性情報については、互換性情報ガイド をご参照ください(すべてのチャートタイプや機能はまだ対応していない可能性があります)。
各レイヤーのカスタマイズ
Python を使用して、マーク(図形)や軸から対話機能、レイアウトまで制御可能です。
- マーク (Marks): カラー、サイズ、不透明度、記号、グラデーション、ストローク、カーブ、カラーマップを制御します。
- ガイド (Guides): 軸、目盛り、グリッド、注釈、凡例、カラーバー、ツールチップのカスタマイズを行います。
- 対話機能 (Interaction): パン、ズーム、ホバー、選択範囲、十字線、コールバック関数、リンクされたチャートを追加します。
- レイアウト (Layout): レイヤーとフェイスを作成し、レスポンシブなサイズを設定、テーマを適用します。
chart = xy.line_chart( xy.line(x, y, color="#7c3aed", width=3), class_name="rounded-xl bg-white", class_names={"tooltip": "rounded-lg bg-zinc-900 text-white"}, )
詳細な情報は スタイルガイド と 機能マトリックス をご参照ください。
ベンチマーク結果
ライブ対話型チャートにおける 1 万点から 1 億点までのパフォーマンスです。すべてのライブラリは各行を取得し、実際のブラウザ上で独自の入力パスを通過させています。時計が止まるのは、キャンバスが正しく描画されかつ安定している時点からです。
結論
- XY は 1 万点で 0.071 秒、1 億点で 0.081 秒という結果を出し、4 つの桁のスケールにおいて安定した性能を発揮します。
- これは、20 万行を超えた場合、各行ごとの単一マークを描画するのではなく、画面境界に束縛された密度表面を描画するためであり、ズーム操作によって詳細な行データに戻れるためです。
- 正確なマークごとの描画パスは N(データ数)と比例してスケールします:Matplotlib は約 300 万点で 1 秒を超え、5,000 万点では 13.4 秒に達します。
パフォーマンス比較 (各点が画面に表示されるまでの時間)
| ライブラリ / 条件 | 10k | 100k | 500k | 1M | 2.5M | 5M | 10M | 25M | 50M | 100M |
|---|---|---|---|---|---|---|---|---|---|---|
| XY | 0.071 | 0.072 | 0.075 | 0.084 | 0.083 | 0.089 | 0.083 | 0.077 | 0.076 | 0.081 |
| XY (density=False) | 0.085 | 0.074 | 0.087 | 0.098 | 0.111 | 0.144 | 0.206 | 0.424 | 0.645 | 1.343 |
| Matplotlib (WebAgg) | 0.086 | 0.115 | 0.224 | 0.357 | 0.758 | 1.424 | 2.804 | 6.838 | 13.385 | ✕ |
| Plotly (scattergl) | 0.341 | 0.373 | 0.477 | 0.614 | 1.033 | 1.785 | 3.367 | 9.794 | ✕ | ✕ |
メモリ消費量 (ピーク Python サイド: GiB)
(ブラウザ内のメモリは別途追跡されており、ここでは除外されています。ヘッドレス Chrome は約 1 GiB を消費)
| ライブラリ / 条件 | 10k | 100k | 500k | 1M | 2.5M | 5M | 10M | 25M | 50M | 100M |
|---|---|---|---|---|---|---|---|---|---|---|
| XY | 0.05 | 0.05 | 0.06 | 0.07 | 0.13 | 0.19 | 0.32 | 0.70 | 1.36 | 2.58 |
| XY (density=False) | 0.05 | 0.05 | 0.07 | 0.10 | 0.18 | 0.31 | 0.57 | 1.35 | 2.66 | 5.26 |
| Matplotlib (WebAgg) | 0.09 | 0.09 | 0.12 | 0.15 | 0.28 | 0.46 | 0.84 | 2.06 | 3.85 | ✕ |
| Plotly (scattergl) | 0.21 | 0.18 | 0.28 | 0.36 | 0.60 | 1.05 | 1.86 | 4.70 | ✕ | ✕ |
測定環境:Apple M5 Pro。詳細については ベンチマーク実施ガイド をご参照ください。
Reflex アプリへの埋め込み
reflex-xy アダプターは、任意の XY チャートをJavaScript や iframe、別々のチャートサービスを使わずに、通常の Reflex コンポーネントに変換します。
インストール
pip install reflex-xy # または、uv を使用する場合 uv add reflex-xy
設定と使用
アダプターを一度だけ登録してください (
rxconfig.py):
import reflex as rx import reflex_xy config = rx.Config( app_name="dashboard", plugins=[reflex_xy.XYPlugin()], )
その後、コンポーネントツリーのどこかにチャートを追加できます:
import reflex as rx import reflex_xy import xy signups = xy.line_chart( xy.line([1, 2, 3, 4, 5], [120, 180, 165, 240, 310]), title="Weekly signups", ) def index() -> rx.Component: return rx.card( rx.heading("Growth"), reflex_xy.chart(signups, height="320px"), width="100%", ) app = rx.App() app.add_page(index)
ホバー、パン、ズームも引き続き動作します。Reflex のステートやイベント、ライブストリームによって駆動されるチャートについては、Reflex インテグレーションガイド をご参照ください。
サンプル例
各ノートブックは、連結された公開ソースから行データを取得します。このリポジトリには生のデータセットは保存されていません。
- Gaia DR3 · HR 図: 可視化された 250,000 個の星 ノートブックを開く
- gnomAD v4.1 · アレル頻度: 可視化された 164,000 のバリアント ノートブックを開く
- Pan-UKBB · マンハッタンプロット: 可視化された 814,294 のバリアント ノートブックを開く
- Dukascopy · EUR/USD タイムティック: 可視化された 101,427 のティック ノートブックを開く
- LIGO · GW150914 ストレンジネス: 生データ 16,777,216 点中、可視化 3,441 点 ノートブックを開く
- NYC TLC · タクシー乗車密度: 可視化された 300,000 の乗車記録 ノートブックを開く
詳細な設定については、サンプルガイド をご参照ください。
仕組みについて
多くのチャート描画スタックは、すべての値を JSON としてシリアライズし、ブラウザにすべてのマークを描画させるように指示します。XY は正確な値を
に保持し、Rust で詳細度レベルを計算し、型付きのバイナリバッファを転送します。ColumnStore
- API: Python API / チャートの構築
- STORE: ColumnStore / 正規化された f64 カラムの保持
- CORE: ネイティブ Rust 計算 / 直接処理・減衰処理・密度処理
- PAYLOAD: コンパクトなペイロード / データのない JSON 仕様の追加、型付きバイナリバッファ
- RENDER: ブラウザまたはノートブック / WebGL2 マーク・キャンバス軸・DOM インターフェース
つまり、密な全体像では集計処理を行い、狭いビューでは正確な点を返すことができます。正規化された f64 データは Python に保持されるため、ホバーや選択操作でも元の行データを返します。詳細な設計については 設計ドossier をご参照ください。
ロードマップ
まず広範な 2D カバレッジを行い、その後地理的、3D、そしてボリューム可視化へと展開します。特定の期限は設定していません:
- カテゴリ分布: ストライプ、スウォーム、ビーゾム、ボックスエン、ルグ
- 回帰診断: テンドライン、残余、QQ プロット、PP プロット
- 散乱行列および共同プロット: SPLOM、ペアグリッド、周辺ヒストグラム
- 円グラフ / ドーナツグラフ: 現在
で利用可能で、後ほどxy.pyplot
へ昇格予定xy.pie_chart(xy.pie(...)) - ロージック/OHLC および金融オーバーレイ: SMA、VWAP、ボリンジャーバンド、RSI、MACD;プロトタイプ済み
- ウォーターフォールおよびファンネル
- 樹形図、サンバースト、イシクル
- レーダー/極座標およびゲージ: 極座標軸が必要です。
- 傾斜、バンプ、ダムベル
- 3D およびボリューム: 散乱、曲面、メッシュ、等表面、そして体積ビュー
完全なランク順のバックログについては チャートロードマップ をご参照ください。必要であれば Issue をお送りください。