ScientificAdvanced

Durov Diagram

A composite hydrochemical chart that pairs two ternary diagrams with a central rectangular field — extending the Piper diagram with total dissolved solids and pH axes to classify water samples.

// 01The chart

What it looks like

Example — Groundwater classification8 well samples
Cations (%meq/L)Anions (%meq/L)TDS (mg/L)pH

A Durov diagram classifying 8 groundwater samples by major ion composition, TDS, and pH.

// 02Definition

What is a Durov diagram?

A Durov diagram is a composite hydrochemical plot used to classify natural water samples based on their major ion chemistry. It was introduced by S.A. Durov in 1948 as an extension of the Piper diagram, adding two additional axes — total dissolved solids (TDS) and pH — to provide richer context about water quality.

The diagram consists of two ternary (triangular) plots — one for cations (calcium, magnesium, sodium+potassium) and one for anions (bicarbonate, sulfate, chloride) — that project into a central rectangular field. Each water sample appears as a single point in this central square, with its position determined by the dominant cation and anion proportions.

The central rectangle is then extended by two additional axes along its edges: TDS on the bottom and pH on the right. This lets hydrochemists see not only the water type (based on ion dominance) but also the mineralization level and acidity in a single view — a key advantage over simpler diagrams.

Because the input requires complete major-ion analyses converted to milliequivalents per liter, the chart is squarely a tool for trained hydrochemists and environmental scientists. It is the workhorse plot in groundwater contamination studies, aquifer characterization, and regulatory water-quality assessments worldwide.

Origin: Published by S.A. Durov in 1948, the Durov diagram was developed specifically to address limitations in the Piper diagram by incorporating TDS and pH, two parameters critical for understanding water’s overall quality and geochemical evolution.

// 03When to use

When a Durov diagram is the right call

Reach for a Durov diagram when you need a single figure that classifies multiple water samples by ion composition while simultaneously showing TDS and pH context.

✓Use a Durov diagram when…
  • Classifying groundwater, springs, or surface-water samples by hydrochemical type
  • Comparing many samples on a single composite figure
  • You need ion proportions plus TDS and pH in one view
  • Tracking groundwater contamination or saltwater intrusion over time
  • Characterizing aquifers in a regional hydrogeology study
  • Producing a regulatory water-quality assessment report
  • Inferring geochemical evolution along a flow path

// 04When not to use

When a Durov diagram is the wrong call

The chart presupposes complete major-ion data and a numerate audience. Outside that, simpler hydrochemistry charts win.

×Avoid a Durov diagram when…
  • Your audience is unfamiliar with ternary plots and meq/L units
  • You only have one or two samples — a results table is clearer
  • Ion data is incomplete (a sample missing one major cation can’t be plotted)
  • A simpler Piper diagram answers the same question
  • You need per-sample ion fingerprints — use a Stiff diagram instead
  • You need absolute concentrations — use a Schoeller diagram instead
  • You need a spatial map showing sample locations on a basin map

// 05Data requirements

What your data needs to look like

Before building the chart, your dataset needs to fit a specific shape. Use this checklist to confirm yours does.

Shape

One row per water sample. Major ion concentrations in mg/L plus TDS (mg/L) and pH (0–14 scale).

Minimum rows

3 samples. Below that a results table communicates better.

Maximum rows

A few hundred per panel. Above that, color or facet by hydrogeologic group to keep the central rectangle readable.

Required fields
sample_idrequired
string

An identifier for each water sample (well number, sampling station, date code).

Ca, Mg, Na, Krequired
number (mg/L)

Major cation concentrations in milligrams per liter. Converted to meq/L and then to percentages of the cation sum.

HCO3, SO4, Clrequired
number (mg/L)

Major anion concentrations in milligrams per liter. Converted to meq/L and then to percentages of the anion sum.

TDSrequired
number (mg/L)

Total dissolved solids — used to position the sample on the bottom side axis.

pHrequired
number (0–14)

Sample pH — used to position the sample on the right side axis.

Example data
sample_idCaMgNaKHCO3SO4ClTDSpH
W1902218332025304307.5
W2751822428020353807.6
W735922010806038017007.9

Tip: the cation–anion charge balance must agree within ~5–10%. If |Σcations − Σanions| / 0.5(Σcations + Σanions) exceeds 0.10, the analysis is suspect and the sample should be flagged.

// 06Anatomy

Parts of a Durov diagram

Four pieces define the layout: the cation ternary, the central rectangle, the TDS strip, and the pH strip. The anion ternary mirrors the cation ternary on the opposite side.

ABCD
A — Cation ternary: Triangle showing Ca²⁺, Mg²⁺, Na⁺+K⁺ proportions
B — Central rectangle: Main plotting field; samples are projected from both ternaries
C — TDS axis: Bottom strip showing total dissolved solids concentration
D — pH axis: Right strip showing acidity / alkalinity of each sample

// 07Step-by-step

Step-by-step: how to build a good Durov diagram

Eight steps that work regardless of tool. The unit conversion and charge-balance check are non-negotiable; everything else is layout.

  1. 1

    Collect a complete major-ion analysis per sample

    Every sample must have all six major ions (Ca, Mg, Na+K, HCO3, SO4, Cl), TDS, and pH. Missing any one ion makes the sample unplottable on the ternaries.
  2. 2

    Convert mg/L to meq/L

    For each ion, divide by atomic weight and multiply by absolute charge: meq/L = mg/L × |valence| / atomic weight. Sum all cations; sum all anions.
  3. 3

    Check the cation–anion balance

    Total cations and total anions in meq/L should match within ~5–10%. Larger imbalances indicate analytical error and the sample should be flagged or excluded.
  4. 4

    Compute percentage compositions

    For each cation, divide by the cation sum and multiply by 100. Repeat for anions. The ternaries plot percentages, not raw concentrations.
  5. 5

    Project samples into the central rectangle

    The cation percentage projects onto the rectangle’s x-axis; the anion percentage projects onto its y-axis. Each sample becomes one point in the central field.
  6. 6

    Place samples on TDS and pH side axes

    Add the same sample marker on the bottom strip at its TDS value and on the right strip at its pH value. Optional faint lines connect the rectangle position to the side strips.
  7. 7

    Color or facet by hydrogeologic group

    Use color to encode aquifer, depth zone, or sampling campaign. Direct labels are essential when the legend is in another corner of the figure.
  8. 8

    Title the takeaway

    Replace “Durov diagram of well samples” with the conclusion: “Wells in the upper aquifer cluster as Ca-HCO3 freshwater; deep wells show Na-Cl signature with elevated TDS.”

// 08Real-world examples

Where you’ll see Durov diagrams used

Durov diagrams are standard equipment for hydrogeologists working on groundwater quality, contamination, and aquifer characterization.

01

Aquifer characterization

Regional hydrogeology studies plot dozens of well samples on a single Durov to identify hydrochemical facies — Ca-HCO3 freshwater near recharge zones, Na-Cl signatures near discharge or saltwater intrusion fronts.

Hydrogeology
02

Saltwater intrusion monitoring

Coastal aquifer monitoring networks plot quarterly samples; the migration of points from the freshwater corner toward the Na-Cl corner is the headline of the report.

Coastal
03

Mining and industrial site investigations

Site characterization for mines or industrial brownfields uses Durov diagrams to distinguish background groundwater from contaminated samples by ion signature and elevated TDS.

Environmental
04

Geothermal and mineral water classification

Geothermal exploration uses the Durov diagram to classify spring waters by composition and to track changes in source chemistry over time.

Geothermal

// 09Variations

Variants of the Durov diagram

Several practical variants extend or adapt the base layout to specific use cases.

Expanded Durov

Adds extra side panels for additional parameters (e.g., temperature, electrical conductivity, isotopic ratios) beyond the canonical TDS and pH.

Color-coded Durov

Uses color to encode a fourth variable such as well depth, sampling year, or aquifer unit — making temporal or spatial trends immediately visible.

Density Durov

Replaces individual sample points with hexbin or contour density plots when hundreds of samples would otherwise overplot the central rectangle.

Interactive Durov (web)

Web implementations often add tooltips on hover that show the full ion analysis, charge balance, and any sample metadata.

// 10Comparisons

How it compares

Durov sits in the family of standard hydrochemistry diagrams. The three most useful comparisons are with Piper (its parent), Stiff (per-sample fingerprints), and Schoeller (concentration-focused alternative).

Durov vs Piper diagram

Both pair a cation ternary with an anion ternary, but the Piper projects samples into a central diamond rotated 45 degrees, while the Durov uses an axis-aligned rectangle and adds TDS and pH side axes. Durov shows more parameters at the cost of a busier layout.

Durov diagram

Cation + anion ternaries, axis-aligned central rectangle, plus TDS and pH side axes. Five hydrochemical dimensions in one figure.

  • Axis-aligned central rectangle
  • Includes TDS and pH
  • Best for full hydrochemical context

Piper diagram

Cation + anion ternaries projected into a central diamond. Three dimensions; TDS and pH not shown.

  • Diamond rotated 45 degrees
  • TDS / pH not included
  • Cleaner layout for ion classification only

Durov vs Stiff diagram

Stiff diagrams show one figure per sample (a polygon ‘fingerprint’), while Durov diagrams show many samples on a single figure. Use Stiff for per-sample inspection; use Durov for population-level classification.

Durov diagram

All samples on one composite figure. Population-level water-type classification.

  • Many samples per figure
  • Comparative classification
  • Compact for reports

Stiff diagram

One polygon per sample, encoding cation / anion meq/L on opposing axes. Sample-level ion fingerprint.

  • One figure per sample
  • Polygon shape encodes ion mix
  • Best for spatial maps of samples

Durov vs Schoeller diagram

A Schoeller diagram plots ion concentrations on a log scale across multiple parallel axes (one per ion), while a Durov shows ion proportions on ternaries. Schoeller preserves absolute concentration; Durov captures composition.

Durov diagram

Ion proportions (percentages) on ternaries; absolute concentration only via TDS strip.

  • Composition focus
  • Ternary geometry
  • Compact composite

Schoeller diagram

Log-scale parallel axes, one per ion. Preserves absolute concentration of each species.

  • Concentration focus
  • Linear / log axes per ion
  • Multiple samples as overlaid lines

// 11Common mistakes

Common Durov diagram mistakes

Most bad Durov diagrams fail on the same handful of issues: skipping unit conversion, ignoring charge balance, or quietly dropping incomplete samples.

Plotting mg/L instead of meq/L percentages

Skipping the unit conversion gives a wrong-shaped distribution. Always convert to meq/L and then to percentages of the cation / anion sums.

Skipping the charge-balance check

If the cation and anion sums don’t agree within ~10%, the sample has analytical error. Plot a flag, exclude it, or document the imbalance.

Silently dropping incomplete samples

Samples missing one major ion can’t be plotted on the ternaries. Document the exclusion in the methods, don’t just delete the row.

Mismatched TDS scales across panels

When comparing aquifers or campaigns, lock the TDS strip to the same range so cloud size is comparable.

Unlabeled ternary corners

Without labels, readers can’t tell which corner is Ca, Mg, Na+K, HCO3, SO4, or Cl. Always label them.

Using a Durov for per-sample analysis

If you need a separate fingerprint per sample, use a Stiff diagram. Durov is for comparing many samples on one figure.

// 12Accessibility

Accessibility checklist

Run through this list before publishing. The chart should still communicate its message to readers using assistive technology, color-blind users, keyboard navigation, and reduced-motion settings.

  • ✓

    Color contrast for sample markers and ternary outlines

    WCAG 1.4.3
    Sample markers must reach 3:1 against the chart background; ternary triangle outlines, the central rectangle border, and the TDS / pH strip borders must reach 4.5:1 so the layout is visible at thumbnail size.
  • ✓

    Don’t encode sample groups by color alone

    WCAG 1.4.1
    When samples are color-coded by aquifer or campaign, also use marker shape and direct labels so color-vision-deficient readers can still distinguish the groups.
  • ✓

    Provide a meaningful text alternative

    WCAG 1.1.1
    An accessible name should describe the takeaway: “Durov diagram of 8 wells: shallow wells cluster as Ca-HCO3 freshwater, deep wells as Na-Cl with TDS above 1500 mg/L.”
  • ✓

    Expose the underlying ion table

    WCAG 1.3.1
    Provide a downloadable CSV or hidden data table with each sample’s Ca, Mg, Na, K, HCO3, SO4, Cl, TDS, pH. The chart’s spatial encoding is essentially impossible to experience without sight.
  • ✓

    Label the axes and ternary corners explicitly

    WCAG 3.3.2
    Every ternary corner must be labeled with its ion (Ca²⁺, Mg²⁺, Na⁺+K⁺, etc.). The bottom and right strips must show their units (mg/L for TDS, the standard 0–14 scale for pH).
  • ✓

    Resizable and zoomable

    WCAG 1.4.4
    Use a responsive viewBox so the layout remains legible at 200% browser zoom. Below a panel width of ~500 px the diagram becomes unreadable; hide it or replace with the data table at narrow widths.
  • ✓

    Keyboard-accessible interactivity

    WCAG 2.1.1
    If samples reveal a tooltip on hover, every sample marker should be reachable with the Tab key and the tooltip should appear on focus, with a visible focus ring.

// 13Best practices

Design and craft tips

A short list of dos and don’ts that consistently separate publication-quality Durov diagrams from the demo-grade ones.

Do

Always verify charge balance

Cation and anion sums in meq/L must agree within ~5–10%. Big imbalances indicate analytical error and should be flagged or excluded — not silently plotted.
×Don’t

Plot mg/L percentages directly

The Durov diagram is defined on milliequivalent percentages. Plotting raw mg/L (or wt%) gives a distorted picture and is the single most common Durov mistake.
Do

Label each ternary corner clearly

Ca²⁺, Mg²⁺, Na⁺+K⁺ on the cation triangle; HCO3⁻, SO4²⁻, Cl⁻ on the anion triangle. Don’t make readers infer them.
×Don’t

Drop samples with missing ions silently

If a sample is missing one major ion, document the exclusion in the methods section. Quietly removing it biases the figure.
Do

Use a fixed TDS scale across panels

When comparing aquifers or time periods, lock the TDS strip to the same range so cloud size is comparable.
×Don’t

Combine many small markers without grouping

Hundreds of overplotted dots make the central rectangle unreadable. Color by group or facet by aquifer.
Do

Connect the rectangle to side axes

Faint horizontal and vertical leaders between the rectangle position and the TDS / pH strip make the multi-panel layout much easier to read.
×Don’t

Substitute a Durov for a Stiff diagram

If the goal is per-sample ion fingerprinting (one figure per sample), use a Stiff diagram instead. Durov is for population-level classification.

// 15Tool instructions

How to build it in your tool of choice

Recipes for the libraries and commercial tools that ship a Durov implementation, plus pragmatic D3 / Matplotlib routes when none are available.

Python (Matplotlib)

Code — ~10 min
  1. 01Install Matplotlib, NumPy, and pandas with pip install matplotlib numpy pandas (optionally pip install WQChartPy for a higher-level helper).
  2. 02Load samples into a pandas DataFrame with columns Ca, Mg, Na, K, HCO3, SO4, Cl, TDS, pH (mg/L for ions and TDS).
  3. 03Convert ion mg/L to meq/L by dividing by ion-specific equivalent weights, then to percentages.
  4. 04Use matplotlib.patches.Polygon to draw the cation triangle, anion triangle, and central rectangle on a single subplot.
  5. 05Project (Ca%, Mg%) onto the cation triangle and (HCO3%, SO4%) onto the anion triangle; project both onto the central rectangle’s x and y axes.
  6. 06Add two thin axes below and to the right for TDS and pH; place sample markers on each.

WQChartPy (PyPI) is the closest thing to a turn-key implementation — it ships Piper, Durov, Stiff, and Chadha plots with one call from a CSV.

R (smwrGraphs)

Code — ~6 min
  1. 01Install smwrGraphs from the USGS R repository: remotes::install_github('USGS-R/smwrGraphs').
  2. 02Build a data frame with Ca, Mg, Na, K, HCO3, SO4, Cl in mg/L plus TDS and pH per sample.
  3. 03Convert with conc2meq() to milliequivalents, then to percentages.
  4. 04Call piperPlot() for the central composition; pair it with subPlot() panels for TDS and pH to construct the Durov layout.
  5. 05Use setSweave or pdf() to write the figure at publication resolution.
  6. 06Add a takeaway-style caption noting the dominant water types found.

smwrGraphs is the de-facto USGS hydrochemistry plotting library; the hydrogeo and hydroTSM packages are alternatives if smwrGraphs install proves difficult.

JavaScript (D3)

Code — ~15 min
  1. 01Install D3 with npm i d3.
  2. 02Project ternary (a, b, c) coordinates to cartesian: x = b + c/2, y = c × sqrt(3)/2 then scale to pixels.
  3. 03Draw the cation triangle, anion triangle, and central rectangle with svg <polygon> and <rect>.
  4. 04Project each sample’s (Ca%, Mg%) onto the cation triangle and (HCO3%, SO4%) onto the anion triangle; place its dot in the rectangle at (cation%, anion%).
  5. 05Render TDS and pH strips as two thin <g> groups below and to the right with their own scales.
  6. 06Add a legend explaining marker color / shape and a takeaway-style title.

There is no first-party D3 helper for Durov diagrams — the recipe above is the standard manual implementation. Reuse the geometry as a small React/Vue component once written.

AquaChem

GUI — ~5 min
  1. 01Open AquaChem (Schlumberger Water Services) and import samples from CSV or Excel.
  2. 02Use the unit-conversion tool to ensure ions are in mg/L; AquaChem handles the meq/L conversion internally.
  3. 03Switch to the Plots panel and pick ‘Durov’ from the standard hydrochemistry chart list.
  4. 04Color or symbol-code samples by sample group (aquifer, depth, campaign) using the legend editor.
  5. 05Export the diagram as PDF or PNG at the report’s required resolution.
  6. 06Save the project so the same chart configuration can be reopened with refreshed samples.

AquaChem is the leading commercial hydrochemistry suite; it produces the Durov and TDS / pH side axes correctly and saves analysts a lot of plumbing.

WQChartPy (open-source GUI)

Open source — ~5 min
  1. 01Install with pip install WQChartPy.
  2. 02Prepare a CSV with the columns Sample, Ca, Mg, Na, K, HCO3, SO4, Cl, TDS, pH, plus a Color and Marker column for plotting style.
  3. 03Load with df = pd.read_csv('samples.csv'); the package expects this exact schema.
  4. 04Call wqchartpy.durov.plot(df, unit='mg/L', figname='durov', figformat='pdf').
  5. 05The function automatically projects samples and renders the Durov layout with TDS and pH strips.
  6. 06Open the resulting PDF and add a manual caption for the takeaway.

WQChartPy is a small open-source helper that replicates Piper, Durov, Stiff, Chadha, and Gibbs diagrams. Useful when AquaChem is unavailable.

// 16Code examples

Working code in the most common stacks

Three runnable snippets that produce equivalent Durov diagrams in Python, R, and JavaScript. Each includes the meq/L conversion and projects samples into the central rectangle.

durov.py
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon, Rectangle

# 8 well samples (mg/L)
samples = pd.DataFrame({
    "well":  ["W1", "W2", "W3", "W4", "W5", "W6", "W7", "W8"],
    "Ca":    [ 90,  75,  60, 130, 120, 110,  35,  40],
    "Mg":    [ 22,  18,  15,  35,  28,  30,   9,  10],
    "Na":    [ 18,  22,  35,  20,  35,  40, 220, 250],
    "K":     [  3,   4,   5,   3,   4,   5,  10,  12],
    "HCO3":  [320, 280, 260, 380, 340, 330,  80,  70],
    "SO4":   [ 25,  20,  35,  40,  30,  35,  60,  55],
    "Cl":    [ 30,  35,  40,  45,  50,  55, 380, 420],
    "TDS":   [430, 380, 360, 540, 480, 480,1700,1850],
    "pH":    [7.5, 7.6, 7.8, 7.4, 7.5, 7.6, 7.9, 8.0],
})

# meq/L equivalent weights (mg / meq).
ew = {"Ca": 20.04, "Mg": 12.16, "Na": 22.99, "K": 39.10,
      "HCO3": 61.02, "SO4": 48.03, "Cl": 35.45}

cat = pd.DataFrame({k: samples[k] / ew[k] for k in ["Ca", "Mg", "Na", "K"]})
an  = pd.DataFrame({k: samples[k] / ew[k] for k in ["HCO3", "SO4", "Cl"]})
cat_pct = cat.div(cat.sum(axis=1), axis=0) * 100
an_pct  = an.div(an.sum(axis=1), axis=0) * 100

fig, ax = plt.subplots(figsize=(8, 8))
ax.set_xlim(-10, 240); ax.set_ylim(-40, 240); ax.set_aspect("equal"); ax.axis("off")

# Central rectangle
ax.add_patch(Rectangle((40, 40), 160, 160, fill=False, ec="#1a1a18", lw=1))
# Cation ternary above-left
ax.add_patch(Polygon([(40, 200), (200, 200), (120, 200 + 80*np.sqrt(3))],
                     closed=True, fill=False, ec="#1a1a18", lw=1))
# Anion ternary right (rotated)
ax.add_patch(Polygon([(200, 40), (200, 200), (200 + 80*np.sqrt(3), 120)],
                     closed=True, fill=False, ec="#1a1a18", lw=1))
# TDS strip below
ax.add_patch(Rectangle((40, 10), 160, 16, fill=False, ec="#1a1a18", lw=0.5))
# pH strip right
ax.add_patch(Rectangle((215, 40), 16, 160, fill=False, ec="#1a1a18", lw=0.5))

# Project samples into central rectangle.
xs = 40 + cat_pct["Na"].values + (cat_pct["K"].values) * 1.6
ys = 40 + an_pct["Cl"].values * 1.6
ax.scatter(xs, ys, c="#c94a2e", alpha=0.85, s=60, edgecolor="white")

# Side axes
tds_x = 40 + (samples["TDS"].clip(0, 2000) / 2000) * 160
ax.scatter(tds_x, np.full(len(samples), 18), c="#c94a2e", alpha=0.85, s=40)
ph_y = 40 + ((samples["pH"] - 6) / 4) * 160
ax.scatter(np.full(len(samples), 223), ph_y, c="#c94a2e", alpha=0.85, s=40)

ax.text(120, 200 + 80*np.sqrt(3) + 8, "Cations (% meq/L)", ha="center", fontsize=10)
ax.text(200 + 80*np.sqrt(3) + 12, 120, "Anions (% meq/L)",
        rotation=270, va="center", fontsize=10)
ax.text(120,  3, "TDS (mg/L)",  ha="center", fontsize=10)
ax.text(232, 120, "pH", rotation=270, va="center", fontsize=10)
ax.set_title("Wells W1–W6 cluster as Ca-HCO3 freshwater; W7–W8 are Na-Cl with high TDS",
             loc="left", fontsize=11)
plt.tight_layout()
plt.savefig("durov.png", dpi=200, bbox_inches="tight")
plt.show()
$ python durov.py

// 17 — FAQs

Frequently asked questions

What is a Durov diagram?+

A Durov diagram is a composite hydrochemical chart that pairs two ternary diagrams — one for major cations and one for major anions — with a central rectangular field, plus extra TDS and pH axes along the edges. It classifies water samples by ion chemistry, mineralization, and acidity in a single figure.

When should you use a Durov diagram?+

Use a Durov diagram for hydrochemical classification of natural water samples — groundwater, springs, surface water — when you need to combine ion proportions with TDS and pH context. It is the standard plot for hydrogeological reports, contamination tracking, and aquifer characterization.

When should you avoid a Durov diagram?+

Avoid a Durov diagram when your audience is unfamiliar with ternary plots, when you only have one or two samples (a table is clearer), when ion data is incomplete (a sample missing one major cation can’t be plotted), or when a simpler Piper diagram answers the same question.

What’s the difference between a Durov and a Piper diagram?+

Both share the cation + anion ternary pair, but a Piper diagram projects samples into a central diamond rotated 45 degrees, while a Durov diagram uses an axis-aligned central rectangle with two extra strips for TDS and pH. The Durov design adds those two extra parameters at the cost of slightly more complex layout.

What units does a Durov diagram use?+

Major ion concentrations must be converted to milliequivalents per liter (meq/L), then expressed as a percentage so the cation and anion totals each sum to 100. TDS is plotted in mg/L; pH is dimensionless on a standard 0–14 scale.

Is a Durov diagram suitable for dashboards?+

Yes — Durov diagrams work in dashboards as long as the panel is large enough that the two ternaries, central rectangle, and TDS / pH strips remain individually legible. Below ~500 px wide they become unreadable.

What category of chart is a Durov diagram?+

Durov Diagram belongs to the Scientific family of charts. Charts in that family are designed to answer the same kind of question — how to classify a sample by multivariate composition — so they often work as alternatives when one doesn’t quite fit your data.

How do you read a Durov diagram?+

Start with the two ternary diagrams to identify the dominant cation and anion. Project both onto the central rectangle to find the water type. Then read across to the TDS axis (bottom) for mineralization and down to the pH axis (right) for acidity to characterize the sample fully.

What’s the best library for building Durov diagrams?+

There is no single canonical library. In R, the smwrGraphs and hydrogeo packages support related Piper / Durov plots. In Python, custom Matplotlib code or the WQChartPy package handles the layout. For the web, D3 with manual ternary-to-cartesian projection is the standard route.

// 18References

References and further reading

Primary sources — Durov 1948 and Piper 1944 — plus the standard hydrogeology reference texts and tools used throughout this guide.