Short answer

Showing uncertainty on a geological map means making interpretation explicit instead of pretending every line was walked in the field. The reliable method is to store a confidence value as an attribute on each feature, then bind it to a visual variable: line dash patterns for contacts (solid = observed, dashed = approximate, dotted/queried = inferred), hachured or fuzzy edges for poorly constrained polygons, and reduced saturation or value-by-alpha for low-confidence units. The styling must be data-driven and reflected in the legend, otherwise the map reads as uniformly authoritative when it is not.

The two kinds of uncertainty geologists conflate

Most "uncertainty" on a geological map is really two distinct things, and they need different visual treatments.

Positional (locational) uncertainty is how well you know where a feature is. A contact mapped from a clean roadcut might be located to within a few metres; the same contact projected beneath alluvium might be uncertain to hundreds of metres. This is the dimension the classic geological line conventions encode.

Categorical (identity) uncertainty is how confident you are about what the feature is — whether a polygon is unit A or unit B, or whether a lineament is a fault at all versus a photo-lineament with no kinematic evidence. This maps poorly to dash patterns and is better shown with fill treatment, queried symbols (?), or a separate confidence-graded color.

Treating both as a single "confidence 1-5" slider is the most common modelling mistake, because a feature can be precisely located but uncertain in identity, or confidently identified but loosely located.

The established line conventions

Before inventing a scheme, use the conventions geologists already read. The USGS FGDC Digital Cartographic Standard for Geologic Map Symbolization (FGDC-STD-013-2006) codifies these:

  • Solid line — contact or fault is located (observed/accurately positioned).
  • Long dashapproximately located.
  • Dotted lineconcealed (continues beneath younger cover or water).
  • Short dash / queried (?)inferred or uncertain existence.

These map cleanly onto a single attribute. In your line layer, add a text field location_method with values like observed, approximate, concealed, inferred, and a separate existence_conf for queried features. Then symbolize categorically rather than drawing dashes by hand, which guarantees the legend matches the data.

Encoding confidence in the data model

Style follows schema. A practical contact/fault layer carries at least:

  • feature_type — contact, fault, fold axis, dyke margin.
  • location_method — observed | approximate | concealed | inferred.
  • existence_conf — integer 1-3 (1 = certain, 3 = speculative), used for the ? query symbol.
  • source — map sheet, survey, or interpreter, so provenance travels with the geometry.

For polygons (map units), add unit_conf (identity confidence) and optionally min_age/max_age so age uncertainty is queryable. Storing these as columns rather than baking them into symbol choices means you can restyle, filter, or audit later without redigitizing.

Styling in QGIS

In QGIS, use a Categorized renderer on location_method for the contacts layer and assign dash patterns in the symbol editor (Simple Line → Dash pattern). For the queried ?, add a Marker line sub-symbol or a rule-based label expression that places a ? glyph where existence_conf >= 3.

For polygon identity confidence, a clean approach is value-by-alpha controlled by a data-defined override. Set fill opacity from the field:

opacity = scale_linear("unit_conf", 1, 3, 100, 35)

so a confidence-1 polygon prints at full opacity and a confidence-3 polygon drops to about 35%. For print, prefer a hachured fill (line-pattern fill at low angle) on low-confidence units instead of transparency, because alpha blends with whatever sits underneath and can be misread.

A rule-based renderer is often cleanest overall:

"unit_conf" = 1   →  solid fill, full saturation
"unit_conf" = 2   →  solid fill, -25% saturation (use color_hsl / set_color_part)
"unit_conf" = 3   →  diagonal-line fill pattern, gray outline

Styling in MapLibre GL for web delivery

On the web, push the same logic into the style spec with data expressions. For a contacts vector source, drive line-dasharray and line-opacity from properties:

{
  "id": "contacts",
  "type": "line",
  "source": "geology",
  "source-layer": "contacts",
  "paint": {
    "line-color": "#444",
    "line-width": 1.4,
    "line-dasharray": [
      "match", ["get", "location_method"],
      "observed",    ["literal", [1]],
      "approximate", ["literal", [4, 2]],
      "concealed",   ["literal", [1, 3]],
      "inferred",    ["literal", [2, 2]],
      ["literal", [1]]
    ]
  }
}

Note that MapLibre does not interpolate line-dasharray per feature in all versions, so if a single layer must mix dash patterns, split into sub-layers by filter on location_method, each with its own static dash. For polygon identity confidence, an interpolate/step expression on fill-opacity or fill-color (toward a desaturated ramp) handles the value-by-alpha cleanly.

For dense, large geological surfaces, deck.gl GeoJsonLayer or MVTLayer lets you bind getLineColor, getDashArray (via the PathStyleExtension), and getFillColor as accessor functions reading the same confidence fields — useful when you need GPU performance over thousands of polygons.

A worked example: a fault under cover

Suppose you map a normal fault: 800 m of trace exposed in a quarry, then projected 1.2 km beneath Quaternary fan deposits to a borehole offset. The honest rendering is one geometry split into segments:

  1. Quarry segment: location_method = observed → solid line.
  2. Projected segment: location_method = concealed, existence_conf = 2 → dotted line with a single ? near the cover boundary.
  3. Borehole tie: a control point symbol so the reader sees what constrains the buried end.

The map now tells the truth: the fault is real where it is solid, plausibly continuous where it is dotted, and anchored by subsurface data rather than wishful projection.

Common pitfalls and why they happen

  • Uniform solid lines everywhere. Happens because digitizing on a screen produces visually identical strokes regardless of evidence. Fix by requiring location_method at capture time, not after.
  • Using transparency for print. Alpha is composited against the underlying layer, so a 40%-opacity unit over a green basemap shifts hue and reads as a different lithology. Reserve alpha for screen layers with a muted base.
  • Rainbow confidence ramps. A red-to-green confidence ramp collides with lithology colors and fails for ~8% of male readers (deuteranopia). Use a single-hue lightness ramp or texture instead.
  • Hiding the certainty class from the legend. If the dash convention is not in the legend, readers default to "all lines equal." The legend must name observed/approximate/inferred explicitly.
  • Bivariate overload. Encoding lithology in hue and confidence in hue is unreadable. Keep one variable for identity (hue) and a different channel (texture, value, dash) for confidence.

Validation before you publish

  • Toggle every confidence class on its own and confirm the geometry count matches the attribute table — silent nulls in location_method will render as the fallback style and quietly overstate certainty.
  • Print a grayscale proof. If certain and uncertain features are indistinguishable in gray, your scheme relies on color alone and will fail in B/W and for colorblind readers.
  • Cross-check that the legend lists every value actually present in the data, not a template legend copied from another sheet.
  • Have a second geologist read three sample areas and state, from the map alone, which contacts are inferred. If they cannot, the encoding is too subtle.

Bathyl perspective

We treat the confidence field as a first-class part of the geometry, captured at digitizing time and carried through to the web style, so a published map can always answer "how do you know this line is here?" The goal is a map that a reviewer can interrogate and a non-specialist can read without overtrusting an inferred boundary.

Related reading

Sources