# plotly-resampler aggregates time series on the fly so a line chart stays fast

> plotly-resampler adds server-side resampling to Plotly figures, aggregating the visible window of a time series with MinMaxLTTB so a chart over 100 million points stays interactive. The project is MIT licensed, still maintained for fixes, and its successor FlexViz is where new development happens.

**predict-idlab/plotly-resampler** — Visualize large time series data with plotly.py

- Repository: https://github.com/predict-idlab/plotly-resampler
- Website: https://predict-idlab.github.io/plotly-resampler/latest
- Stars: 1,211 · Forks: 78
- Language: Python
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/predict-idlab-plotly-resampler

## The aggregation happens in the backend, not in the browser

plotly-resampler improves the scalability of Plotly for visualizing large time series datasets, and the mechanism is stated precisely: it dynamically aggregates time-series data respective to the current graph view, so the updates during panning and zooming stay efficient and responsive.

That is the whole idea, and it is a good one. A Plotly figure holds its data in the browser as JSON. With a hundred million points, the browser has to download, parse and render all of it, and every pan or zoom re-renders it. The alternative is to send only the points that are visible, and to send a new set whenever the view changes.

The aggregation is done by time-series data point selection algorithms, and the library delegates that to the highly optimized implementations in tsdownsample, from the same organisation. The default method is MinMaxLTTB and it selects 1000 data points for plotting. MinMaxLTTB is a downsampling algorithm that combines a min-max envelope with a largest-triangle-three-buckets selection, and the project points at a dedicated MinMaxLTTB repository and an arXiv paper for the details.

The README describes the result in terms of a demo: over 110,000,000 data points are visualized in the basic example notebook, and the demo is linked as an animated gif.

The choice of 1000 points as the default is a deliberate trade. It is a resolution, and the aggregation algorithm is what makes a chosen resolution meaningful, because a naive every-nth-point sample would miss spikes while MinMaxLTTB preserves the extremes and the shape of the curve within each bucket.

## There are three ways to use it, and one of them is a trap

The feature list offers three entry points, and the details section expands on the difference between them.

You can add the register_plotly_resampler function to your notebook with the best suited mode argument, you can wrap a Plotly figure with the FigureResampler decorator and call .show_dash(), or you can use the FigureWidgetResampler decorator and output the instance in a cell.

The important warning is about the plain show method. The README says show always generates a static HTML view of the figure, prohibiting dynamic aggregation, and to have dynamic aggregation you have to use show_dash with FigureResampler, which initiates a Dash app to realise the dynamic aggregation with callbacks, or to use FigureWidgetResampler with IPython.display, which uses widget events to realise the aggregation through the running IPython kernel.

So calling show on a resampler figure gives you a static picture of the aggregated data, and it looks like it works while none of the resampling behaviour is present. The way to get the interactive behaviour is Dash with callbacks, or a figure widget in a notebook. Anyone adopting this needs to know that before they start, because the difference is not visible in the code, only in the behaviour.

The environment independence is the other part of the feature list. It can be used in Jupyter, vscode-notebooks, Pycharm-notebooks, Google Colab, DataSpell, and even as an application on a server. The Dash path is the server path, since a Dash app is a server.

## The autoscale behaviour deliberately differs from vanilla Plotly

There is one behavioural override, and the README is candid that it is a deliberate opinion.

Double-clicking within a line-chart area does not Reset Axes in a plotly-resampler figure, because it results in an Autoscale event. The project says they decided to implement an Autoscale event as updating the y-range so that it shows all the data that is in your x-range, and that vanilla Plotly figures produce Reset Axes behaviour as their Autoscale result, which in their opinion did not make a lot of sense.

This is a small thing that matters in practice. With a resampled chart, the y-axis is drawn from the currently visible data, so a Reset Axes would jump the y-range to the full dataset and break the correspondence between the visible window and the axis. Rescaling the y-range to the visible x-window is what keeps the chart readable as you pan.

It is also a compatibility difference you inherit. Code or habits built around vanilla Plotly's double-click behaviour will behave differently here, and a user who has not read this will experience it as a bug.

The rest of the differences come from the wrapper model. The README describes plotly-resampler as a wrapper around plain Plotly figures which adds visualization scalability to line charts by dynamically aggregating the data with respect to the front-end view, and says it thus adds dynamic aggregation functionality to plain Plotly figures. The feature list makes the same point from the other side, saying that it allows all other Plotly figure construction flexibility to be used.

## FlexViz is the successor, and it changes the scope

The first thing in the README is a notice about a successor project, and it should shape any decision about adopting this one.

The README says FlexViz is the successor project. The comparison is precise: plotly-resampler makes one Plotly trace fast, that is a line trace, while flexviz applies the same principle, never ship the raw data to the browser, to a whole dashboard. FlexViz adds linked cross-filtering, ten trace types, which are lines, histograms, bars, pies, box plots, treemaps, 2D histograms, correlation heatmaps and maps, and a drag-and-resize grid. The README says it stays interactive at 100M+ rows and 1B+ points per chart, with peak backend memory around 25 MB at 200M rows, and there is a live demo on two hundred million rows.

The status line is equally clear. plotly-resampler remains maintained, for bug fixes and Plotly compatibility, but new development happens in flexviz.

Those numbers for flexviz are vendor claims in a README, so they deserve the usual caution, but the direction of travel is not ambiguous. A project that ships one fast line trace and a successor that ships a fast dashboard with cross-filtering is telling you which one to build on.

The practical reading depends on what you need. If you have one heavy line chart in an existing Plotly application, plotly-resampler solves that problem and the wrapper model keeps your existing figure construction code. If you are building a dashboard with several trace types that filter each other, the successor is the project that covers that, and starting on plotly-resampler means migrating later.

## Packaging, dependencies and what to check before installing

The project is packaged with poetry, and the pyproject.toml shows a carefully bounded dependency set.

The version is 0.11.1, the licence is MIT, and the authors are Jonas Van Der Donckt, Jeroen Van Der Donckt and Emiel Deprost. The declared Python constraint is ^3.8, with classifiers for 3.8 through 3.13 and for POSIX Linux, MacOS X and Windows.

The dependencies are pinned in ranges: plotly is at least 5.5.0 and below 7.0.0, dash is at least 2.11.0 with a note that from dash 2.11 Jupyter support is included, and pandas is at least 1 for Python below 3.13 and at least 2.2.3 for 3.13 and later. numpy has a similar split, with different minimums per Python version.

One packaging detail is worth noting if you build a wheel. The include list adds the C extension artefacts to the wheel distributions, both the .so files and the .pyd files, with a comment that C extensions must be included in the wheel distributions. So the aggregation is backed by compiled code, not pure Python, and a custom build has to carry the binaries.

The repository layout is a standard Python project with a Makefile whose targets are format, lint, test, docs and clean. The format target runs black and ruff, lint runs ruff and black in check mode, test runs pytest with coverage over the plotly_resampler package, and docs runs mkdocs build. The mkdocs/ directory and mkdocs.yml hold the documentation, the examples/ directory has notebooks including basic_example.ipynb, figurewidget_example.ipynb, datashader.ipynb and other_examples.ipynb plus a dash_apps/ folder, and there is a CHANGELOG.md.

The release history shows a slow but steady cadence: 0.10.0 in March 2024, 0.11.0 in August 2025 and 0.11.1 on 2026-10-04, with the last push on the same day, so the maintenance commitment in the README is backed by recent commits even if the versions move slowly.

## Conclusion

plotly-resampler suits a team that already uses Plotly and Dash and needs one heavy line chart to stay responsive, and it is the wrong tool for a dashboard with many trace types, since the README says FlexViz is the successor and covers ten of them with linked cross-filtering. Before adopting it, read the show versus show_dash distinction, because the static show path gives you no dynamic aggregation at all and that is the trap most users hit. Verify first that your Plotly version falls in the supported range of 5.5.0 up to below 7.0.0, and that your Python version matches the constraint the project declares.

## FAQ

### What is plotly-resampler?

It is a Python library that adds resampling to Plotly figures, dynamically aggregating time series data with respect to the current graph view so that panning and zooming stay responsive on very large datasets. The default aggregation method is MinMaxLTTB, which selects 1000 points for plotting.

### How do I get dynamic aggregation in plotly-resampler?

Not with show, which always produces a static HTML view and prohibits dynamic aggregation. Use show_dash with FigureResampler to start a Dash app with callbacks, or use FigureWidgetResampler and output the instance in a cell so that IPython widget events drive the aggregation.

### What is the difference between plotly-resampler and FlexViz?

FlexViz is the successor project. plotly-resampler makes one Plotly trace fast, while flexviz applies the same never-ship-raw-data principle to a whole dashboard with linked cross-filtering, ten trace types and a drag-and-resize grid, and it stays interactive at 100M+ rows.

### Which aggregation algorithms can I use?

The library provides an interface for various aggregation algorithms, with the ability to develop or select your preferred sequence aggregation method. The default is MinMaxLTTB, and the underlying implementations come from the tsdownsample project.

### What does plotly-resampler need to install?

The declared dependencies are plotly at least 5.5.0 and below 7.0.0, dash at least 2.11.0, pandas and numpy with version dependent minimums, and the project requires Python 3.8 or newer. It is MIT licensed and the latest release is 0.11.1 from 2026-10-04.

## Sources

- [License: MIT](https://github.com/predict-idlab/plotly-resampler/blob/main/LICENSE)
- [predict-idlab/plotly-resampler on GitHub](https://github.com/predict-idlab/plotly-resampler)
- [Project website](https://predict-idlab.github.io/plotly-resampler/latest)
- [README](https://github.com/predict-idlab/plotly-resampler/blob/main/README.md)
- [Releases](https://github.com/predict-idlab/plotly-resampler/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/predict-idlab-plotly-resampler
