Skip to content

tricontourf

Mojo function 🡭

tricontourf

fn def tricontourf(x: List[Float64], y: List[Float64], z: List[Float64], levels: List[Float64] = List(), level_count: Int = Int(8), theme: Theme = Theme(WHITE, Color(UInt8(30), UInt8(100), UInt8(180), UInt8(255)), Color(UInt8(80), UInt8(80), UInt8(80), UInt8(255)), Color(UInt8(225), UInt8(225), UInt8(225), UInt8(255)), Color(UInt8(40), UInt8(40), UInt8(40), UInt8(255)), SIMD(12), SIMD(3.5), SIMD(2), Int(60), Int(20), Int(20), Int(50), True, False, False, Color(UInt8(240), UInt8(240), UInt8(240), UInt8(255)), Int(3), Color(UInt8(60), UInt8(110), UInt8(200), UInt8(255)), Color(UInt8(235), UInt8(235), UInt8(235), UInt8(255)), Color(UInt8(220), UInt8(90), UInt8(40), UInt8(255)), ColorRamp(), ColorPalette(), SIMD(3), SIMD(15), True, SIMD(1), Int(0), False, Color(UInt8(200), UInt8(60), UInt8(60), UInt8(255)), Color(UInt8(224), UInt8(224), UInt8(224), UInt8(255)), Color(UInt8(120), UInt8(120), UInt8(120), UInt8(255)), Color(UInt8(100), UInt8(100), UInt8(100), UInt8(255)), Color(UInt8(230), UInt8(230), UInt8(230), UInt8(255)), Color(UInt8(255), UInt8(255), UInt8(255), UInt8(255)), UInt8(90), UInt8(160), False, False, SIMD(0), SIMD(18), SIMD(14), Color(UInt8(110), UInt8(110), UInt8(110), UInt8(255)), SIMD(14), Color(UInt8(150), UInt8(150), UInt8(150), UInt8(255)), Color(UInt8(224), UInt8(236), UInt8(246), UInt8(200)), Color(UInt8(255), UInt8(255), UInt8(255), UInt8(255)), True, False, False, True, AxisPosition.EDGE, AxisPosition.EDGE, String("sans-serif"), True, UInt8(90), Int(5), Int(4), Int(130), Int(14), Int(8), Int(14), Int(100), Int(8), SIMD(4), OutputFormat.SVG, Tooltips.AUTO, Missing.DRAW, String("(missing)"), Int(1000), False, LineStyle.SOLID, SIMD(1.5), LineStyle.SOLID, LegendPosition.RIGHT, XAxisLabelRotation.AUTO, TickFormat.AUTO, TickFormat.AUTO), width: Int = Int(640), height: Int = Int(420), title: String = "", subtitle: String = "", x_title: String = "", y_title: String = "") -> Chart[Tricontourf]

Filled contour bands over scattered samples: tricontour()’s regions rather than its lines, Delaunay-triangulated the same way – the reading for a field measured at stations, boreholes or any other irregular set of positions.

Mark.TRICONTOURF. See Plot.encode_tricontour() (plot.mojo) for the data shape, which is the same one tricontour() takes, and _render_tricontourf for how the bands are painted.

Filled is usually the more readable of the two for scattered data: isolines alone leave the reader to work out which side of a line is higher, and the fill is what carries the color scale.

To draw both at once, render_layers(tricontourf(...), tricontour(...)) is how to say it – filled bands underneath, isolines on top. Both marks lay out through the same _draw_continuous_axis_frame over the same _data_extent of the same samples, so the combined domain is each one’s own and every isoline lands on exactly the pixel the standalone tricontour() puts it on.

The fill covers the samples’ convex hull, not the whole plot rect – scattered data says nothing about the corners it does not reach.

Example:

from std.math import exp, sin

from dataviz import tricontourf
from dataviz import save

def main() raises:
    var x = List[Float64]()
    var y = List[Float64]()
    var z = List[Float64]()
    var seed = 12345
    for _ in range(240):
        seed = (seed * 1103515245 + 12345) % 2147483648
        var px = Float64(seed % 1200) / 100.0
        seed = (seed * 1103515245 + 12345) % 2147483648
        var py = Float64(seed % 800) / 100.0
        x.append(px)
        y.append(py)
        # Same illustrative well survey as tricontour(), rendered as
        # bands so concentration regions are easier to compare.
        var farm_x = (px - 3.2) / 1.6
        var farm_y = (py - 5.3) / 1.3
        var plant_x = (px - 9.0) / 1.2
        var plant_y = (py - 2.1) / 1.0
        var nitrate = 1.8 + 0.12 * px + 0.4 * sin(py * 1.7)
        nitrate += 5.8 * exp(-(farm_x * farm_x + farm_y * farm_y))
        nitrate += 3.6 * exp(-(plant_x * plant_x + plant_y * plant_y))
        z.append(nitrate)

    var c = tricontourf(
        x,
        y,
        z,
        level_count=10,
        title="Illustrative Groundwater Nitrate Bands (mg/L)",
        x_title="Easting (km)",
        y_title="Northing (km)",
    )
    save(c, "docs/src/examples/out_tricontourf.svg")

Args:

  • x (List[Float64]): Sample x coordinates.
  • y (List[Float64]): Sample y coordinates, one per x entry.
  • z (List[Float64]): The value at each sample.
  • levels (List[Float64]): Explicit level values. Empty (the default) places level_count of them evenly inside the samples’ own range.
  • level_count (Int): How many levels to place when levels is empty.
  • theme (Theme): Colors, sizes and spacing.
  • width (Int): Canvas width in pixels.
  • height (Int): Canvas height in pixels.
  • title (String): Chart title.
  • subtitle (String): Smaller line under the title.
  • x_title (String): X-axis label.
  • y_title (String): Y-axis label.

Returns:

Chart[Tricontourf]: The finished Plot.

Raises:

Error: Empty data, mismatched column lengths, or a non-positive level_count.

fn def tricontourf(df: DataFrame, x: String, y: String, z: String, levels: List[Float64] = List(), level_count: Int = Int(8), theme: Theme = Theme(WHITE, Color(UInt8(30), UInt8(100), UInt8(180), UInt8(255)), Color(UInt8(80), UInt8(80), UInt8(80), UInt8(255)), Color(UInt8(225), UInt8(225), UInt8(225), UInt8(255)), Color(UInt8(40), UInt8(40), UInt8(40), UInt8(255)), SIMD(12), SIMD(3.5), SIMD(2), Int(60), Int(20), Int(20), Int(50), True, False, False, Color(UInt8(240), UInt8(240), UInt8(240), UInt8(255)), Int(3), Color(UInt8(60), UInt8(110), UInt8(200), UInt8(255)), Color(UInt8(235), UInt8(235), UInt8(235), UInt8(255)), Color(UInt8(220), UInt8(90), UInt8(40), UInt8(255)), ColorRamp(), ColorPalette(), SIMD(3), SIMD(15), True, SIMD(1), Int(0), False, Color(UInt8(200), UInt8(60), UInt8(60), UInt8(255)), Color(UInt8(224), UInt8(224), UInt8(224), UInt8(255)), Color(UInt8(120), UInt8(120), UInt8(120), UInt8(255)), Color(UInt8(100), UInt8(100), UInt8(100), UInt8(255)), Color(UInt8(230), UInt8(230), UInt8(230), UInt8(255)), Color(UInt8(255), UInt8(255), UInt8(255), UInt8(255)), UInt8(90), UInt8(160), False, False, SIMD(0), SIMD(18), SIMD(14), Color(UInt8(110), UInt8(110), UInt8(110), UInt8(255)), SIMD(14), Color(UInt8(150), UInt8(150), UInt8(150), UInt8(255)), Color(UInt8(224), UInt8(236), UInt8(246), UInt8(200)), Color(UInt8(255), UInt8(255), UInt8(255), UInt8(255)), True, False, False, True, AxisPosition.EDGE, AxisPosition.EDGE, String("sans-serif"), True, UInt8(90), Int(5), Int(4), Int(130), Int(14), Int(8), Int(14), Int(100), Int(8), SIMD(4), OutputFormat.SVG, Tooltips.AUTO, Missing.DRAW, String("(missing)"), Int(1000), False, LineStyle.SOLID, SIMD(1.5), LineStyle.SOLID, LegendPosition.RIGHT, XAxisLabelRotation.AUTO, TickFormat.AUTO, TickFormat.AUTO), width: Int = Int(640), height: Int = Int(420), title: String = "", subtitle: String = "", x_title: String = "", y_title: String = "") -> Chart[Tricontourf]

tricontourf() over named columns of a dataframe_mojo DataFrame (#743). x, y, and z name columns; levels supplies contour thresholds independently of the rows.

The filled counterpart of tricontour()’s own frame overload, which this mirrors.

See Plot.encode_frame() for how columns are read and what a column with missing values does.

Args:

  • df (DataFrame): The frame to read.
  • x (String): The numeric column for this channel.
  • y (String): The numeric column for this channel.
  • z (String): The numeric column for this channel.
  • levels (List[Float64]): Explicit contour levels; empty uses level_count.
  • level_count (Int): See the list overload.
  • theme (Theme): See the list overload.
  • width (Int): See the list overload.
  • height (Int): See the list overload.
  • title (String): See the list overload.
  • subtitle (String): See the list overload.
  • x_title (String): See the list overload.
  • y_title (String): See the list overload.

Returns:

Chart[Tricontourf]: The finished chart – unrendered.

Raises:

Error: A named column is missing, has the wrong dtype for its channel, or has missing values.