1. User Guide
Contour Plotter is an offline web application for creating contour maps from CSV survey data. It supports optional background images or CAD drawings, cross-section elevation profiles, and export to PNG, DXF, and project JSON.
Getting started
| Requirement | Details |
|---|---|
| Browser | Chrome, Edge, or Firefox (recent). JavaScript enabled. |
| Internet | Not required after the app file is copied to the PC. |
| Data | CSV with columns X, Y, Z |
| Optional | JPG/PNG site plan (+ world file), or DXF drawing (max 150 MB) |
CSV data format
| Column | Description |
|---|---|
| X | Easting or horizontal coordinate |
| Y | Northing or vertical coordinate |
| Z | Elevation or value to contour |
| Name (optional) | Headers: Name, ID, Point, Label — shown on point labels (else P1, P2, …) |
- Minimum 3 valid rows across enabled files.
- Header names are case-insensitive. Delimiter auto-detected (comma, semicolon, tab).
- Decimals:
.or,. Negative X, Y, Z supported. Large UTM coordinates supported. - Multiple CSV files: enable/disable individually in the file list.
X,Y,Z 100.000,200.000,12.400 101.500,201.200,13.100 102.000,199.800,11.900
Workflow
- Upload CSV — sidebar Data → drag or select one or more
.csvfiles. Plot auto-generates on success. - Adjust Contour settings (interval, colors, theme) as needed.
- Use Fit to Data (bottom-right) to reset the view.
- Export PNG, DXF, or project JSON from the sidebar.
After changing Grid resolution or Clip to data hull, click Generate Plot to re-run interpolation.
Background overlays
Image (JPG / PNG)
- Set background to IMAGE.
- Upload image; optionally drop a world file (
.jgw,.pgw,.tfw) together. - Set extent fields (X-min, X-max, Y-min, Y-max) or click Auto from CSV.
- Use 2-point calibration to align by clicking two known locations and entering world coordinates.
- Import inverted… inverts colors (light plans → dark background for dark theme).
DXF (CAD)
- Set background to DXF and upload
.dxf(max 150 MB). - Lines appear under the contour; view auto-fits to combined bounds.
| File size | Behavior |
|---|---|
| Under ~50 MB | Full line geometry |
| 50–150 MB | Lines-only mode (hatches/text skipped) |
| Over 150 MB | Rejected |
Cross section profiles
- Generate a contour plot from CSV data.
- Enable Cross section in the sidebar.
- Set Start angle (0° = East, 90° = North) and optional Section line length.
- Click Add section line — line appears at map centre.
- Drag endpoints on the map. Add more lines (A, B, C, …) for comparison.
- Export CSV with Export cross section CSV (set export interval first).
CSV export format (wide): Distance,Elevation A,Elevation B,… — one row per distance step. Blank cells where the sample falls outside the interpolated area (e.g. hull clipping).
Project save and load
Export project / Import project saves a .json file containing all CSV datasets, contour settings, backgrounds, viewport, and cross-section state.
Plot viewer
| Control | Action |
|---|---|
| Fit to Data | Zoom to all CSV + background bounds |
| Pan | Click-drag to move |
| Zoom | Drag rectangle to zoom in |
| Scroll wheel | Zoom in/out |
| Hover | Coordinate readout (X, Y, Z) bottom-left |
Axis labels use 3 decimal places. Map keeps 1:1 scale (1 m in X = 1 m in Y on screen).
Troubleshooting
| Problem | Solution |
|---|---|
| Blank page | Use Chrome or Edge; rebuild index.html |
| Missing X, Y, Z columns | Fix CSV header row |
| Need at least 3 valid rows | Enable files with enough points |
| Flat color / no contours | Check Z range; adjust contour interval |
| Image misaligned | World file, extent fields, or 2-point calibration |
| Cross section CSV blanks | Line outside hull; move line or disable hull clip |
2. Geography & Topography Fundamentals
Contour Plotter draws on classical topographic cartography. Understanding how contour lines represent land surface helps you choose interval, read the map, and validate exports against field survey.
What contour lines are
A contour line (contour) is a line on a map joining points of equal elevation above a chosen datum (e.g. mean sea level, local benchmark, or project zero). On a topographic map, every point along one contour has the same height; moving across a contour means changing elevation.
In this application, the Z column in your CSV is treated as that scalar value—most often elevation (m or ft), but it can represent any continuous field (e.g. groundwater head, pollution concentration) that you wish to visualize as isolines.
| Cartographic term | In Contour Plotter |
|---|---|
| Contour interval | Contour interval slider — vertical distance between adjacent contour levels (e.g. 0.5 m, 1 m, 5 m) |
| Index contour | Every Nth line on paper maps is emphasised; here all levels use the same line weight unless you change step size |
| Datum / zero | Implicit in your Z values; the app does not shift datum—you supply absolute or relative elevations |
| Plan position | X (easting) and Y (northing), e.g. UTM or local grid |
Reading slope and landform from contours
- Contour spacing: Lines close together indicate steep slope; widely spaced lines indicate gentle slope. The horizontal distance between lines at a given interval is inversely related to gradient.
- Valleys and ridges: Contours form V shapes where they cross valleys or ridges. The V points upstream (toward higher ground) in a valley; on a ridge, bends point toward lower ground.
- Hills and depressions: Closed loops indicate hills (higher values toward the centre) or depressions/basins (lower values toward the centre). Without hatch marks, compare inner labels to outer labels to distinguish mound vs hollow.
- Uniform slope: Parallel, evenly spaced contours suggest a planar or uniform gradient (cut slope, embankment, or flat terrace).
scaleanchor), so horizontal distances on screen match true plan distances—essential for comparing contour spacing to real-world slope.
Survey coordinates and elevation (Z)
Topographic surveys typically record:
- X, Y — horizontal position on a projected coordinate system (e.g. UTM easting/northing) or local site grid.
- Z — height from GNSS, total station, or level run.
Discrete survey points are rarely dense enough to draw smooth contours directly. Cartographers and GIS software interpolate a surface between points, then extract contours at regular Z intervals—the same workflow this tool uses (grid → interpolate → contour levels).
Cross sections in civil and geotechnical work are vertical slices along a plan line (chainage vs elevation). The app’s cross-section export samples the interpolated surface along user-drawn lines—analogous to a section cut on a topographic model.
How this tool relates to published topographic maps
| Published topographic map | Contour Plotter output |
|---|---|
| Contours from photogrammetry, lidar, or field levelling | Contours from your CSV points + chosen grid/interpolation |
| Fixed national contour interval (e.g. 10 m on 1:50k) | User-defined interval and smoothing |
| Index contours, relief shading, hydrography | Colour-filled bands, optional lines-only mode, optional CAD/image underlay |
| Accurate only within survey control | Accuracy limited by point density, interpolation, and Clip contours to data area (convex hull) |
Always treat interpolated contours between survey points as modelled, not measured. Increase point density or reduce grid spacing where detail matters; use hull clipping to avoid drawing contours in unsampled voids.
3. Mathematics & Algorithms
This section describes how survey points become a displayed contour map. The pipeline runs entirely in the browser.
Processing pipeline
- Parse CSV → array of (X, Y, Z) points; compute data statistics (bounds, Z min/max).
- Build interpolation grid → regular N×N lattice over the XY bounding box.
- Interpolate Z at each grid node (Delaunay + barycentric, with IDW fallback).
- Optional hull clip → set grid cells outside the convex hull to NaN.
- Render → Plotly
contourtrace on the grid; contour levels from step size. - DXF export → separate pass using d3-contour marching squares on the same grid.
Grid construction & interpolation
The Grid resolution parameter sets both row and column count (50–300, default 100). The grid spans the axis-aligned bounding box of all survey points:
Coordinates are shifted by an origin (x₀, y₀) near the data centroid before interpolation to improve floating-point precision for large survey coordinates (e.g. UTM).
Primary method: Delaunay triangulation + barycentric interpolation
For each grid node (px, py):
- Build a Delaunay triangulation of all survey points in local coordinates.
- Find the triangle containing (px, py) by testing barycentric weights wA, wB, wC ≥ 0.
- Interpolate: Z = wA·ZA + wB·ZB + wC·ZC.
Barycentric weights for point P in triangle ABC:
wB = ((Cy−Ay)(Px−Cx) + (Ax−Cx)(Py−Cy)) / denom
wC = 1 − wA − wB
Higher grid resolution → finer lattice → smoother contours and more detail between points, at the cost of computation time.
IDW fallback (Inverse Distance Weighting)
When Delaunay fails or a grid node lies outside all triangles, the tool falls back to IDW with power p = 2:
If the grid node coincides exactly with a survey point (d = 0), that point's Z value is used directly. IDW produces smooth blending but can create bull's-eye patterns near isolated points; the Delaunay path is preferred inside the triangulated region.
Convex hull clipping
When Clip contours to data area is enabled:
- Compute the convex hull of all survey XY positions (Andrew's monotone chain algorithm).
- For each grid cell centre, test point-in-polygon (ray casting).
- Cells outside the hull → Z set to NaN.
Plotly is configured with connectgaps: false, so NaN cells break both filled regions and contour lines at the hull boundary. This prevents extrapolation into areas with no survey coverage. Disabling hull clip leaves the full rectangular grid interpolated (including extrapolated corners).
Contour level generation
Contour levels are not auto-generated (autocontour: false). They are computed from the contour interval (step) and the data Z range:
Levels are placed at start, start + step, start + 2·step, … up to end. This grid alignment ensures negative Z values are fully covered and labels align to round values.
The on-screen contour trace sets zmin/zmax to the data range and contours.size to the step. Labels show 3 decimal places (labelformat: '.3f').
For DXF export, d3-contour marching squares extracts iso-lines at the same threshold levels from the Z matrix, then maps grid indices back to world coordinates.
1:1 scale (scaleanchor)
The plot enforces equal data units on both axes:
xaxis.scaleanchor = 'y'xaxis.scaleratio = 1
A 100 m span in X occupies the same screen distance as 100 m in Y. PNG export preserves this constraint. The reference dimension setting controls which pixel edge receives the preset resolution; the other edge is computed from the data/view aspect ratio and layout margins.
Line smoothing
The Smoothness parameter maps to Plotly contour line smoothing (0–1, default 0.85):
- 0 — sharp, piecewise-linear contour segments following grid geometry.
- 1 — maximum curve rounding between vertices (visually smoother arcs).
Smoothing affects the rendered polyline only — it does not change the underlying Z grid or filled colour bands. The fill is drawn between iso-levels on the raw grid; only the line stroke is smoothed.
4. Parameter Reference
Each sidebar control and its effect on Lines contour lines, Area filled heatmap, and Labels contour value labels.
Contour controls
| Parameter | Valid range | What it does | Effect on lines | Effect on area | Effect on labels |
|---|---|---|---|---|---|
| Plot theme | Dark, White | Sets background, axis, line, and label colours. | Line colour: theme contour line (dark) or black (white theme, lines-only). | Background + colorbar styling; white theme = white paper. | Label font colour follows theme. |
| Contour interval | 0.1 – 100 (default 10) | Spacing between contour levels in Z units. | Smaller → more lines closer together; larger → fewer, wider-spaced lines. | More levels → narrower colour bands; fewer → broader bands. | More/fewer labels (one per level); values change by step size. |
| Smoothness | 0 – 1 (default 0.85), step 0.05 | Plotly line smoothing on contour strokes. | 0 = angular/grid-aligned; 1 = rounded curves. | No direct effect (fill uses grid cells). | Labels follow smoothed line paths. |
| Color palette | Viridis, Jet, Hot, RdYlBu, Portland, Earth, Electric, Blues, Greens, YlOrRd | Plotly colorscale for filled contours. | Line colour from theme, not palette (filled mode). | Maps Z values to fill colours across the range. | No effect on label text; colorbar shows palette. |
| Lines only (no fill) | On / Off | Disables filled heatmap; shows lines + labels only. | Thicker lines (1.5 px); black on white theme. | Fill and colorbar hidden (coloring: 'none'). |
Labels still shown on lines. |
| Reverse colour palette | On / Off | Reverses colorscale direction (low↔high colours). | No effect. | Inverts which colours represent low vs high Z. | No effect. |
| Opacity | 0.1 – 1 (default 0.75), step 0.05 | Transparency of filled contour layer. | No effect on line opacity. | Lower → more transparent fill (background visible). | No effect. |
| Clip to data hull | On / Off (default On) | Masks grid outside convex hull of survey points. | Lines stop at hull edge (NaN gaps). | Fill clipped to hull; no colour outside data. | Labels only where lines exist inside hull. |
Grid
| Parameter | Range | What it does | Lines | Area | Labels |
|---|---|---|---|---|---|
| Resolution | 50 – 300 (default 100), step 10 | N×N interpolation lattice density. | Higher → finer, more detailed line geometry; lower → coarser, blockier lines. | Higher → smoother colour gradients; lower → visible grid artefacts / banding. | Label positions follow finer/coarser line paths. |
Points
| Parameter | Range | What it does | Lines | Area | Labels |
|---|---|---|---|---|---|
| Show survey points | On / Off | Green circle markers at CSV locations. | None Separate scatter overlay; does not affect contour computation. | ||
| Show name labels | On / Off | Point name or P1, P2, … above markers. | None Point labels only. | ||
| Show X, Y labels | On / Off | Coordinate text on each point. | None Point labels only. | ||
| Label size | 6 – 24 px (default 10) | Font size for point labels. | None Point labels only. | ||
| Label colour | White, Black, Grey | Point label text colour. | None Point labels only. | ||
Background
| Parameter | What it does | Lines | Area | Labels |
|---|---|---|---|---|
| None / IMAGE / DXF | Selects background layer under contours. | View Background visible through semi-transparent fill; does not change contour math. | ||
| Image extents (X-min … Y-max) | Maps image corners to world coordinates. | View Alignment only. | ||
| Auto from CSV | Sets image extents to data bounding box. | View Alignment only. | ||
| 2-point calibration | Affine alignment from two clicked image points. | View Alignment only. Blocks cross section while active. | ||
| Import inverted | Inverts image colours on load. | View Visual contrast for dark theme. | ||
| DXF upload | CAD linework under contour (max 150 MB). | View Reference geometry only. | ||
Cross section
| Parameter | Range | What it does | Lines | Area | Labels |
|---|---|---|---|---|---|
| Enable cross section | On / Off | Shows profile panel below map. | None Adds section line overlays; samples Z from interpolated grid. | ||
| Start angle (°) | Any number (default 45) | Direction for new lines: 0°=East, 90°=North. | None Profile sampling only. | ||
| Section line length | ≥ 0.001 world units | Length for new/active section lines. | None Profile sampling only. | ||
| Sample resolution | 50 – 500 (default 200) | Points sampled along each line for on-screen profile. | None Profile chart smoothness only. | ||
| Profile panel height | 160 – 720 px (default 300) | Height of elevation profile chart. | View Layout only. | ||
| Export interval (distance) | 0.001 – 10000 (default 1) | Chainage step for CSV export along each line. | None Export spacing only. | ||
Export & actions
| Parameter | What it does | Lines | Area | Labels |
|---|---|---|---|---|
| Generate Plot | Re-runs grid interpolation (after grid/hull changes). | Rebuilds entire contour from scratch. | ||
| Reset All | Clears data, backgrounds, cross sections, settings. | Removes plot entirely. | ||
| Export contour lines (DXF) | Downloads contour polylines at current step (one layer per level). | Exports iso-lines from d3-contour on current grid. | Not included in DXF. | Not included in DXF. |
| Export / Import project | Saves/restores full session as JSON. | Preserves all settings affecting contours. | ||
5. PNG Export Options
High-resolution PNG export renders the current plot (including theme, contours, points, backgrounds) via Plotly's image export. The map always preserves 1:1 X/Y data scale.
Resolution presets
| Preset | Reference edge pixel count | Typical use |
|---|---|---|
| HD (long edge 1920 px) | 1920 | Screen display, presentations |
| A4 @ 150 DPI | 1754 | Office printing |
| A4 @ 300 DPI | 3508 | High-quality A4 print |
| A3 @ 300 DPI | 4961 | Large format print |
| A2 @ 150 DPI | 3508 | Poster draft |
| A2 @ 300 DPI | 7016 | Publication-quality poster |
The preset value is applied to the reference dimension (see below). The other dimension is computed from aspect ratio. Maximum long edge is capped at 8000 px.
Reference dimension
| Option | Behaviour |
|---|---|
| Width (horizontal) | Exported image width = preset pixels. Height computed from data/view aspect ratio, layout margins (72/88/52/72 px), and Y-axis domain (0.07–0.93). |
| Height (vertical) (default) | Exported image height = preset pixels. Width computed from aspect ratio. |
Example: A2 @ 300 DPI with Height reference on a tall narrow survey → 7016 px tall; width scales proportionally.
Export area
| Option | Behaviour |
|---|---|
| Current view (default) | Exports the pan/zoom state visible on screen. Figure size scaled from on-screen plot dimensions. Margins scaled proportionally (capped at 35% of figure size). |
| All points | Fits the full survey extent (CSV bounds + background bounds, with 5% padding). Axis ranges set to data extent; dimensions computed from data aspect ratio. |
Export process
- Compute target width/height from preset, reference edge, and extent mode.
- Temporarily relayout plot: fixed size, theme colours, axis ranges,
scaleanchor: 'y',scaleratio: 1. - Download PNG via Plotly (
contour_plot_YYYY-MM-DD.png). - Restore responsive autosize layout.
Quick snapshot: The Plotly toolbar camera icon captures the current screen resolution (not the high-res presets).
Dimension formula (data extent mode)
Layout aspect ratio from axis ranges:
where yDomain = 0.86 (0.93 − 0.07) and xDomain = 0.92. If reference = height:
Margins: l=72, r=88, t=52, b=72 pixels (matching on-screen layout).