Skip to main content

Block Plot

NIST/SEMATECH Section 1.3.3.3 Block Plot

1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 Plot Character 1= Method 1 2= Method 2 P1/F/Sh1 P1/F/Sh2 P1/F/Sh3 P1/S/Sh1 P1/S/Sh2 P1/S/Sh3 P2/F/Sh1 P2/F/Sh2 P2/F/Sh3 P2/S/Sh1 P2/S/Sh2 P2/S/Sh3 Plant / Speed / Shift 15 20 25 30 Defects per Hour Block Plot
A block plot displays the response values from a designed experiment organized by block positions on the horizontal axis. Each position is drawn as an outlined vertical rectangle spanning the min-to-max response range, with bold plot characters (numerals) placed inside at their Y-value positions to mark treatment levels. Scanning across all positions reveals how often one treatment outperforms the other.

What It Is

A block plot displays the response values from a designed experiment organized by block positions on the horizontal axis. Each position is drawn as an outlined vertical rectangle spanning the min-to-max response range, with bold plot characters (numerals) placed inside at their Y-value positions to mark treatment levels. Scanning across all positions reveals how often one treatment outperforms the other.

Each block position corresponds to one combination of nuisance factors (e.g., plant × speed × shift). An outlined vertical rectangle spans the full response range within that position. Bold numerals (plot characters) mark the treatment levels at their response values inside the rectangle. The height of each rectangle reflects the total variability within that combination, while the relative placement of the characters inside shows which treatment level is higher or lower — enabling a simple counting diagnostic that replaces the ANOVA F-test with a binomial argument.

Questions This Plot Answers

  • Is the factor of interest significant?
  • Does the factor of interest have an effect?
  • Does the location change between levels of the primary factor?
  • Has the process improved?
  • What is the best setting (level) of the primary factor?
  • How much of an average improvement can we expect with this best setting of the primary factor?
  • Is there an interaction between the primary factor and one or more nuisance factors?
  • Does the effect of the primary factor change depending on the setting of some nuisance factor?
  • Are there any outliers?

Why It Matters

The block plot is a graphical technique that pointedly focuses on whether or not the primary factor conclusions are in fact robustly general. If one setting of the primary factor does better than the other for all or most of the nuisance factor combinations, then the conclusion is general and robust. It replaces a quantitative procedure (analysis of variance) with a graphical procedure and an F-test with a binomial test, requiring fewer statistical assumptions.

When to Use a Block Plot

Check whether a factor of interest (the primary factor) has an effect that is robust over all other factors. The block plot displays the response for every combination of nuisance factor levels, letting you see whether one setting of the primary factor consistently outperforms the other regardless of the nuisance factor combination. It replaces the analysis of variance F-test with a less assumption-dependent binomial test.

How to Interpret a Block Plot

Each block position on the horizontal axis represents one combination of nuisance factors (e.g., plant × speed × shift). An outlined rectangle spans the min-to-max response range within that position. Plot characters (e.g., "1" for Method 1, "2" for Method 2) are placed inside each rectangle at their observed response values on the vertical axis. The primary diagnostic is counting: scan across all positions and tally how often one treatment is above or below the other. If treatment 1 is consistently above treatment 2 across most positions, the treatment effect is robust regardless of the nuisance factor combination. In the canonical NIST example, Method 2 is lower (better) than Method 1 in 10 of 12 positions — a result with approximately 2% probability under the null hypothesis, replacing the F-test with a simple binomial test.

Examples

Consistent Treatment Effect

The same plot character (e.g., "2") is consistently lower across all or most block positions, indicating the treatment effect is robust over all nuisance factor combinations. The factor of interest has a main effect with no interaction.

Block-by-Treatment Interaction

The relative ordering of plot characters reverses between some block positions — "1" is lower in some blocks but "2" is lower in others. The factor of interest behaves differently under different nuisance factor combinations, and the interaction must be investigated.

Robustly General Conclusion

If one primary factor level is better in 10 of 12 blocks, the chance of this happening by chance is about 2% (like getting 10 heads in 12 coin flips). The binomial test confirms the treatment effect is statistically significant without requiring normality or equal-variance assumptions.

Assumptions and Limitations

The block plot assumes a balanced or near-balanced design where each treatment appears in every combination of nuisance factor levels. It is most effective when the number of combinations and treatment levels is moderate, as very large designs produce cluttered displays. Block plots are not available in most general-purpose statistical software programs, but they can be generated with custom code in Python, R, or similar tools.

See It In Action

This technique is demonstrated in the following case studies:

Reference: NIST/SEMATECH e-Handbook of Statistical Methods, Section 1.3.3.3

Python Example

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
# NIST-style block plot: 12 blocks (2 plants x 2 speeds x 3 shifts)
# 2 weld methods as primary factor
rng = np.random.default_rng(42)
base_m1, base_m2 = 27, 20
plant_eff = [0, -4]
speed_eff = [0, 2]
shift_eff = [0, -2, 3]
labels, m1_vals, m2_vals = [], [], []
for p in range(2):
for sp in range(2):
for sh in range(3):
eff = plant_eff[p] + speed_eff[sp] + shift_eff[sh]
m1_vals.append(base_m1 + eff + rng.normal(0, 2))
m2_vals.append(base_m2 + eff + rng.normal(0, 2))
labels.append(f"P{p+1}/{'FS'[sp]}/Sh{sh+1}")
x = np.arange(len(labels))
bar_w = 0.5
fig, ax = plt.subplots(figsize=(10, 5))
for i, (v1, v2) in enumerate(zip(m1_vals, m2_vals)):
lo, hi = min(v1, v2), max(v1, v2)
pad = (hi - lo) * 0.15 + 0.5
ax.add_patch(Rectangle((i - bar_w / 2, lo - pad), bar_w, hi - lo + 2 * pad,
fill=False, edgecolor="gray", lw=1))
ax.text(i, v1, "1", ha="center", va="center",
fontsize=11, fontweight="bold")
ax.text(i, v2, "2", ha="center", va="center",
fontsize=11, fontweight="bold")
all_vals = m1_vals + m2_vals
ax.set_ylim(min(all_vals) - 3, max(all_vals) + 3)
ax.set_xticks(x)
ax.set_xticklabels(labels, rotation=45, ha="right", fontsize=8)
ax.set_ylabel("Defects per Hour")
ax.set_xlabel("Plant (2) x Speed (2) x Shift (3)")
ax.set_title("Block Plot — Randomized Block Design")
ax.set_xlim(-0.6, len(labels) - 0.4)
ax.grid(True, axis="y", alpha=0.3)
plt.subplots_adjust(bottom=0.22)
plt.show()