Lesson 10 of 14 · 12 min
Reading confidence: pLDDT and PAE
AlphaFold2 and ColabFold report two complementary confidence signals, and reading them correctly separates a trustworthy fold from an over-interpreted one. pLDDT scores per-residue local accuracy, while the PAE matrix scores how confidently any two residues are placed relative to each other. Neither is a single global quality number, and they answer different questions.
Per-residue pLDDT bands
pLDDT is the model's predicted lDDT-Ca, a 0 to 100 estimate of local structural accuracy stored in the B-factor column of the output PDB. Above 90 the backbone and most side chains are reliable; 70 to 90 marks a confidently placed backbone; 50 to 70 is low and should be treated with caution; below 50 usually signals a residue with no single well-defined position, often intrinsically disordered.
Tip: pLDDT is local, not global. A stretch below 50 is frequently a genuine intrinsically disordered region with no single native conformation rather than a failed prediction, and a high mean pLDDT can still hide one badly placed loop. Judge segments, and never use pLDDT to reason about the relative orientation of two domains, that is exactly what PAE is for.
The PAE matrix
PAE[i, j] is the expected position error in Angstroms of residue i when the predicted and true structures are superposed on residue j's frame. Low off-diagonal blocks between two domains mean their relative position and orientation are confident, whereas high values mean each domain may fold well internally yet float relative to the other. For complexes, low inter-chain PAE across an interface is the signal that the interface itself is reliable.
import json, numpy as np
# ColabFold writes one scores file per ranked model.
# Pattern: <jobname>_scores_rank_00N_<model>.json
scores = json.load(open(
"myprotein_scores_rank_001_alphafold2_ptm_model_3_seed_000.json"))
plddt = np.asarray(scores["plddt"]) # (L,) per-residue, 0-100
pae = np.asarray(scores["pae"]) # (L, L) Angstroms
print("length :", plddt.shape[0])
print("mean pLDDT :", round(float(plddt.mean()), 1))
print("frac >= 70 :", round(float((plddt >= 70).mean()), 2))
print("PAE shape :", pae.shape, " max_pae:", scores["max_pae"])length : 312
mean pLDDT : 84.7
frac >= 70 : 0.86
PAE shape : (312, 312) max_pae: 31.75
import numpy as np
import matplotlib.pyplot as plt
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(11, 4))
# Left: per-residue pLDDT with the four AlphaFold DB confidence bands
res = np.arange(1, plddt.shape[0] + 1)
ax1.axhspan(90, 100, color="#0053D6", alpha=0.15) # very high
ax1.axhspan(70, 90, color="#65CBF3", alpha=0.20) # confident
ax1.axhspan(50, 70, color="#FFDB13", alpha=0.25) # low
ax1.axhspan( 0, 50, color="#FF7D45", alpha=0.20) # very low / disordered
ax1.plot(res, plddt, color="black", lw=0.8)
ax1.set(xlabel="residue", ylabel="pLDDT", ylim=(0, 100))
# Right: PAE, dark = low error = confident relative position.
# imshow puts pae[i, j] at row i (y) and column j (x); with
# PAE[i, j] = error in scored residue i aligned on frame j,
# the y-axis is the scored residue and the x-axis is the frame.
im = ax2.imshow(pae, cmap="Greens_r", vmin=0, vmax=scores["max_pae"])
ax2.set(xlabel="aligned (frame) residue", ylabel="scored residue")
fig.colorbar(im, ax=ax2, label="expected position error (A)")
fig.tight_layout()
fig.savefig("confidence.png", dpi=150)AlphaFold DB cross-reference
# Every AlphaFold DB entry is keyed by UniProt accession: AF-<ACC>-F1.
ACC=P00533 # human EGFR
base="https://alphafold.ebi.ac.uk/files/AF-${ACC}-F1"
curl -sLO "${base}-model_v4.pdb" # pLDDT in B-factor column
curl -sLO "${base}-predicted_aligned_error_v4.json" # PAE matrix + max_pae
# Per-residue pLDDT is columns 61-66 (tempFactor) of each ATOM record.
grep '^ATOM' "AF-${ACC}-F1-model_v4.pdb" | cut -c61-66 | tr -d ' ' \
| sort -n | tail -1Try it yourself: Run a two-domain protein (or a linker-joined fusion) through ColabFold, then plot its PAE matrix as above. Confirm you can see two low-PAE squares on the diagonal, meaning each domain folds well on its own, separated by high-PAE off-diagonal blocks, meaning their relative orientation is uncertain. Then open the same UniProt accession at alphafold.ebi.ac.uk and check that the interactive PAE viewer shows the same block pattern.