controlchartspy
The controlchartspy package provides tools for both calculating and visualising
statistical process control (SPC) charts and funnel plots in Python. It is based on
the R controlcharts
package.
Installation
Python 3.10 or later is required. Once the package is published on PyPI, you can install it with:
uv add controlchartspy
You can install the development version from a local checkout with
uv add /path/to/controlchartspy.
Getting Started
Constructing SPC Charts
Consider a basic time series comprising two years of monthly data:
from datetime import date
from random import Random
from controlchartspy import spc, funnel
rng = Random(12324)
dat = {
"month": [date(2024 + i // 12, i % 12 + 1, 1) for i in range(24)],
"y": [rng.gauss(0, 1) for _ in range(24)],
}
By default, the spc() function constructs an i-chart (individuals chart,
also referred to as an XmR chart):
spc_chart = spc(data=dat, keys="month", numerators="y")
The result is a ControlChart containing:
static_plot: a static SVG plot of the SPC chart.limits: a list of records containing the calculated control limits.
Display the plot in a notebook and inspect the first six rows of control limits:
spc_chart.static_plot
spc_chart.limits[:6]
Funnel Plot
The same interface is provided for funnel charts. For this example, consider proportion data recorded by ten organisations:
funnel_data = {
"organisation": list("abcdefghij"),
"numerators": [27, 23, 35, 26, 38, 22, 46, 26, 27, 35],
"denominators": [170, 122, 178, 184, 161, 105, 190, 121, 137, 197],
}
For funnel plots, the default is a proportions (PR) chart:
funnel_chart = funnel(
data=funnel_data,
keys="organisation",
numerators="numerators",
denominators="denominators",
)
funnel_chart.static_plot
funnel_chart.limits
Chart Types
The package supports fourteen SPC chart types and three funnel plot types.
Select a chart type with spc_settings={"chart_type": ...} or
funnel_settings={"chart_type": ...}:
| Function | Chart types | Additional required inputs |
|---|---|---|
spc |
run, i (default), i_m, i_mm, mr, c, g, t |
None |
spc |
p, pp (proportions), u, up (rates) |
denominators |
spc |
xbar (sample means) |
denominators, xbar_sds |
spc |
s (sample standard deviations) |
denominators; supply standard deviations as numerators |
funnel |
PR (proportions, default), SR (indirectly standardised ratios), RC (rates) |
denominators |
The individuals chart uses moving ranges to calculate control limits. i_m
uses a median centreline; i_mm also uses median moving-range limits. pp and
up are proportion and rate charts with large-sample correction.
Data and Arguments
data accepts a mapping of columns or a sequence of records. Column arguments
accept a column name or a sequence in the original row order:
keys: the categories of the chart; for SPC charts, these form the x-axis.numerators: the numeric observations for each category.denominators: the denominators for each category, where required.labels: optional labels for each category.
SPC keys accept Python date objects and ISO date strings (YYYY-MM-DD),
including mixtures in one column. Rows are sorted by key, within indicator
groups when supplied. Funnel keys identify organisations or other groups.
Numeric None and NaN values are treated as missing. Infinite values are
rejected. Repeated keys are aggregated: numerators and denominators
default to sum, while other input fields default to first. Override these
with aggregations, using first, last, sum, mean, min, max, median,
or count.
Aesthetic Options
Visual adjustments are handled through dedicated settings arguments. Each group
of settings has its own argument, such as canvas_settings, line_settings,
scatter_settings, x_axis_settings, or y_axis_settings. SPC charts also accept
date_settings, while label_settings controls observation labels.
To see the full list of available options, retrieve the complete defaults or one group:
from controlchartspy import spc_default_settings, funnel_default_settings
spc_defaults = spc_default_settings()
x_axis_defaults = spc_default_settings("x_axis")
funnel_defaults = funnel_default_settings("funnel")
Each settings argument is a mapping. Values can be scalars, one-element sequences, or sequences aligned with the original input rows.
For example, add a title and customise the x-axis:
styled_chart = spc(
data=dat,
keys="month",
numerators="y",
title={"text": "Monthly Performance", "font_size": "20px"},
x_axis_settings={
"xlimit_tick_rotation": -45,
"xlimit_label": "Month of Observation",
},
)
styled_chart.static_plot
Outlier Detection
Configure outlier detection through outlier_settings. SPC charts support
astronomical points, shifts, trends, and two-in-three patterns. Use
spc_default_settings("outliers") to see the available detection parameters.
NHS variation and assurance icons are configured through nhs_icon_settings.
spc_data = {
"date": [date(2023, month, 1) for month in range(1, 13)],
"value": [10, 12, 11, 15, 12, 11, 25, 12, 11, 10, 11, 12],
}
outlier_chart = spc(
data=spc_data,
keys="date",
numerators="value",
outlier_settings={
"astronomical": True,
"shift": True,
"trend": True,
"two_in_three": True,
},
)
outlier_chart.static_plot
outlier_chart.limits
Phases and Grouped Limits
Use groupings to calculate separate limits for phases of one time series:
grouped_data = {
**dat,
"phase": ["Before"] * 12 + ["After"] * 12,
"site": ["A"] * 12 + ["B"] * 12,
}
phased_chart = spc(
data=grouped_data, keys="month", numerators="y", groupings="phase",
)
grouped_chart = spc(
data=grouped_data, keys="month", numerators="y",
indicators="site", return_objs="limits",
)
site_a_limits = grouped_chart.limits["A"]
indicators create separate series and nested limits. A mapping such as
indicators={"Region": "region", "Site": "site"} creates a nested mapping in
that order, with names available through chart.indicator_names. A single
indicator group can render a plot; multiple groups require return_objs="limits".
Results and Saving Plots
Both constructors return a ControlChart. return_objs accepts one output name
or an iterable; its default is ("static_plot", "limits").
| Attribute | Contents |
|---|---|
static_plot |
StaticPlot with to_svg() and notebook SVG display |
limits |
A list of records, or nested mappings for grouped SPC series |
limit_lines |
Funnel control limits across the full range of denominators; request "limit_lines" explicitly |
indicator_names |
SPC indicator names in nesting order |
Unrequested outputs are None. SPC records include the formatted date,
value, target, and applicable lower/upper limits (ll68, ll95, ll99,
ul68, ul95, ul99). Columns depend on chart type and requested signal flags.
Funnel records include group, numerator, denominator, value, z, target,
and limits. Proportion charts use percentage values under the default settings.
Save a plot as SVG with save_plot():
spc_chart.save_plot("spc_chart.svg")
funnel_chart.save_plot("funnel_chart.svg", width=960, height=600)
Specify width and height to render at a different size, or use
spc_chart.static_plot.to_svg() to get the SVG as a string. The default size is
640 × 400 pixels. Static plots display as SVGs in notebooks.
The R package documentation provides further information about the shared calculation and display settings.
Metadata
Release files for controlchartspy 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| controlchartspy-0.1.0.tar.gz | 228.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| controlchartspy-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 371.2 kB
Release files / controlchartspy-0.1.0.tar.gz
| Download URL | controlchartspy-0.1.0.tar.gz |
|---|---|
| Size | 228.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b5b9b6f3d117673f3895a1583fb71b800cc8809bffa7c8bfba68405e321b464e
|
|
BLAKE2b-256 checksum How to use checksums |
7bc1ef9a6e7b46bee8171097516797ecaae3ec781a9697d66009750c800dbff9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / controlchartspy-0.1.0-py3-none-any.whl
| Download URL | controlchartspy-0.1.0-py3-none-any.whl |
|---|---|
| Size | 142.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0ff612f811c52155cced601b89cc3149a6a6c4cd6707b4cbd92019e9cb76db2d
|
|
BLAKE2b-256 checksum How to use checksums |
32ed6c569958c465ed2d698e8b0682c63326da49a6edc2f81c82f2308102dc33
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|