Attribute Control Charts (p, np, c, u): Implementation and Factory Deployment
Attribute data represents discrete quality characteristics—pass/fail outcomes, defect counts, or nonconformities per inspection unit. Unlike continuous measurements tracked on variable charts (see SPC Fundamentals & Control Chart Taxonomy), attribute charts require distinct statistical foundations rooted in the binomial and Poisson distributions. Manufacturing operations deploy p, np, c, and u charts when measurement systems are impractical, inspection is destructive, or quality criteria are inherently categorical.
Chart Selection and Statistical Foundations
The choice between p/np and c/u charts hinges on two operational factors: whether the metric tracks defectives (nonconforming units) or defects (nonconformities), and whether the inspection sample size is constant.
| Chart | Metric | Sample Size | Distribution | 3σ Limit Formula |
|---|---|---|---|---|
| p | Proportion defective | Variable | Binomial | p̄ ± 3√(p̄(1−p̄)/nᵢ) |
| np | Count defective | Constant (n) | Binomial | np̄ ± 3√(np̄(1−p̄)) |
| c | Count of defects | Constant | Poisson | c̄ ± 3√c̄ |
| u | Defects per unit | Variable | Poisson | ū ± 3√(ū/nᵢ) |
For the np-chart, the limit formula uses σ = √(n·p̄·(1−p̄)), where p̄ = mean(defectives)/n.
Control limits derive from the underlying variance structure: binomial for p and np charts, Poisson for c and u charts. When continuous metrology is available, practitioners often prefer X-Bar R Chart Implementation for tighter process control and earlier shift detection. Attribute charts remain indispensable for visual inspection, final audit, supplier quality scoring, and compliance-driven pass/fail gates.
Production-Ready Python Implementation
Factory data streams rarely arrive clean. MES systems output irregular timestamps, missing lot identifiers, and fluctuating inspection counts. A robust attribute chart engine must handle these constraints gracefully, validate inputs, and compute variable limits without silent failures.
import numpy as np
import pandas as pd
import warnings
from typing import Optional
class AttributeControlChart:
"""
Production-grade engine for p, np, c, and u control charts.
Handles variable subgroup sizes, missing data, and zero-defect boundaries.
"""
def __init__(self, chart_type: str, sigma: float = 3.0):
valid_types = {"p", "np", "c", "u"}
if chart_type.lower() not in valid_types:
raise ValueError(f"Unsupported chart type. Choose from {valid_types}.")
self.chart_type = chart_type.lower()
self.z = sigma
def calculate_limits(self, data: pd.DataFrame) -> pd.DataFrame:
"""
Compute center line, UCL, and LCL for the selected attribute chart.
Expected columns by chart type:
p: 'defectives', 'sample_size'
np: 'defectives', 'sample_size'
u: 'defects', 'sample_size'
c: 'defects'
"""
df = data.copy()
ct = self.chart_type
if ct in {"p", "np"}:
if "defectives" not in df.columns or "sample_size" not in df.columns:
raise ValueError(f"{ct}-chart requires 'defectives' and 'sample_size' columns.")
df = df.dropna(subset=["defectives", "sample_size"])
elif ct == "u":
if "defects" not in df.columns or "sample_size" not in df.columns:
raise ValueError("u-chart requires 'defects' and 'sample_size' columns.")
df = df.dropna(subset=["defects", "sample_size"])
elif ct == "c":
if "defects" not in df.columns:
raise ValueError("c-chart requires a 'defects' column.")
df = df.dropna(subset=["defects"])
if ct == "p":
df["metric"] = df["defectives"] / df["sample_size"]
p_bar = (df["defectives"].sum() / df["sample_size"].sum()) # weighted average
sigma = np.sqrt(p_bar * (1 - p_bar) / df["sample_size"])
center = p_bar
elif ct == "np":
if df["sample_size"].nunique() > 1:
warnings.warn(
"np-chart assumes constant sample size. "
"Variable n detected—consider using a p-chart instead."
)
n = df["sample_size"].iloc[0]
p_bar = df["defectives"].sum() / df["sample_size"].sum()
df["metric"] = df["defectives"]
center = n * p_bar
sigma = np.full(len(df), np.sqrt(n * p_bar * (1 - p_bar)))
elif ct == "u":
df["metric"] = df["defects"] / df["sample_size"]
u_bar = df["defects"].sum() / df["sample_size"].sum() # weighted average
sigma = np.sqrt(u_bar / df["sample_size"])
center = u_bar
elif ct == "c":
df["metric"] = df["defects"]
center = df["metric"].mean()
sigma = np.full(len(df), np.sqrt(center))
df["center_line"] = center
df["ucl"] = center + self.z * sigma
df["lcl"] = np.maximum(0.0, center - self.z * sigma)
return df[["metric", "center_line", "ucl", "lcl"]]
Note: p and u charts use weighted averages for the centerline (total defects or defectives divided by total sample units) rather than simple mean of per-subgroup proportions. This is the correct approach when sample sizes vary, as recommended by the AIAG SPC Manual and ISO 7870-2.
Factory Deployment and Automation Constraints
Subgroup definition. Subgroup boundaries must align with physical process boundaries. Mixing lots from different shifts, tooling setups, or raw material batches violates the independence assumption and inflates false alarms. When subgroup sizes fluctuate by more than ±25% from the average, variable limits (calculated per subgroup) are mandatory.
Zero-defect and near-zero periods. When p̄ ≈ 0 or c̄ < 1, the LCL collapses to zero and the UCL becomes artificially tight. In high-yield environments, transition to exact binomial or Poisson limits, or deploy attribute EWMA/CUSUM variants for micro-shift detection.
Overdispersion. Attribute data from real production often exhibits greater variance than the theoretical binomial or Poisson model predicts. Test for overdispersion using a chi-square goodness-of-fit test before deploying automated alerts. Overdispersion typically indicates batch-to-batch heterogeneity or correlated defect modes requiring investigation, not just wider limits.
Data pipeline resilience. MES timestamps frequently drift and manual inspection logs contain nulls. The implementation above uses explicit column validation and weighted-average center lines to prevent silent NaN propagation. In production, wrap the chart engine in a scheduled orchestration layer (Apache Airflow or Prefect) that validates data completeness before triggering limit recalculation.
Statistical Validation and Signal Interpretation
Attribute charts follow the same Western Electric and Nelson run rules as variable charts, with important caveats. The discrete nature of binomial and Poisson data creates "ladder effects" where points can only take specific values. This reduces sensitivity to small shifts and can increase Type I error when limits are narrow. For large subgroup scenarios where continuous measurement granularity improves, evaluate X-Bar S Chart for Large Subgroups to capture within-subgroup variance more accurately than attribute counts allow.
Authoritative derivations for attribute control limits, overdispersion diagnostics, and chi-square testing procedures are documented in the NIST Engineering Statistics Handbook: Control Charts for Attributes.