Data Visualization

Contour Surfaces

Turn a matrix into a dense, colored 3D heightmap using contour bands, stitched disjoint paths, cached geometry, and in-place data updates.

Updated Publisher Alien_AlgorithmsPine Script v6

Contour band rendering

Naive triangle drawing exhausts TradingView’s 100-polyline limit quickly. Pine3D quantizes elevation into colored bands, groups all cells from a band, and stitches disconnected islands into one hole-aware path using invisible bridges.

  • One band path can carry many disconnected triangle-equivalent regions.
  • Band paths are depth-sorted and near-plane culled.
  • Contour geometry is cached between data changes.
  • Large heightmaps can fit within the fixed polyline budget.

Create a surface

Damped cosine heightmappine
//@version=6
indicator("Pine3D Contour Surface", overlay = false,
  max_polylines_count = 100, max_lines_count = 500, max_labels_count = 500)
import Alien_Algorithms/Pine3D/1 as p3d

var p3d.Scene scene = p3d.newScene()
var p3d.Mesh heatmap = na

if barstate.isfirst
    int N = 20
    matrix<float> data = matrix.new<float>(N, N, 0.0)
    for r = 0 to N - 1
        for c = 0 to N - 1
            float dx = c - (N - 1) / 2.0
            float dz = r - (N - 1) / 2.0
            float d = math.sqrt(dx * dx + dz * dz) * 0.7
            data.set(r, c, math.cos(d) * math.exp(-d * 0.12) * 50.0)

    heatmap := p3d.surface(data, 200.0, color.blue, color.red, 24)
      .gridBox()
      .gridLabels(color.white, "X", "Amplitude", "Z")
    scene.add(heatmap)
    scene.camera.orbit(35.0, 25.0, 380.0)

if barstate.islast
    p3d.render(scene, lighting = true)

surface(heights, size, lowCol, highCol, levels, axisX, axisZ) reads a matrix<float>, maps values to vertical position, and grades color from low to high.

Grid cage and labels

  • .gridBox() adds a wireframe bounding cage.
  • .gridLabels(color, xName, yName, zName) adds axis titles and tick values.
  • Tick labels refresh when the data range changes.

Non-uniform grids

Optional axisX and axisZ arrays provide explicit column and row coordinates. This supports irregular timestamps, logarithmic strike spacing, or other non-uniform domains without resampling.

Update data in place

Refresh the heightmappine
if barstate.islast
    heatmap.updateSurface(newDataMatrix)
    p3d.render(scene, lighting = true)
Compute series globally
Any history-dependent source for the matrix must be calculated at global scope. Build the matrix from those values, then pass it into updateSurface() on the last bar.

Budget guidance

  • Reduce contour levels before reducing matrix resolution.
  • Use the linefill backend for in-place updates.
  • Lower occlusion resolution for faster dense-scene rendering.
  • Do not rebuild labels or cages every frame.
  • Use scene.totalFaces() and drawing monitor tables while profiling.

Common uses

Volatility surfaces, parameter sensitivity maps, depth heatmaps, correlation landscapes, optimization objectives, and any matrix-valued market feature.

Pine3D is a graphical rendering library for Pine Script. TradingView drawing, execution, and publication limits still apply. © Alien_Algorithms.