Every analysis in ProcessBehavior starts with a classification: what structure does your (factor × time) grid actually have? The answer — a design state on Bishop’s 1–6 reference scale — decides which charts are valid, how variance is estimated, and which residuals exist.
This tour generates data for each of the six states with make_design and watches the classifier work. For the formal definitions behind the scale, see the Design-State Reference Scale; for how detection works on your own data, the Design-State Lineage guide.
Two vocabulary anchors:
ODS (observed design state) — what the raw data supports
ADS (analytical design state) — what the analysis actually runs at
States 1–3 describe how much replication the grid has; states 4–6 are their counterparts with empty cells in the grid.
from processbehavior import ProcessBehavior
from processbehavior.datasets import synthetic
for state in range(1, 7):
df = synthetic.make_design(state, seed=11)
study = ProcessBehavior(df).formulate(
response='y', factors=['factor 1', 'factor 2'], time='time')
print(f"state {state}: ODS {study.observed_design_state.sds} -> ADS {study.analytical_design_state.sds}"
f" | {study.ads_reason:<20} | recommended: {study.recommended_chart}")state 1: ODS 1 -> ADS 1 | full_replication | recommended: Xbar
state 2: ODS 2 -> ADS 2 | no_replication | recommended: X
state 3: ODS 3 -> ADS 3 | partial_replication | recommended: X
state 4: ODS 4 -> ADS 1 | full_replication | recommended: Xbar
state 5: ODS 5 -> ADS 2 | no_replication | recommended: X
state 6: ODS 6 -> ADS 3 | partial_replication | recommended: X
The collapse rule¶
States 4–6 never analyze as 4–6: the empty cells are removed from the analysis grid, and what remains is a complete grid at the corresponding replication level. That is the deterministic collapse you just watched:
| ODS | grid | ADS after removing empty cells |
|---|---|---|
| 4 | full replication, empty cells | 1 |
| 5 | no replication, empty cells | 2 |
| 6 | partial replication, empty cells | 3 |
So the analytical machinery only ever needs to handle states 1–3 — but the observed state still matters: it tells you your data collection missed planned combinations.
# State 1 - full replication: every cell has n >= 2, Xbar-S with exact limits
study1 = ProcessBehavior(synthetic.make_design(1, seed=11)).formulate(
response='y', factors=['factor 1', 'factor 2'], time='time')
result = study1.execute(companion=True)
print(f"charts: {result.all_charts}")
result.plot(chart='Xbar', show_stats=True)charts: ['Xbar', 'S']
# State 2 - no replication: n = 1 everywhere, individuals chart territory
study2 = ProcessBehavior(synthetic.make_design(2, seed=11)).formulate(
response='y', factors=['factor 1', 'factor 2'], time='time')
study2.execute(chart='X', by=[], companion=True).plot(chart='X')# State 6 - partial replication WITH empty cells: the design report
# shows exactly which planned combinations never produced data
study6 = ProcessBehavior(synthetic.make_design(6, seed=11)).formulate(
response='y', factors=['factor 1', 'factor 2'], time='time')
report = study6.design()
print(f"ODS {study6.observed_design_state.sds} -> ADS {study6.analytical_design_state.sds}")
print(f"empty cells: {report.n_empty_cells}")
print(report.structure_summary)ODS 6 -> ADS 3
empty cells: 15
Complete structure
Where to go next¶
Bishop Reference Validation — the full slide-by-slide validation of these mechanics against Tom Bishop’s Minitab output
Complete Design-State-1 Analysis — everything a state-1 dataset supports
Design-State Reference Scale — the formal definitions