Skip to main content

plotilleresample

plotilleresample banner

Python module to resample datasets before plotting with Plotille.

CI PyPI version Python versions License: MIT

Why resample?

Plotille rasterizes to a terminal canvas of braille dots: width * 2 columns by height * 4 rows. Feeding it far more points than that costs interpolation time on detail the canvas cannot show. Plotille rasterizes; plotilleresample decides what information deserves to reach the rasterizer:

Function Strategy Best for
resample_plot uniform stride smooth lines, cheapest reduction
resample_plot_minmax min/max per bucket peaks, oscillations, time series
resample_plot_lttb largest triangle per bucket shape-faithful single line
resample_plot_minmax_lttb minmax preselection + LTTB shape-faithful line, large inputs
resample_scatter uniform stride large scatter inputs

The uniform stride keeps one point every N: fast and predictable, but a narrow peak that falls between two kept points disappears from the plot. resample_plot_minmax instead makes one bucket per braille dot column and keeps the minimum and the maximum Y of each bucket, so the envelope of the signal, spikes included, always survives:

X = list(range(10000))
Y = [0.0] * 10000
Y[33] = 1000.0  # a narrow spike

_, y_stride = plotilleresample.resample_plot(X, Y)
_, y_minmax = plotilleresample.resample_plot_minmax(X, Y)

1000.0 in y_stride  # False: the spike vanished
1000.0 in y_minmax  # True: the envelope survives

resample_plot_lttb implements Largest-Triangle-Three-Buckets (Steinarsson, 2013): it always keeps the first and the last point and picks the most shape-representative point of each bucket, giving a single clean line that looks like the original. It keeps one point per bucket, so (unlike min/max) one of two opposing extremes falling in the same bucket can be dropped: shape fidelity instead of envelope guarantee.

resample_plot_minmax_lttb is the hybrid (MinMaxLTTB, Van der Donckt et al., 2023; the plotly-resampler default): on large inputs a minmax pass preselects the per bucket extremes and LTTB runs over those candidates only. Visually close to pure LTTB and faster, with a gap that grows with input size (about 1.6x end to end at 100,000 points, and about 3.4x on the resampling pass alone at 1,000,000), and the true extremes are always among the candidates.

All four plot resamplers work in sample order: they bucket by index, so X is expected to be already sorted, as in a time series (resample_scatter makes no ordering assumption). They keep at most width * 4 points and resample_scatter keeps at most width * 2 * height, so plotille only receives what the canvas can actually display.

Benchmark

End to end times: building the plot string with plotille alone versus resampling first. Measured with benchmarks/bench.py (canvas 80x40, best of 3) on Python 3.14, Linux, Intel Core i5-1135G7:

Points plotille alone stride + plotille minmax + plotille lttb + plotille mmlttb + plotille
10,000 202 ms 23 ms 22 ms 27 ms 24 ms
100,000 1.75 s 39 ms 52 ms 90 ms 56 ms

Reproduce it from the repository root with:

uv run --group bench benchmarks/bench.py

The resampling-pass figure quoted in Why resample? (pure LTTB vs MinMaxLTTB at 1,000,000 points) has its own script:

uv run benchmarks/bench_resamplers.py

Installation

Install with UV:

uv add plotilleresample

Install with pip:

pip install plotilleresample

plotilleresample has no runtime dependencies, not even plotille: it only reduces sequences. To run the example below, install plotille as well (uv add plotille or pip install plotille).

Usage

import math

import plotille

from plotilleresample import resample_plot_minmax_lttb

r = 100_000
X = list(range(r))
Y = [math.sin(i / 500) * 100 for i in range(r)]

X, Y = resample_plot_minmax_lttb(X, Y, width=80, height=40)
print(plotille.plot(X, Y, width=80, height=40))

The full interactive demo, running every resampler on the same dataset, lives in examples/demo.py.

Acknowledgements

plotilleresample has a narrow purpose, giving Tammo Ippen's plotille only the points its terminal canvas can actually show. plotille now points back to this project from its own README. The min/max strategy came out of the discussion in plotille#22, opened in 2019.

Metadata

Release files for plotilleresample 1.0.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for plotilleresample 1.0.3
File Size Uploaded
plotilleresample-1.0.3.tar.gz 8.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for plotilleresample 1.0.3
File Interpreter ABI Platform
plotilleresample-1.0.3-py3-none-any.whl Python 3 none any Details

Total release size: 14.9 kB

Release files / plotilleresample-1.0.3.tar.gz

Download URL plotilleresample-1.0.3.tar.gz
Size 8.0 kB
Tags Source
SHA-256 checksum
How to use checksums
2d63216cad4c67665611f17b2fbbd2297fc169bcd75789211de37e9691a7247a
BLAKE2b-256 checksum
How to use checksums
0da2964c676752596b347762fc0df630d7513b11ed5b5c2ad6b2e10b5070acd2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / plotilleresample-1.0.3-py3-none-any.whl

Download URL plotilleresample-1.0.3-py3-none-any.whl
Size 6.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dba3a3cac55b338cc31eb346c420449a4d729ae66a74542883669da52d053c3e
BLAKE2b-256 checksum
How to use checksums
5269f9d998da1ac791f2df85eff0c635d65dbffc62e0bc179cb842695c0f6371
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

1.2.0

2 release files

1.1.0

2 release files

This release

1.0.3 This release

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0

2 release files

0.5

2 release files

0.4

1 release file

0.3

1 release file

0.2

1 release file

0.1

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page