Result Model

After calling Analyze() on a chart object, the chart exposes its analysis results through typed series properties. This page describes the shared properties available on all ControlSeries subtypes, explains the difference between scalar and pointwise control limits, documents the RuleViolation window model, and gives guidance on translating the result object into a visual chart.

Shared Chart Data Properties

All concrete chart-data types inherit from ControlSeries, which exposes Values and Index. Control-limit properties are defined on FixedLimitSeries (for charts with constant limits) and on PointwiseLimitSeries (for P, U, and EWMA charts with per-point limits).

Property

Source

Type

Description

Values

ControlSeries

Vector<double>

The plotted statistic for each point on the chart (e.g., individual value, subgroup mean, proportion defective). Indexed from 0 (earliest) to Values.Length - 1 (latest). Available on all chart types.

CenterLine

FixedLimitSeries

double

The estimated process center. Drawn as a horizontal reference line. Available on all chart types through FixedLimitSeries or PointwiseLimitSeries.

UpperControlLimit

FixedLimitSeries

double

Scalar upper 3-sigma control limit. Available on Individuals, MR, XBar, R, S, NP, and C charts. For P, U, and EWMA charts use the pointwise UpperControlLimits vector instead.

LowerControlLimit

FixedLimitSeries

double

Scalar lower 3-sigma control limit. Same availability note as above. May be double.NaN when the lower limit is theoretically zero (count charts).

Sigma

FixedLimitSeries

double

The within-process sigma estimate used to compute the 3-sigma limits. The estimation method is controlled by SigmaEstimator.

Point Alignment

The length of the <codeEntityReference>P:Numerics.NET.Statistics.ProcessControl.ControlSeries.Values</codeEntityReference> vector depends on the chart family:

  • Individuals charts: one point per observation, so Values.Length equals the number of values passed in.

  • XBar, XBar‑R, XBar‑S, P, NP, C, U charts : one point per subgroup. For a matrix input with k rows, Values.Length == k.

  • EWMA and CUSUM charts: one point per observation, mirroring the individuals layout.

When displaying a control chart alongside a time axis or subgroup-number axis, map index i in Values to the (i+1)-th tick on the axis.

Scalar vs. Pointwise Control Limits

For chart families where every point shares the same control limit (equal subgroup sizes), the scalar UpperControlLimit and LowerControlLimit properties are sufficient for rendering.

For P and U charts with variable subgroup sizes, the 3-sigma limits vary from point to point because they depend on n_i. In this case:

C#
Vector<double> defects =
    Vector.Create(new double[] { 3, 5, 2, 7, 4, 6 });
Vector<double> sampleSizes =
    Vector.Create(new double[] { 50, 60, 45, 70, 55, 65 });

PChart chart = new PChart(defects, sampleSizes);
chart.Analyze();

// CORRECT: use pointwise vectors for variable-sample P/U charts
Vector<double> upperLimits = chart.Series.UpperControlLimits;
Vector<double> lowerLimits = chart.Series.LowerControlLimits;
Vector<double> points = chart.Series.Values;

for (int i = 0; i < points.Count; i++)
{
    Console.WriteLine(
        $"Point {i}: p={points[i]:F4} " +
        $"LCL={lowerLimits[i]:F4} UCL={upperLimits[i]:F4}");
}
// NOTE: in Deployed state per-point limits are not available;
// use chart.Apply(newCounts, newSizes) to obtain fresh pointwise limits.

Chart Family Summary

The table below summarizes the point unit and limit layout for each chart family.

Chart family

Point unit

Scalar limits valid?

Pointwise limits available?

Individuals (I)

Individual observation

Yes

No

Moving Range (MR)

Successive absolute difference

Yes

No

XBar

Subgroup mean

Yes

No

R (Range)

Subgroup range

Yes

No

S (Standard Deviation)

Subgroup standard deviation

Yes

No

P

Proportion defective

No. Always use vectors

Yes, always

NP

Count defective

Yes

No

C

Defect count per unit

Yes

No

U (variable inspection unit)

Defects per unit

Summary only. Do not use for per-point rendering

Yes, use vectors

EWMA

Exponentially weighted mean

Yes (asymptotic)

Optional transient-phase vectors

CUSUM

Cumulative sum statistic

Yes (decision interval h)

No

Rule-Violation Windows

When a run rule fires, the library records a RuleViolation object with the following properties:

Property

Meaning

TriggerIndex

Zero-based index into Values of the trigger point, the observation at which the rule condition was finally satisfied.

RuleId

A short string identifier for the rule (e.g., "N1" for Nelson rule 1, "W1" for Western Electric rule 1).

RuleName

Human-readable description of the rule that fired, suitable for display in a tooltip or report.

WindowStart

Zero-based index of the first point in the detection window (the oldest point contributing to the violation).

WindowLength

Number of consecutive points in the detection window, ending at TriggerIndex. Always satisfies WindowStart + WindowLength - 1 == Index .

  Note

Multiple violations may overlap when consecutive windows share points. Collect all RuleViolation objects from the RuleSetEvaluation and union their windows before highlighting to avoid redundant rendering.

Rendering Rule Violations

The typical pattern for highlighting a violation window is:

  1. Iterate the Violations collection on RuleSetEvaluation.

  2. For each violation, shade the horizontal region from x = WindowStart - 0.5 to x = WindowStart + WindowLength - 0.5 with a warning color.

  3. Render the trigger point at TriggerIndex with a distinct marker (e.g., filled circle vs. open circle) so that the exact trigger is identifiable at a glance.

C#
double[] data = {
    10.5, 11.2, 10.8, 11.5, 10.3, 11.8, 10.1, 11.4,
    10.9, 11.1, 10.6, 11.3, 10.7, 11.0, 10.4
};
IndividualsMovingRangeChartSet chart =
    new IndividualsMovingRangeChartSet(Vector.Create(data));
chart.Analyze();

RuleSetEvaluation ruleResult =
    chart.IndividualsSeries.EvaluateRules(ControlRuleSets.Nelson);

foreach (RuleViolation v in ruleResult.Violations)
{
    int windowEnd = v.WindowStart + v.WindowLength - 1;
    // Shade the violation window in your charting layer:
    // chart.AddHighlight(v.WindowStart, windowEnd, color: Red);
    Console.WriteLine(
        $"[{v.RuleId}] Highlight points {v.WindowStart}..{windowEnd}");
}

Rendering a Basic Control Chart

The minimal steps to render any control chart are the same regardless of charting library:

  1. Plot Values as the primary data series (line + markers).

  2. Draw CenterLine as a solid horizontal reference line.

  3. Draw UpperControlLimit and LowerControlLimit as dashed horizontal lines (or per-point series for variable-limit charts).

  4. Overlay violation highlights using the window model described above.

C#
double[] data = {
    10.5, 11.2, 10.8, 11.5, 10.3, 11.8, 10.1, 11.4, 10.9, 11.1
};
IndividualsMovingRangeChartSet chart =
    new IndividualsMovingRangeChartSet(Vector.Create(data));
chart.Analyze();

FixedLimitSeries iSeries = chart.IndividualsSeries;

// Map to a hypothetical plotting API:
// chartSeries.Add("I", iSeries.Values);
// chartSeries.AddHorizontalLine("CL", iSeries.CenterLine);
// chartSeries.AddHorizontalLine("UCL", iSeries.UpperControlLimit);
// chartSeries.AddHorizontalLine("LCL", iSeries.LowerControlLimit);
Console.WriteLine($"Points: {iSeries.Values.Count}");
Console.WriteLine(
    $"CL={iSeries.CenterLine:F4} UCL={iSeries.UpperControlLimit:F4}");

See Also