///|
// Validate the input shared by all stackplot baseline algorithms.
fn validate_stackplot_input(
xs : Array[Double],
ys : Array[Array[Double]],
labels : Array[String],
baseline : String,
) -> Unit raise @core.DataError {
if xs.is_empty() {
raise @core.DataError::InvalidReference(
message="stackplot requires at least one x value",
)
}
if ys.is_empty() {
raise @core.DataError::InvalidReference(
message="stackplot requires at least one y series",
)
}
if labels.length() != 0 && labels.length() != ys.length() {
raise @core.DataError::LengthMismatch(
expected=ys.length(),
actual=labels.length(),
)
}
if baseline != "zero" &&
baseline != "sym" &&
baseline != "wiggle" &&
baseline != "weighted_wiggle" {
raise @core.DataError::InvalidReference(
message="stackplot baseline must be zero, sym, wiggle, or weighted_wiggle",
)
}
for value in xs {
if value.is_nan() || value.is_inf() {
raise @core.DataError::InvalidReference(
message="stackplot x values must be finite",
)
}
}
for row in ys {
if row.length() != xs.length() {
raise @core.DataError::LengthMismatch(
expected=xs.length(),
actual=row.length(),
)
}
for value in row {
if value.is_nan() || value.is_inf() {
raise @core.DataError::InvalidReference(
message="stackplot y values must be finite",
)
}
}
}
}
///|
fn stackplot_zeroes(length : Int32) -> Array[Double] {
let result = Array(capacity=length)
for _ in 0.. Array[Array[Double]] {
let length = ys[0].length()
let cumulative = stackplot_zeroes(length)
let result : Array[Array[Double]] = []
for row in ys {
let upper = Array(capacity=length)
for index in 0.. Array[Double] {
let rows = ys.length()
let length = ys[0].length()
let result = stackplot_zeroes(length)
if baseline == "zero" {
return result
}
if baseline == "sym" {
for index in 0.. 0.0 { 1.0 / total } else { 0.0 }
let mut movement = 0.0
for row_index in 0.. String {
if labels.is_empty() {
""
} else {
labels[index]
}
}
///|
fn Axes::add_stackplot_layer(
self : Axes,
xs : Array[Double],
lower : Array[Double],
upper : Array[Double],
color : String,
label : String,
) -> Artist {
let lower_points = Array(capacity=xs.length())
let upper_points = Array(capacity=xs.length())
for index in 0.. Array[Artist] raise @core.DataError {
self.axes().stackplot(xs, ys, labels~, colors~, baseline~)
}
///|
/// Draw a stacked area plot through the axes handle.
pub fn Axes::stackplot(
self : Axes,
xs : Array[Double],
ys : Array[Array[Double]],
labels~ : Array[String] = [],
colors~ : Array[String] = [],
baseline~ : String = "zero",
) -> Array[Artist] raise @core.DataError {
validate_stackplot_input(xs, ys, labels, baseline)
let stacked = stackplot_cumulative(ys)
let first_line = stackplot_first_line(ys, stacked, baseline)
let start = self.state.val.artists.length()
let mut lower = first_line.copy()
let result : Array[Artist] = []
for row_index in 0..