Macaw.Data.Reduce (macaw_data v0.5.3)

Copy Markdown View Source

Shape-preserving downsampling (spec/01 ยง2.4): the two reducers finishing uses to bring a delivery within a budget.

  • lttb/3, Largest-Triangle-Three-Buckets, keeps about n points chosen to keep a series' visual shape;
  • m4/3 keeps, per pixel column, the first, last, least and greatest points, which a line drawn that wide needs to draw the same pixels as all of them.

Both treat a datum whose x or y is not a number as a gap, kept in place, so a line over the result still breaks where the input broke. Ported from visualize's Visualize.Data.lttb/3 and m4/3.

Summary

Functions

Largest-Triangle-Three-Buckets: about n of the elements, chosen to keep the series' visual shape (Steinarsson 2013).

M4: per pixel column, the first, last, least-y and greatest-y elements โ€” the elements a line drawn width pixels wide needs to draw the same pixels as all of them (Jugel et al. 2014).

Functions

lttb(data, n, accessor \\ nil)

@spec lttb([any()], pos_integer(), (any() -> {term(), term()}) | nil) :: [any()]

Largest-Triangle-Three-Buckets: about n of the elements, chosen to keep the series' visual shape (Steinarsson 2013).

The accessor returns {x, y}; without one the elements are {x, y} tuples. A datum whose x or y is not a number is a gap: the defined data are reduced run by run between the gaps, and each run of gaps keeps its first element in place, so a line over the result still breaks where the input broke. Input of n or fewer elements is returned unchanged; without gaps the result is exactly n elements, the first and the last among them. n must be at least 3.

Examples

iex> Macaw.Data.Reduce.lttb([{0, 0}, {1, 1}, {2, 0}, {3, 5}, {4, 0}, {5, 1}, {6, 0}], 4)
[{0, 0}, {2, 0}, {3, 5}, {6, 0}]

iex> Macaw.Data.Reduce.lttb([{0, 0}, {1, 3}, {2, nil}, {3, 4}, {4, 1}], 9)
[{0, 0}, {1, 3}, {2, nil}, {3, 4}, {4, 1}]

m4(data, width, accessor \\ nil)

@spec m4([any()], pos_integer(), (any() -> {term(), term()}) | nil) :: [any()]

M4: per pixel column, the first, last, least-y and greatest-y elements โ€” the elements a line drawn width pixels wide needs to draw the same pixels as all of them (Jugel et al. 2014).

The columns split the extent of the defined x readings evenly. The accessor, the gaps and the runs are as lttb/3's: each run of gaps keeps its first element in place, and each stretch of one run in one column keeps at most four elements, deduplicated and in input order. width must be at least 1.

Examples

iex> Macaw.Data.Reduce.m4([{0, 1}, {1, 5}, {2, 0}, {3, 2}, {4, 3}, {5, 9}, {6, 4}, {7, 6}], 2)
[{0, 1}, {1, 5}, {2, 0}, {3, 2}, {4, 3}, {5, 9}, {7, 6}]

iex> Macaw.Data.Reduce.m4([{0, 1}, {1, 2}, {2, nil}, {3, nil}, {4, 3}], 1)
[{0, 1}, {1, 2}, {2, nil}, {4, 3}]