プログラミング
Show HN: XY – 高速で composable、GPUアクセラレーテッドなPythonグラフ描画ライブラリ
Show HN: XY – Fast, composable, GPU-accelerated Python charting library (github.com)
要約
XYは、Web、ノートブック、静的エクスポート向けの、非常に高速でインタラクティブ、カスタマイズ可能なPythonグラフ描画ライブラリです。数百万から数億点のデータセットを効率的に処理でき、GPUアクセラレーションとRustコアにより、大規模データでも高速な描画とインタラクションを実現します。Matplotlibとの互換性もあり、Python、CSS、Tailwindによる高度なカスタマイズが可能です。
全文翻訳
XYは、Web、ノートブック、静的エクスポート向けの、非常に高速でインタラクティブ、カスタマイズ可能なPythonグラフ描画ライブラリです。グラフは宣言的に、またはmatplotlibの慣習に従って構成できます。Python、CSS、またはTailwindを使用して完全にカスタマイズできます。小さなグラフでは、すべての点がブラウザに送信されます。大きなグラフでは、Rustコアは画面が必要とするものだけを、その解像度に基づいて計算します。パン、ズーム、ホバー、選択は、新しい範囲に対して同じプロセスを実行することで完全な詳細を表示でき、選択は元の行を返します。XYを使用して、OpenStreetMap全体、つまり100億点のデータセットをレンダリングしました。例を見る → 重要XYはアルファ版であり、頻繁に機能強化が行われています。進捗を追跡するには、リポジトリにスターを付けてください。XYは私に適していますか?XYは、日常的なプロットからカスタムアプリケーションのビジュアル、大規模データセットまで、あらゆるものに対応できる柔軟なグラフ描画ライブラリを求めるPythonユーザー向けです。一度グラフを作成すれば、ノートブックやWebアプリで使用したり、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を使用して、マーク、軸、インタラクション、レイアウトからグラフを制御します。マーク: 色、サイズ、不透明度、シンボル、グラデーション、ストローク、曲線、カラーマップを制御します。ガイド: 軸、ティック、グリッド、注釈、凡例、カラーバー、ツールチップをカスタマイズします。インタラクション: パン、ズーム、ホバー、選択、クロスヘア、コールバック、リンクされたグラフを追加します。レイアウト: レイヤーとファセットを作成し、レスポンシブな寸法を設定し、テーマを適用します。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億点のライブインタラクティブグラフ。すべてのライブラリはすべての行を取得し、実際のブラウザで独自の入力パスを介して駆動されます。時計が停止するのは、キャンバスが正しい(配置されたセンチネルポイントが検証され点灯した)かつ安定している(10バイト同一フレーム)場合のみです。そのため、プログレッシブレンダラーは最後のチャンクが着地するまで課金されます。XYは、1万点で0.071秒、1億点で0.081秒を記録し、4桁のオーダーでフラットです。これは、20万行を超えると、1行あたりのマーカーではなく、画面にバウンドされた密度サーフェスを描画し、ズームすると正確な行に戻るためです。各正確マーカーパスはNに比例してスケールします。Matplotlibは〜300万点で1秒を超え、5000万点で13.4秒に達します。Plotlyは〜250万点で1秒を超え、2500万点で9.8秒に達します。淡い線は密度=FalseのXYです。これは、1行あたりのマーカーを描画する同じエンジンで、集計クレジットはありません。1.34秒で1億点の正確マーカーを5.26 GiBでレンダリングします。すべての点が画面に表示されるまでの時間(秒)。✕はライブラリがレンダリングしなかったサイズです。Plotlyは5000万点で図の構築を完了できず、Matplotlibは1億点で描画しますが、それに続くズームを解決できません。点数10k 100k 500k 1M 2.5M 5M 10M 25M 50M 100M XYスピードアップ1× 2× 3× 4× 9× 16× 34× 89× 177× — 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アドバンテージ1.8× 1.7× 1.9× 2.1× 2.1× 2.4× 2.6× 2.9× 2.8× — 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 ✕ ✕ 1台のマシン(Apple M5 Pro)、1回の実行ごとに1つのセル。小さい方では、タイミングは実行ごとに約±10ミリ秒のばらつきがあります。環境、方法論、サイズごとのビデオ、および生の Загрузка結果については、ベンチマーク実行ブックおよび競合ベンチマーク仕様を参照してください。ReflexアプリにXYを埋め込むreflex-xyアダプターは、任意のXYグラフを通常のReflexコンポーネントに変換します。JavaScript、iframe、または個別のグラフサービスは不要です。独自のパッケージとして出荷され、xyと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個のプロットされた星Open notebook gnomAD v4.1 · 対立頻度164,000個のプロットされたバリアントOpen notebook Pan-UKBB · マンハッタンプロット814,294個のプロットされたバリアントOpen notebook Dukascopy · EUR/USDティック101,427個のプロットされたティックOpen notebook LIGO · GW150914ひずみ16,777,216個の生データ · 3,441個を表示Open notebook NYC TLC · タクシーピックアップ密度300,000個のピックアップレコードOpen notebook仕組みほとんどのグラフスタックは、すべての値をJSONにシリアル化し、ブラウザにすべてのマークを描画するように要求します。XYは、正確な値をColumnStoreに保持し、Rustで詳細レベルを計算し、型付きバイナリバッファを転送します。デシメートされたビューと密度ビューは、表示される結果によってバウンドされます。flowchart TB API["Python API<br/>グラフを作成"] STORE["ColumnStore<br/>正規のf64列を保持"] CORE["ネイティブRust計算<br/>直接 · デシメート · 密度"] PAYLOAD["コンパクトペイロード<br/>データレスJSON仕様 + 型付きバイナリバッファ"] RENDER["ブラウザまたはノートブック<br/>WebGL2マーク · Canvas軸 · DOMインターフェース"] API --> STORE --> CORE --> PAYLOAD --> RENDER ロード中したがって、密な概要は集計できますが、狭いビューは正確なポイントを返します。ライブホストを使用すると、パンとズームは洗練されたペイロードを要求します。正規のf64データはPythonに残るため、ホバーと選択は依然として元の行を返します。完全な設計については、設計ドシエを参照してください。ロードマップまず広範な2Dカバレッジ、次に地理、3D、ボリュームビジュアライゼーション。次にキューに入っていますが、日付は示されていません。Cate