Visualize.Scale.Symlog (Visualize v0.2.35)

Copy Markdown View Source

Symmetric log scale for data spanning orders of magnitude including zero.

Unlike a regular log scale, symlog can handle zero and negative values. It's linear near zero and logarithmic for larger absolute values.

The constant parameter controls the transition point between linear and logarithmic behavior.

Examples

# Scale that handles -1000 to 1000 including zero
scale = Visualize.Scale.Symlog.new()
  |> Visualize.Scale.Symlog.domain([-1000, 1000])
  |> Visualize.Scale.Symlog.range([0, 400])

Visualize.Scale.Symlog.apply(scale, 0)     # => 200.0 (center)
Visualize.Scale.Symlog.apply(scale, 100)   # => ~300
Visualize.Scale.Symlog.apply(scale, -100)  # => ~100

Formula

The transformation is: sign(x) * log1p(|x| / constant)

Summary

Functions

Maps a value from the domain to the range using the symlog transform

Returns 0: a symlog scale has no bandwidth

Enables or disables clamping of the output to the range

Sets the constant that controls the linear/log transition.

Sets the domain from a two-element list; a two-tuple is accepted and stored as a list

Maps a value from the range back to the domain (inverse)

Creates a new symlog scale

Extends the domain to nice round values, as Linear.nice/1 does

Identity: a symlog scale has no padding

Sets the range from a two-element list; a two-tuple is accepted and stored as a list

Alias of apply/2, kept for one release (spec/03 §1.3)

Generates nice tick values for the scale: signed decades of the constant, and zero

Types

t()

@type t() :: %Visualize.Scale.Symlog{
  clamp?: boolean(),
  constant: number(),
  domain: [number()],
  range: [number()]
}

Functions

apply(scale, value)

@spec apply(t(), number()) :: number()

Maps a value from the domain to the range using the symlog transform

bandwidth(symlog)

@spec bandwidth(t()) :: 0

Returns 0: a symlog scale has no bandwidth

clamp(scale, clamp?)

@spec clamp(t(), boolean()) :: t()

Enables or disables clamping of the output to the range

constant(scale, c)

@spec constant(t(), number()) :: t()

Sets the constant that controls the linear/log transition.

Smaller values make the linear region smaller. Default is 1.

domain(scale, arg2)

@spec domain(t(), [number()] | {number(), number()}) :: t()

Sets the domain from a two-element list; a two-tuple is accepted and stored as a list

invert(symlog, value)

@spec invert(t(), number()) :: number()

Maps a value from the range back to the domain (inverse)

new()

@spec new() :: t()

Creates a new symlog scale

nice(scale)

@spec nice(t()) :: t()

Extends the domain to nice round values, as Linear.nice/1 does

padding(scale, padding)

@spec padding(t(), number()) :: t()

Identity: a symlog scale has no padding

range(scale, arg2)

@spec range(t(), [number()] | {number(), number()}) :: t()

Sets the range from a two-element list; a two-tuple is accepted and stored as a list

scale(scale, value)

@spec scale(t(), number()) :: number()

Alias of apply/2, kept for one release (spec/03 §1.3)

ticks(symlog, count \\ 10)

@spec ticks(t(), integer()) :: [number()]

Generates nice tick values for the scale: signed decades of the constant, and zero