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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

plotilleresample-1.0.tar.gz (7.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

plotilleresample-1.0-py3-none-any.whl (6.7 kB view details)

Uploaded Python 3

File details

Details for the file plotilleresample-1.0.tar.gz.

File metadata

  • Download URL: plotilleresample-1.0.tar.gz
  • Upload date:
  • Size: 7.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","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}

File hashes

Hashes for plotilleresample-1.0.tar.gz
Algorithm Hash digest
SHA256 19c336aa168ec725d10b3d6e22e88a9d8ac6b4baff67b42be646dcde0dda583c
MD5 bed8a2a04a4b37809b7c5e229c9f5d97
BLAKE2b-256 4aa781a70c9955e6a6c45fe09a16732c4ee1bae7d20c3d51ea6b73d47a8c1d6c

See more details on using hashes here.

File details

Details for the file plotilleresample-1.0-py3-none-any.whl.

File metadata

  • Download URL: plotilleresample-1.0-py3-none-any.whl
  • Upload date:
  • Size: 6.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","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}

File hashes

Hashes for plotilleresample-1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fb867b16509fc660485050bd3a9e544dcaede8650255093820efb03569c38959
MD5 a68d68206eaa8f09a60a5958a3740555
BLAKE2b-256 3cb270bacada518ed421ac89af16da057758fddd9204968bfdd3e9ffd302db01

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.0 This release

2 files

0.5

2 files

0.4

1 file

0.3

1 file

0.2

1 file

0.1

1 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