Skip to content
Dev Tools Article

Reflex's XY Wins by Not Drawing Your Data

The new Python charting library's GPU pitch hides the real trick: screen-space aggregation in Rust.

Rachel Goldstein
Rachel Goldstein
Dev Tools Editor · Jul 29, 2026 · 4 min read
Reflex's XY Wins by Not Drawing Your Data

Reflex, the YC-backed company behind the pure-Python web framework of the same name, launched a new open-source charting library today called XY, and the Show HN pitch leads with the obvious hook: fast, composable, GPU-accelerated. The demo backs it up — the team has shown it panning and zooming across OpenStreetMap's ten billion nodes with sub-second response, and Reflex's own benchmarks claim a 10-million-point chart rendered to PNG in 0.023 seconds versus 2.8 seconds for Matplotlib and 9.6 for Plotly.

Here's the thing, though: the GPU is the least interesting part of this library. The interesting part is everything XY does to avoid drawing your data at all.

The trick is refusing to render

A 4K monitor has about 8 million pixels. A scatter plot region has maybe two million. Rendering 100 million points into that space means overdrawing nearly every pixel dozens of times — wasted work no matter how fast your GPU is. Every system that's ever made big-data plotting feel instant has attacked the same insight: reduce the data to screen resolution before rendering, and the rendering problem disappears.

XY's architecture is a clean, modern expression of that idea. Data lives in a columnar store on the Python side. A Rust core computes what the screen actually needs: long line and area traces get reduced with M4 — the aggregation algorithm from a 2014 VLDB paper that keeps the min, max, first, and last value per pixel column, which is provably enough to reproduce the exact rasterized line. Dense scatter plots above roughly 200k rows switch to a fixed-size density grid plus a representative sample. Whatever survives that reduction ships to the browser as compact typed binary buffers — no JSON serialization of millions of floats — where WebGL2 draws the marks and plain Canvas and DOM handle axes and UI.

The payoff shows up in the shape of the benchmark curve, not just its height. Matplotlib and Plotly scale linearly with point count because they render everything; XY's render time stays roughly flat from 10k to 100M points because the work is bounded by your screen, not your dataset. That's also why the headline comparisons are a bit apples-to-oranges — you're comparing exact rendering against screen-space aggregation, and the honest baseline would be Datashader, which has done server-side rasterization in the HoloViz stack since 2016. But Reflex's numbers are self-reported and the fair fight hasn't been run publicly yet, so treat the specific multipliers as marketing until someone independent reproduces them.

Research idea, product packaging

None of the individual techniques here is novel, and that's a compliment. M4 aggregation is what plotly-resampler bolts onto Plotly. Screen-bounded density rendering is Datashader's whole reason for existing. The binary-transport, aggregate-in-a-fast-backend, render-in-WebGL pipeline is essentially the architecture of Mosaic, the UW Interactive Data Lab project that pushes aggregation into DuckDB. Fastplotlib covers the GPU angle for desktop with WGPU.

What none of those give you is a coherent single package. The Datashader path means assembling HoloViews, Bokeh, and Datashader and accepting the seams between them. Mosaic is brilliant and largely JavaScript-first. plotly-resampler inherits every limitation of Plotly's DOM. XY's bet is that productizing the research — one pip install, one declarative Python API, same chart object working in a notebook, exported to HTML, or mounted in a web app — is worth more than inventing anything new. Given how many teams still hand-roll df.sample(50_000) before every scatter call, that's probably right.

There's a detail in the design that suggests the team understands the failure mode of aggregation, too: selections on a density view return the original underlying rows, not the aggregated bins. That's the thing Datashader workflows historically made painful — you rendered a summary and lost the ability to click through to the actual records.

What it looks like from your desk

If you're the person maintaining an internal dashboard where someone inevitably loads a 20GB Parquet file, XY is aimed squarely at you. Adoption is genuinely cheap to try: uv add xy, compose a chart declaratively, call to_html() or drop it in a notebook. Styling goes through CSS and Tailwind rather than a bespoke theming API, which will feel natural to web developers and mildly heretical to Matplotlib veterans. A separate reflex-xy adapter mounts charts as native components in Reflex apps — no iframes — which is transparently the business logic of the whole exercise: Reflex wants its framework to be the place data-heavy Python apps get built, and charts were a gap.

Now the reasons to wait. This is version 0.0.4, released today, requiring Python 3.11+, and the docs say plainly that callback payloads and rendering thresholds may change. There's no 3D. The Matplotlib-compatible API is still in development, so migrating existing plotting code isn't a drop-in today. And the strategic question deserves real weight: this is a venture-backed web-framework company's adjacent library, Apache 2.0 licensed but with a bus factor tied to one startup's roadmap. The plotting graveyard is full of company-sponsored libraries that stopped mattering when priorities shifted. Matplotlib has survived two decades precisely because it belongs to no one.

The verdict

Architecturally, XY is the right answer — screen-space aggregation with exact drill-down is where interactive plotting has been converging for a decade, and shipping it as a self-contained Python package rather than a research stack is a legitimate contribution. If you're fighting Matplotlib's animation slowness or Plotly's memory footprint on multi-million-point data today, it's worth an afternoon in a notebook this week.

But it's an alpha from a company whose core product is something else. Use it for notebooks and internal tools where a breaking API change costs you an hour. Don't build your product's charting layer on it until it hits 1.0 and the benchmark claims survive contact with someone else's hardware. The idea has already won; whether this particular implementation does is a question for six months from now.

Sources & further reading

  1. reflex-dev/xy: Fast, composable, GPU-accelerated charts for the web and notebooks — github.com
  2. Show HN: XY - A Fast, composable, GPU-accelerated interactive plotting library — news.ycombinator.com
  3. Fast, Interactive Python Charting Library - XY — reflex.dev
  4. xy - PyPI — pypi.org
Rachel Goldstein
Written by
Rachel Goldstein · Dev Tools Editor

Rachel has been embedded in the developer tooling ecosystem for nearly eight years, covering everything from IDE wars and package-manager drama to the quiet rise of AI-assisted coding. She has a soft spot for open-source maintainers and an unhealthy number of terminal emulators installed on a single laptop.

Discussion 0

Join the discussion

Sign in or create an account to comment and vote.

No comments yet

Be the first to weigh in.

Related Reading